GithubHelp home page GithubHelp logo

eclipse / paho.mqtt.embedded-c Goto Github PK

View Code? Open in Web Editor NEW
1.3K 105.0 746.0 730 KB

Paho MQTT C client library for embedded systems. Paho is an Eclipse IoT project (https://iot.eclipse.org/)

Home Page: https://eclipse.org/paho

License: Other

Makefile 1.86% Shell 0.46% C 46.40% C++ 20.44% HTML 2.22% CMake 2.70% Python 25.92%
eclipseiot mqtt iot embedded internet-of-things

paho.mqtt.embedded-c's Introduction

Eclipse Paho MQTT C/C++ client for Embedded platforms

This repository contains the source code for the Eclipse Paho MQTT C/C++ client library for Embedded platorms.

It is dual licensed under the EPL and EDL (see about.html and notice.html for more details). You can choose which of these licenses you want to use the code under. The EDL allows you to embed the code into your application, and distribute your application in binary or source form without contributing any of your code, or any changes you make back to Paho. See the EDL for the exact conditions.

There are three sub-projects:

  1. MQTTPacket - simple de/serialization of MQTT packets, plus helper functions
  2. MQTTClient - high(er) level C++ client, plus
  3. MQTTClient-C - high(er) level C client (pretty much a clone of the C++ client)

The MQTTPacket directory contains the lowest level C library with the smallest requirements. This supplies simple serialization and deserialization routines. They serve as a base for the higher level libraries, but can also be used on their own It is mainly up to you to write and read to and from the network.

The MQTTClient directory contains the next level C++ library. This networking code is contained in separate classes so that you can plugin the network of your choice. Currently there are implementations for Linux, Arduino and mbed. ARM mbed was the first platform for which this was written, where the conventional language choice is C++, which explains the language choice. I have written a starter Porting Guide.

The MQTTClient-C directory contains a C equivalent of MQTTClient, for those platforms where C++ is not supported or the convention. As far as possible it is a direct translation from MQTTClient.

Build requirements / compilation

CMake builds for the various packages have been introduced, along with Travis-CI configuration for automated build & testing. The basic method of building on Linux is:

mkdir build.paho
cd build.paho
cmake ..
make

The travis-build.sh file has the full build and test sequence for Linux.

Usage and API

See the samples directories for examples of intended use. Doxygen config files for each package are available in the doc directory.

Runtime tracing

The MQTTClient API has debug tracing for MQTT packets sent and received - turn this on by setting the MQTT_DEBUG preprocessor definition.

Reporting bugs

This project uses GitHub Issues here: github.com/eclipse/paho.mqtt.embedded-c/issues to track ongoing development and issues.

More information

Discussion of the Paho clients takes place on the Eclipse Mattermost Paho channel and the Eclipse paho-dev mailing list.

General questions about the MQTT protocol are discussed in the MQTT Google Group.

More information is available via the MQTT community.

paho.mqtt.embedded-c's People

Contributors

apullin avatar icraggs avatar johanstokking avatar jpwsutton avatar miketran78727 avatar msonn avatar radoslavv avatar rafaeldelucena avatar redboltz avatar scaprile avatar sg- avatar sshtel avatar tjdai avatar wifixcort avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

paho.mqtt.embedded-c's Issues

MQTTDeserialize_publish uses wrong type for payloadlen parameter

migrated from Bugzilla #481975
status UNCONFIRMED severity critical in component MQTT-Embedded-C for 1.2
Reported in version unspecified on platform PC
Assigned to: Ian Craggs

On 2015-11-11 20:05:54 -0500, Joe McIlvain wrote:

MQTTDeserialize_publish takes the payloadlen parameter as an int * (the address of an int), but the MQTTMessage struct defines payloadlen as of type size_t.

On platforms where size_t is bigger than int, this causes the upper byte(s) of the size_t bytes to be uninitialized/undefined. If the upper byte(s) happen to be zero, this works okay - if they happen to be anything else, the payloadlen number becomes huge, and will likely cause a segmentation fault when you try to read the message.

MQTTDeserialize_publish should be fixed to use type size_t for the payloadlen parameter.

Many implicit converstions from size_t to signed int in function args.

Building with this code produces warnings with -Wsign-conversion, where size_t is implicitly converted to signed int.

A usage example is here:
https://github.com/eclipse/paho.mqtt.embedded-c/blob/master/MQTTClient-C/src/MQTTClient.c#L212

Where the function definition is here:
https://github.com/apullin/paho.mqtt.embedded-c/blob/master/MQTTPacket/src/MQTTConnectClient.c#L211

This seems like a relatively straightforward fix for individual instances, but refactoring across the library and verifying correct operation may be a significant undertaking.

Is there active development on this library? Should I go ahead and start work on this? I don't want to duplicate any work.

Compiling with Microchip XC8 issue

migrated from Bugzilla #434081
status RESOLVED severity normal in component MQTT-Embedded-C for ---
Reported in version unspecified on platform PC
Assigned to: Ian Craggs

On 2014-05-05 05:03:07 -0400, Eugenio Bonifacio wrote:

I'm using the embedded client in a Microchip PIC18 micro. Obviously stdio.h does not contain a definition of "FILE" type, that is used in StackTrace.h in function StackTrace_printStack(FILE* dest).

So even if I don't use StackTrace I get an error related to this, because the compiler cannot find the symbol. I solved moving the function declarations inside the #else block of #if defined(NOSTACKTRACE) in StackTrace.h.

Here's the patch string:

diff --git a/src/StackTrace.h b/src/StackTrace.h
index 990895d..282707c 100644
--- a/src/StackTrace.h
+++ b/src/StackTrace.h
@@ -59,13 +59,13 @@
#define FUNC_EXIT_MED_RC(x) StackTrace_exit(func, LINE, &x, TRACE_MEDIUM)
#define FUNC_EXIT_MAX_RC(x) StackTrace_exit(func, LINE, &x, TRACE_MAXIMUM)
#endif
-#endif

void StackTrace_entry(const char* name, int line, int trace);
void StackTrace_exit(const char* name, int line, void* return_value, int trace);

void StackTrace_printStack(FILE* dest);
char* StackTrace_get(unsigned long);
+#endif

On 2014-05-08 03:26:34 -0400, Ian Craggs wrote:

Thanks Eugenio.

On 2014-05-08 03:51:24 -0400, Ian Craggs wrote:

Fixed.

Asynchronous embedded C++ client

migrated from Bugzilla #442032
status NEW severity enhancement in component MQTT-Embedded-C for 1.2
Reported in version future on platform PC
Assigned to: Ian Craggs

On 2014-08-19 06:01:37 -0400, Ian Craggs wrote:

Use callbacks, as per the Paho C client.

Allow multiple inflight QoS1/2 messages (maximum as template parameter).

Use a background thread (implementation dependent - template parameter).

On 2014-08-24 18:39:10 -0400, Ian Craggs wrote:

I had made a start here:

http://mbed.org/teams/mqtt/code/MQTT/file/f5beda831651/MQTTAsync.h

On 2015-01-21 05:27:22 -0500, Ian Craggs wrote:

Updating target milestone.

Add packet printing to MQTTPacket

migrated from Bugzilla #442033
status CLOSED severity enhancement in component MQTT-Embedded-C for 1.1
Reported in version 1.0 on platform PC
Assigned to: Ian Craggs

On 2014-08-19 06:03:14 -0400, Ian Craggs wrote:

Add routine(s) for printing out packets nicely.

On 2014-08-24 18:40:21 -0400, Ian Craggs wrote:

I've started on this one, along with logging in the synchronous client.

On 2015-04-29 10:22:42 -0400, Ian Craggs wrote:

This is now complete.

Subscribe using PAHO Embedded C client

I am using PAHO embedded C client for MQTT implementation. I have successfully implemented publish and now working on subscribe. I see a while loop when a SUBACK is received and the code is checking for PUBLISH value (I am referring a file pub0sub1.c from folder \org.eclipse.paho.mqtt.embedded-c-1.0.0\MQTTPacket\samples).
It looks that the code will remain in this loop till a message is received. How to break this loop in case no message is received or desired message is received?
I tried adding a timeout (using timer) and also checking the received message but it is not working. Has anyone tried using this example to implement subscribe? Any type of help will be highly appreciated.

Thanks in advance.

Mike

linux_read in MQTTLinux.c doesn't handle recv returning 0

migrated from Bugzilla #481962
status UNCONFIRMED severity major in component MQTT-Embedded-C for 1.2
Reported in version unspecified on platform PC
Assigned to: Ian Craggs

On 2015-11-11 16:18:47 -0500, Joe McIlvain wrote:

I've observed cases where recv in the linux_read function in MQTTClient.c returns 0, instead of -1 or a positive number of bytes.

I'm not sure how/why this happens, but I can reliably reproduce this when I create a trivial loop of MQTTYield(); printf(".\n"); sleep(1);. At some point, the .s stop printing and the execution gets stuck in an inner, unthrottled loop at 100% CPU. This is because recv keeps returning 0, so the loop in linux_read never accumulates a number of bytes above the target len, and never stops.

I am on 64-bit Linux (Fedora 22), compiled from latest source.

I would recommend treating rc == 0 && bytes == 0 as a condition to break the loop in linux_read.

Inefficient instantiation of Timer in MQTT-Embedded C++ client

migrated from Bugzilla #475204
status RESOLVED severity enhancement in component MQTT-Embedded-C for 1.2
Reported in version 1.0 on platform Other
Assigned to: Ian Craggs

On 2015-08-17 17:52:28 -0400, Mark Sonnentag wrote:

The MQTT-Embedded C++ client instantiates the Timer class on the stack in an inefficient manner.

For example in the subscribe method at line 719:

Timer timer = Timer(command_timeout_ms);

This basically asks the the compiler to instantiate a temporary object, call the copy constructor for the timer object and pass the temporary object and afterwards call the destructor for the temporary object.

The compiler can optimize it, but it does not have to.

A better version would be:

Timer timer(command_timeout_ms);

And so on for all other Timer instantiations.

I hope I have not missed anything as for why this might have been intented. I can commit all those changes once I have figured out how to contribute to this project.

On 2015-08-18 16:49:13 -0400, Ian Craggs wrote:

Mark, thanks. No I don't think I intended this particularly - I've been moving between languages a lot while maintaining the different clients, and it there was quite a long gap in my use of C++ because of the erratic support on small devices (until recently).

I can fix this myself, but please do contribute if you want. Some of our repositories have a pretty good guide, I think: http://git.eclipse.org/c/paho/org.eclipse.paho.mqtt.c.git/about/

On 2015-08-24 18:48:38 -0400, Eclipse Genie wrote:

New Gerrit change created: https://git.eclipse.org/r/54439

On 2015-08-24 18:55:30 -0400, Mark Sonnentag wrote:

Thanks Ian. I have pushed the changed client for a review. It is however the develop branch. I have noticed that the other reviews have been for the master branch.

I will open another "bug" report later. I made a list of additional improvements.

On 2015-08-25 06:23:32 -0400, Eclipse Genie wrote:

Gerrit change https://git.eclipse.org/r/54439 was merged to [develop].
Commit: http://git.eclipse.org/c/paho/org.eclipse.paho.mqtt.embedded-c.git/commit/?id=SHA: 8b8af11

On 2015-08-25 06:37:15 -0400, Ian Craggs wrote:

Making the changes to the develop branch is fine, and what I expected. I've accepted the changes. I will merge into master later.

MQTTClient.h - (re)subscribe to the same topic filter failed

Steps to reproduce the issue (e.g TI CC3200):

void loop() {
    int rc = 0;
    if (!client.isConnected()) {
        rc = connect();
    }

    if (rc == 0) {
        char json[56];
        sprintf(json, "{\"d\":{\"count\":%d}}\0", count++);
        Serial.print("Publishing: ");
        Serial.println(json);
        MQTT::Message message;
        message.qos = MQTT::QOS0; 
        message.retained = false;
        message.payload = json; 
        message.payloadlen = strlen(json);
        rc = client.publish(pubtopic, message);
        if (rc != 0) {
            Serial.print("Message publish failed with return code : ");
            Serial.println(rc);
        }

        Serial.print("Subscribing to topic : ");
        Serial.print(subtopic);
        rc = client.subscribe(subtopic, MQTT::QOS1, messageArrived);
        if (rc != 0) {
            Serial.print(" Subscribe failed with return code : ");
            Serial.println(rc);
        } else {
            Serial.println(" ...OK");
            client.yield(1000);
            Serial.print("Unsubscribing from topic : ");
            Serial.println(subtopic);
            rc = client.unsubscribe(subtopic);
            if (rc != 0) {
                Serial.print("  Unsubscribe failed with return code : ");
                Serial.println(rc);
            } else {
                Serial.println(" ...OK");
            }
        }

        if (rc != 0) {
            client.yield(60000);
        }

    }

    // Wait 10 seconds before publishing again
    client.yield(10000);
}

After iteration MAX_MESSAGE_HANDLERS (default is 5) the subscribe() failed as shown in the console:

Subscribe failed with return code : 1

I am testing my simple fix for this issue on CC3200,..

MQTT::Client::sendPacket send loop uses wrong length

migrated from Bugzilla #460389
status RESOLVED severity normal in component MQTT-Embedded-C for 1.1
Reported in version unspecified on platform Other
Assigned to: Ian Craggs

On 2015-02-19 18:15:55 -0500, Joe Planisky wrote:

MQTT::Client::sendPacket uses a 'while' loop to ensure all data in sendBuf is sent. However, in the call to 'ipstack.write', the length parameter is never updated to account for data already sent.

This line:

    rc = ipstack.write(&sendbuf[sent], length, timer.left_ms());

should be:

    rc = ipstack.write(&sendbuf[sent], length-sent, timer.left_ms());

On 2015-02-20 06:12:09 -0500, Ian Craggs wrote:

Thanks Joe. Fixed in master branch.

MQTTSerialize_ack parameters for packetid and dup are in wrong order for QoS level 1+ publish ACKs.

migrated from Bugzilla #453144
status RESOLVED severity normal in component MQTT-Embedded-C for 1.1
Reported in version unspecified on platform PC
Assigned to: Ian Craggs

On 2014-11-25 01:06:16 -0500, Jeff Smith wrote:

This bug results in messages not being correctly ACKed when using QoS levels 1 or 2. The message ID associated with the ACK is always 0 because it's coming from the dup flag, and packetid is being passed as the dup flag.

Solution:

In the file MQTTPacket/src/MQTTSerializePublish.c, in the functions MQTTSerialize_puback, MQTTSerialize_pubrel, and MQTTSerialize_pubcomp, the parameters packetid and dup supplied to MQTTSerialize_ack are in the wrong positions and should be swapped.

On 2015-01-19 12:04:20 -0500, Ian Craggs wrote:

Thanks Jeff. Fixed in master.

MQTTPacket_readnb fails to decode pingresp

migrated from Bugzilla #464367
status UNCONFIRMED severity normal in component MQTT-Embedded-C for 1.1
Reported in version 1.0 on platform PC
Assigned to: Ian Craggs

Original attachment names and IDs:

On 2015-04-10 04:13:47 -0400, Srikanth Kyatham wrote:

Created attachment 252282
If only header is available goto header bits

MQTTPacket_readnb is unable to decode the pingresp.
Since the pingresp is exactly 2 bytes. Its only the header bits and nothing else.

Its failing in here if I am right

line 390

case 2:
/* read the rest of the buffer using a callback to supply the rest of the data */

I have attached a patch hope it helps

Fix is
case 2:
if (trp->rem_len == 0)
goto header_exit;

Embedded C++ client cannot reconnect and resubscribe after broker failure

migrated from Bugzilla #464169
status RESOLVED severity normal in component MQTT-Embedded-C for 1.1
Reported in version unspecified on platform Other
Assigned to: Ian Craggs

On 2015-04-08 10:38:53 -0400, Joe Planisky wrote:

If a client is disconnected from the broker (e.g. because the broker crashed), the same client instance can reconnect to the broker, but cannot resubscribe to the same topics.

When a Client subscribes to a topic, an entry is added to the messageHandlers array. If all the slots in that array are used, attempts to subscribe to additional topics fail. There is no way to remove entries from that array once the connection to the broker is lost, so there's no way to reconnect and resubscribe once the broker comes back up without creating a new instance of the Client.

To put it another way, here's what I expect to be able to do:

  • create a Client
  • connect to broker (clean_session = true)
  • subscribe to topics
  • receive pubs
  • broker crashes | network failure, Client senses problem and isconnected = false.
  • broker restarts
  • same client instance connects to broker (clean_session = true)
  • subscribe to (same) topics
  • continue receiving pubs

On 2015-04-08 16:00:52 -0400, Ian Craggs wrote:

I've created a fix in the (newly created) develop branch, if you'd like to try it, Joe.

The second part will be to remove the message handler on unsubscribe.

On 2015-04-08 18:21:22 -0400, Joe Planisky wrote:

Initial testing looks good, Ian. We're able to reconnect & resubscribe after a broker crash.

On 2015-04-09 09:18:08 -0400, Ian Craggs wrote:

Code to remove message handler on unsubscribe now also added to the develop branch.

Arduino Library does not work on ESP8266 if SPI.h is not included

In IPStack.h it tries to include SPI.h (as this is required by normal Arduinos). However, if the user is using the ESP8266 Arduino core (https://github.com/esp8266/Arduino) and does not need to include SPI.h then a compile error will be thrown:

In file included from PahoESP8266.ino:6:0:
/Users/jamessutton/Documents/Arduino/libraries/MQTTClient/IPStack.h:22:19: fatal error: SPI.h: No such file or directory
   #include <SPI.h>
                   ^
compilation terminated.
Error compiling.

Because the ESP8266 does not require SPI for it's networking functions, a user is unlikely to want to include the SPI library just to get their sketch to compile.

I modified my local copy of IPStack.h to only attempt to include SPI.h if WiFi_h has not been defined. This is because, the ESP8266WiFi Library has defined it so should be a good indicator as to whether the client is being compiled for the ESP8266.

#ifndef WiFi_h
  #include <SPI.h>
#endif

I've tested this and it seems to work fine on my own machine / ESP8266, but I wouldn't say I'm confident enough with C to want to make the commit / Pull request myself in case this is a terrible idea, so thought it best to open as an issue.

Other than that, the library works great on the ESP8266, I've modified the Example sketch to work with it here: https://gist.github.com/jpwsutton/d364f46a54575f359fbe#file-paho_arduino_esp8266-ino

Undefined behavior due to packetid being modified twice before next sequence point

migrated from Bugzilla #475749
status RESOLVED severity normal in component MQTT-Embedded-C for 1.2
Reported in version 1.0 on platform Other
Assigned to: Ian Craggs

On 2015-08-24 19:29:01 -0400, Mark Sonnentag wrote:

This is about the c++ embedded client.

Alright so at line 77 (develop branch):

return next = (next == MAX_PACKET_ID) ? 1 : ++next;

next is modified twice here whenever next is != MAX_PACKET_ID.
1.) by the pre-increment
2.) by the assigment

This is in violation of the c++ standard and the result is undefined behavior.
It should be replaced by if/else or simply:
return next = (next == MAX_PACKET_ID) ? 1 : next + 1;

On 2015-08-25 06:50:37 -0400, Ian Craggs wrote:

Fix added to develop branch.

Example of connect with willFlag=1

I've searched the examples but can't find any that has a last will and testament. The code below generates a rc=-1 with MQTTSerialize_connect failing.

char willTopic[100] = "/device/";
strcat(willTopic,username);
strcat(willTopic,"/shadow/update");

MQTTPacket_connectData data = MQTTPacket_connectData_initializer;     
data.MQTTVersion = 3;
data.clientID.cstring = (char*) username;
data.username.cstring = (char*) username;
data.password.cstring = (char*) password;
data.cleansession = 1;
data.keepAliveInterval = 30;
data.will.message.cstring = (char*) "{\"connected\":false}";
data.will.topicName.cstring = (char*) willTopic;
data.willFlag = 1;


// this will call the read and write functions of the cellular code
int rc = _client->connect(data);
if (rc != 0) {
    ERROR(F("MQTT connect error: %d"),rc);
    return false;
} 

MQTTDeserialize_publish can give wrong results when sizeof(enum) != sizeof(int)

migrated from Bugzilla #464551
status RESOLVED severity normal in component MQTT-Embedded-C for 1.1
Reported in version unspecified on platform Other
Assigned to: Ian Craggs

On 2015-04-13 16:56:58 -0400, Joe Planisky wrote:

The parameters to MQTTDeserialize_publish include an "int* qos". In the Message struct defined in MQTTClient.h, the qos field is an enum. In the MQTT::Client<...>::cycle() method, the PUBLISH case calls MQTTDeserialize_publish and passes the address of Message struct fields dup, qos, and retained with &msg.qos being cast to an int* (&msg.dup and &msg.retained are cast to unsigned char*, which matches their bool definitions in the Message struct.)

Treating msg.qos as an int is problematic when sizeof(enum) == 1 byte. If sizeof(enum) is 1 byte, the address of msg.retained will point to a location within the (cast-to-int) msg.qos field. This causes erroneous results in MQTTDeserialize_publish in the code that reads the packetid if the qos > 0.

if (*qos > 0)
    *packetid = readInt(&curdata);

If sizeof(enum) == 1, for a QoS0 message with the retained bit set, the value of *qos in MQTTDeserialize_publish is 256 because the value of the retained bit gets written to a memory location within the cast-to-int qos. 256 > 0, which causes the code to erroneously read a packetid int.

This is not a problem with compilers (like gcc for the Atmel AVR line of MCUs) where sizeof(enum) == sizeof(int) == 2. It IS a problem with compilers (like that for the TI CC3200) where sizeof(enum) == 1 and sizeof(int) == 2.

Changing the qos parameter in MQTTDeserialize_publish to unsigned char* instead of int* seems to fix the problem, but causes MQTTFormat_toClientString to report wrong values for QoS and may have impacts in other places.

Many thanks to my colleague Kevin Buck for his diligent efforts in tracking this issue down.

On 2015-04-14 08:08:39 -0400, Joe Planisky wrote:

Just a note on the practical, observable effects of this issue.

If a client on a system with sizeof(enum) == 1 connects to a broker and subscribes with QoS0 to a topic that has been published with the retain bit set, the first (i.e. retained) payload received will be missing the first 2 bytes.

This is because MQTTDeserialize_publish erroneously reads an int (2 bytes) as the (non-existant) packetID. Subsequent updates of the value are received correctly because the retain bit is not set, so it doesn't corrupt the qos variable in MQTTDeserialize_publish.

We have a client that periodically publishes a value with the retain bit set. When a new client connects and subscribes to that topic, the first value it receives (the retained value) is missing the first 2 bytes. For example, instead of seeing the correct value of 1234567890, it gets 34567890. Subsequent updates of the value are received correctly.

On 2015-04-14 09:53:15 -0400, Ian Craggs wrote:

I believed that the C standard says that enums should be ints.

Out of interest, which compiler and platform is this?

The easiest solution will be to replace the enum with an int, and constants. I was trying to be more helpful than that, but that doesn't always work.

On 2015-04-14 10:29:01 -0400, Joe Planisky wrote:

Unfortunately, I don't have access to the official C standard documents. However, the relevant section is quoted in the answer to this StackOverflow question:

http://stackoverflow.com/questions/1113855/is-the-sizeofenum-sizeofint-always

It seems that compilers are free to choose the particular type to represent an enum (char, int, or unsigned int) at compile time. Apparently some choose to always represent an enum as an int, and some choose to use the smallest type that will contain all enum values in a program.

We are seeing this behavior on a TI CC3200 LaunchPad board using TI's Energia IDE (version 14) which includes the ARM version of GCC:

$ ./arm-none-eabi-gcc --version
arm-none-eabi-gcc (GNU Tools for ARM Embedded Processors) 4.8.4 20140725 (release) [ARM/embedded-4_8-branch revision 213147]

On 2015-04-14 11:06:12 -0400, Ian Craggs wrote:

So, the type for qos in MQTTDeserialize_publish (and MQTTSerialize_publish) could be changed to an enum. This should cause minimum disruption. Will this work for you?

You're using the C version of MQTTClient.h, not the C++ version, then?

On 2015-04-14 17:32:09 -0400, Joe Planisky wrote:

Changing parameter types to "enum QoS" seems to work, but I'm not sure it's the least disruptive. Unless I've misunderstood your suggestion, the "enum QoS" definition would have to be moved to someplace where MQTTDeserializePublish.c (and others) can see it. Plus it's currently in the MQTT namespace, so that would have to be maintained.

We are using the C++ client defined in MQTTClient/src/MQTTClient.h

Another possibility that seems less disruptive to me (although more wasteful of memory) is to change all "enum QoS" parameters and variables in the client code to "int". As far as I can tell, this only affects code in MQTTClient.h. Of course, this eliminates the type safety of using an enum to define legal QoS levels.

Note that in an earlier comment I said sizeof(int) == 2 on a CC3200, which is wrong. Sizeof(int) == 4 on that platform.

On 2015-04-15 06:09:53 -0400, Ian Craggs wrote:

The least disruptive will be to use a temporary integer in the MQTTDeserialize call in MQTTClient.h and then assign it to the enum in the Message structure.

        Message msg;
        int intQoS;
        if (MQTTDeserialize_publish((unsigned char*)&msg.dup, &intQoS, (unsigned char*)&msg.retained, (unsigned short*)&msg.id, &topicName,
                             (unsigned char**)&msg.payload, (int*)&msg.payloadlen, readbuf, MAX_MQTT_PACKET_SIZE) != 1)
            goto exit;
        msg.qos = (enum QoS)intQoS;

        I'm happy to go with that.  (On the basis that any expected value from the deserialize call is not going to overflow the enum)

On 2015-04-16 06:30:23 -0400, Ian Craggs wrote:

My last proposed fix pushed to develop branch.

Thanks guys, for finding and debugging this one.

Waspmote embedded C version

migrated from Bugzilla #462680
status ASSIGNED severity normal in component MQTT-Embedded-C for 1.1
Reported in version unspecified on platform Other
Assigned to: Ian Craggs

On 2015-03-20 09:00:16 -0400, Guy D wrote:

Similar to the Arduino Paho client is it possible building one for Libelium Waspmote?
Thanks
Guy

On 2015-03-31 08:32:13 -0400, Ian Craggs wrote:

Hi Guy.

so according to the website, the Waspmote has these wireless interfaces:

802.15.4 / ZigBee
LoRa 868 / 915MHz
Bluetooth Low Energy (BLE) 4.0
WiFi
6LoWPAN / IPv6 Radio
3G + GPS
GPRS + GPS
GSM / GPRS
Bluetooh PRO
RFID/NFC
Expansion Radio Board
Waspmote Gateway

I think we're talking about the WiFi interface in this case, right?

On 2015-03-31 10:11:55 -0400, Guy D wrote:

Hi Ian,

Indeed these are the available (wireless) communication modules.

Wifi is one but I don't know if it's difficult also to have it for GSM/GPRS, 3G?
The latter two would be interesting in cases of having edge devices somewhere in the field with GSM/GPRS or 3G communication communicating with an MQTT broker in the cloud.

Thanks.
Guy

On 2015-04-24 13:22:05 -0400, Guy D wrote:

Hi Ian,

I don't know if you already had the chance starting?
The most important would be GSM/GPRS and WiFi.

If you are too busy with other things, maybe you can give me some starting points so I can try to do the port myself?

Thanks.
Guy

On 2015-04-28 09:08:50 -0400, Ian Craggs wrote:

There are two classes that need to be written and tested to make the API work on the WaspMote.

  1. A timer class. This is the Arduino version:

http://git.eclipse.org/c/paho/org.eclipse.paho.mqtt.embedded-c.git/tree/MQTTClient/src/arduino/Countdown.h

which relies on the Arduino millis() function. If the WaspMote supports the millis() function too, then this class should work as is.

  1. A network class, for each networking interface you want to use. An example for Arduino is here:

http://git.eclipse.org/c/paho/org.eclipse.paho.mqtt.embedded-c.git/tree/MQTTClient/src/arduino/WifiIPStack.h

The absolutely necessary methods are:

int read(char* buffer, int len, int timeout);  // read data, length len, from the network into the supplied buffer.  The timeout is in milliseconds.

int write(char* buffer, int len, int timeout); // write date length len from the buffer to the network.  Again the timeout is in milliseconds.

All the other methods are optional, for convenience.

Looking at the WaspMote wifi networking guide here: http://www.libelium.com/development/waspmote/documentation/wifi-networking-guide/, I see that Chapter 13 has a coding example.

So the read and write methods of the networking class would have to call

WIFI.send(buffer, len);

and

WIFI.read(UNBLO); // times out after 2 seconds, according to the doc

respectively, after having setup the WIFI connection. Does this make sense? Does it get you started?

Support for 3.1.1

I noticed the Paho MQTT Client libraries support MQTT 3.1.1. Is there any support for 3.1.1. for MQTTPacket?

Arduino download link is broken

migrated from Bugzilla #462690
status RESOLVED severity normal in component MQTT-Embedded-C for 1.1
Reported in version v0.5 on platform PC
Assigned to: Ian Craggs

On 2015-03-20 10:37:13 -0400, Benjamin Cabé wrote:

On https://eclipse.org/paho/clients/c/embedded/ the download link for the arduino zip should be https://www.eclipse.org/downloads/download.php?file=/paho/arduino_1.0.0.zip

On 2015-03-20 12:08:23 -0400, Ian Craggs wrote:

Thanks Benjamin. I've updated the link to point to the project downloads page, so that in future I only need to change the link information in one place. There are some other pages that need to be updated similarly, which I will do asap.

Tell me if you think this is ok, or if you have another suggestion.

On 2015-03-20 12:12:36 -0400, Benjamin Cabé wrote:

(In reply to Ian Craggs from comment # 1)

Tell me if you think this is ok, or if you have another suggestion.

I have no other suggestion. This is great :)

Keepalive Fix + Enhancement

migrated from Bugzilla #481454
status UNCONFIRMED severity enhancement in component MQTT-Embedded-C for 1.2
Reported in version 1.0 on platform All
Assigned to: Ian Craggs

Original attachment names and IDs:

On 2015-11-04 15:58:22 -0500, John Rotach wrote:

Created attachment 257744
git patch for keepalive

Currently the return value from keepalive is unused. This prevents client disconnect on dead TCP connections. This change addresses this.

Also in this change is what we believe to be an enhancement to ping handing. In our disconnect testing resetting the ping timer on a successful packet send (in sendPacket) prevented the client from determining a disconnect until an underlying TCP buffer error occurs. Using our default Linux configuration this was much longer than the keepalive specified to the client. We have made an update to only use the PINGREQ/PINGRESP mechanism. Any feedback on this design would be much appreciated.

MQTTClient/src/MQTTClient.h missing + erroneous include statements

migrated from Bugzilla #478665
status ASSIGNED severity normal in component MQTT-Embedded-C for 1.2
Reported in version 1.0 on platform PC
Assigned to: Ian Craggs

On 2015-09-29 15:04:04 -0400, David H. wrote:

MQTTClient/src/MQTTClient.h has two issues with included libraries.

  1. #include "stdio.h" should be #include <stdio.h>
  2. #include <string.h> needs to be added for memcpy to work (called on lines 695 and 868)

I noticed the memcpy error when I ran build.sh in MQTTClient/samples/linux; output below:

me:linux:% sh build.sh
In file included from hello.cpp:3:0:
../../src/MQTTClient.h: In instantiation of �int MQTT::Client<Network, Timer, MAX_MQTT_PACKET_SIZE, MAX_MESSAGE_HANDLERS>::connect(MQTTPacket_connectData&) [with Network = IPStack; Timer = Countdown; int MAX_MQTT_PACKET_SIZE = 100; int MAX_MESSAGE_HANDLERS = 5]�:
hello.cpp:42:29: required from here
../../src/MQTTClient.h:695:15: error: �memcpy� was not declared in this scope, and no declarations were found by argument-dependent lookup at the point of instantiation [-fpermissive]
memcpy(sendbuf, pubbuf, MAX_MQTT_PACKET_SIZE);
^
In file included from ../../src/linux/linux.cpp:32:0,
from hello.cpp:7:
/usr/include/string.h:46:14: note: �void* memcpy(void_, const void_, size_t)� declared here, later in the translation unit
extern void _memcpy (void *_restrict dest, const void *restrict src,
^
In file included from hello.cpp:3:0:
../../src/MQTTClient.h: In instantiation of �int MQTT::Client<Network, Timer, MAX_MQTT_PACKET_SIZE, MAX_MESSAGE_HANDLERS>::publish(const char
, void
, size_t, short unsigned int&, MQTT::QoS, bool) [with Network = IPStack; Timer = Countdown; int MAX_MQTT_PACKET_SIZE = 100; int MAX_MESSAGE_HANDLERS = 5; size_t = long unsigned int]�:
../../src/MQTTClient.h:888:19: required from �int MQTT::Client<Network, Timer, MAX_MQTT_PACKET_SIZE, MAX_MESSAGE_HANDLERS>::publish(const char
, void
, size_t, MQTT::QoS, bool) [with Network = IPStack; Timer = Countdown; int MAX_MQTT_PACKET_SIZE = 100; int MAX_MESSAGE_HANDLERS = 5; size_t = long unsigned int]�
../../src/MQTTClient.h:895:19: required from �int MQTT::Client<Network, Timer, MAX_MQTT_PACKET_SIZE, MAX_MESSAGE_HANDLERS>::publish(const char
, MQTT::Message&) [with Network = IPStack; Timer = Countdown; int MAX_MQTT_PACKET_SIZE = 100; int MAX_MESSAGE_HANDLERS = 5]�
hello.cpp:61:39: required from here
../../src/MQTTClient.h:868:15: error: �memcpy� was not declared in this scope, and no declarations were found by argument-dependent lookup at the point of instantiation [-fpermissive]
memcpy(pubbuf, sendbuf, len);
^
In file included from ../../src/linux/linux.cpp:32:0,
from hello.cpp:7:
/usr/include/string.h:46:14: note: �void* memcpy(void
, const void
, size_t)� declared here, later in the translation unit
extern void _memcpy (void *__restrict __dest, const void *_restrict src,
^
In file included from stdoutsub.cpp:40:0:
../../src/MQTTClient.h: In instantiation of �int MQTT::Client<Network, Timer, MAX_MQTT_PACKET_SIZE, MAX_MESSAGE_HANDLERS>::connect(MQTTPacket_connectData&) [with Network = IPStack; Timer = Countdown; int MAX_MQTT_PACKET_SIZE = 1000; int MAX_MESSAGE_HANDLERS = 5]�:
stdoutsub.cpp:188:26: required from here
../../src/MQTTClient.h:695:15: error: �memcpy� was not declared in this scope, and no declarations were found by argument-dependent lookup at the point of instantiation [-fpermissive]
memcpy(sendbuf, pubbuf, MAX_MQTT_PACKET_SIZE);
^
In file included from ../../src/linux/linux.cpp:32:0,
from stdoutsub.cpp:44:
/usr/include/string.h:46:14: note: �void
memcpy(void
, const void
, size_t)� declared here, later in the translation unit
extern void *memcpy (void *__restrict __dest, const void *__restrict __src,

Side note: it's unclear if stdio.h is necessary. Removing it doesn't produce any compile errors, and a quick search didn't locate any lines that use it. But I may have missed something.

On 2015-09-30 06:01:55 -0400, Ian Craggs wrote:

I don't get any errors when I build on my RedHat installation, but I'm happy to make the change in the include.

On 2015-09-30 07:49:32 -0400, David H. wrote:

That's odd; I'm on Fedora. I'd expect that you'd get the same errors on Red Hat. Maybe our compilers are set up differently?

Looking for programmers guide and reference

I'd like to use this C client library in a project but I am having trouble finding documentation on how to use the APIs. Reading the code and code samples aren't cutting it for me. Is there any documentation on using the APIs?

C client's readPacket can overflow read buffer

The C client's readPacket reads the message size from the incoming packet and then reads that much data into the read buffer (c->readbuf) with no regard for the read buffer's size (c->readbuf_size). This means that messages larger than the read buffer's size will always cause a buffer overflow.

We're using FreeRTOS, with a read buffer that's allocated on the stack of the task that's handling Mqtt. When this buffer overflow occurs it smashes our stack (including the MQTTClient) and leads to anomalous behaviour.

A couple of small improvements to embedded c++ client

migrated from Bugzilla #475751
status ASSIGNED severity enhancement in component MQTT-Embedded-C for 1.2
Reported in version 1.0 on platform Other
Assigned to: Ian Craggs

On 2015-08-24 19:58:40 -0400, Mark Sonnentag wrote:

Just a couple of suggestions for improvements:

1.) this->var = var is bad style in c++. CDT even reports it as a warning (-wshadow)
It is better to use a different name for the member variable (m_var, var_ or something like that).

2.) Casts: C-Style cast shouldn't be used in C++. C++ has its own casts. The advantage is that the C++ can be only used for particular tasks instead of the jack of all trades C cast. The intention of the cast is clear and the potentially most dangerous casts like reinterpret_cast and const_cast can be easily spotted in the source.

3.) Out-parameters: The out-parameters are passed as a reference to a variable. Imho it is better to pass variables that are modified as a pointer. This way it is clear for the caller that this variable is modified. References are fine for in-params (breaks the API)

4.) "Template" files for Network/Timer classes. Files with all necessary methods of the Network and Timer classes, empty bodies and some comments would help with porting the client.

5.) Currently the user of the mqtt client is supposed to connect to the mqtt broker server prior to telling the mqtt client to connect. This is my opinion bad design, because the mqtt client uses the network anyways. The result is that a connection and the mqtt client has to be injected in class X that uses the client, although the network connection is logically below the client. I think it would be be better if the mqtt client would establish the connection to the server at the beginning of the
int MQTT::Client<Network, Timer, MAX_MQTT_PACKET_SIZE, b>::connect(MQTTPacket_connectData& options) method. The user of the client could implement a connect method in the Network class for this purpose. Same applies to disconnect. This breaks the current API, however the behavior could be controlled with a macro.

On 2015-08-25 07:16:32 -0400, Ian Craggs wrote:

  1. do you mean referring to this-> at all? In the case that the parameter name is the same as the variable, I prefer to change the parameter name. So this is a couple of instances of

this->command_timeout_ms = command_timeout_ms;

  1. The only hesitation I have with this is knowing which versions of C++ support this. I want the API to be as portable as possible, and embedded environments can have varying levels of C++ compiler. I think there is only one instance (enum QoS)?

  2. Using references rather than pointers does have an effect on some APIs. References give a simpler and more native look and feel on the Arduini, for instance. I see the logic behind your suggestion, and would bear it in mind for a later time.

  3. Definitely. This is a good idea.

  4. I took this approach in the spirit of keeping the API as minimalist as I could (although the per subscription message handlers violate that spirit -- I added them due to popular demand). Thinking about it, I'm still more in favour of my current approach, although if we were changing the API substantially at some later point, I would bear it in mind.

On 2015-08-25 09:42:50 -0400, Mark Sonnentag wrote:

1.) Yes. There are more instances however like
this->keepAliveInterval = options.keepAliveInterval;
It is just not necessary and reduces a bit the amount of code that one has to read beside avoiding the warning by the compiler/cdt. Renaming the parameters works as well of course (var = aVar like the constructor of MessageData)

2.) Afaik there should not be a C++ compiler for any embedded device that does not know C++ casts. They have been part of C++98 Standard already. They are not a C++11 feature or anything like that.

There are quite few C style casts in the client source e.g.:
if (MQTTDeserialize_publish((unsigned char_)&msg.dup, &intQoS, (unsigned char_)&msg.retained, (unsigned short_)&msg.id, &topicName,
(unsigned char__)&msg.payload, (int_)&msg.payloadlen, readbuf, MAX_MQTT_PACKET_SIZE) != 1)

and even a ambigious cast (const cast):
MQTTString topic = {(char*)topicFilter, {0, 0}};

You only know what happens here if you compare the datatypes.
The C++ variant would be:
MQTTString topic = {const_cast<char*>(topicFilter), {0, 0}};

Then everyone knows just by looking at the cast that const has been cast away of a char* and that it will never do anything else no matter what topicFilter is. If the code changes then C style cast variant could even become a reinterpret_cast and then you have a potential bug.

But it is good that you mention the (enum QoS) cast. This is potentially a bug. Casting an integer to an enum is undefined behavior in C++ if the integer value is not equal to at least one of the enum values.
Someone could send a MQTT packet with a QOS value of 3.

3.) Yes I have seen that passing out parameters as a reference instead of pointers is quite common in an Arduino environment. A non API breaking alternative would be a clear documentation. Doxygen supports for example @param[in], @param[inout] and @param[out]

  1. My idea was to add a macro to the network template file. If the macro is not defined then the couple of lines in the mqttclient connect and disconnect method are removed by the preprocessor. This way it technically breaks the API but it affects you only if you decide to use the feature otherwise the client code is the same as before and you can still decl/define connect/disconnect methods in the network however you like (see arduino/mbed samples).

Your approach of sticking with a minimal API is definitely the way to go for an embedded device.
The main problem is just that the API is not consistent currently. The client can receive/send on its own by using the network stack however it cannot connect/disconnect. The same interface is used everytime.

If you want then I can push 1, 2, 4 and maybe 3(comment variant) to Gerrit after I have tested the changes against the test python server. The client could silently break with 2.

embedded mqtt send / receive tasks hung-up when running concurrently on STM32

So I am using paho.mqtt.embedded-c MQTT library on board STM32F107, with LWIP 1.4.1 as tcp/ip stack library, freeRTOS as embedded OS. With reference to MQTTEcho.c example code, I created mqtt send and recv tasks separately.

While doing test work with mqtt.fx tool, I found that if the data transmit frequency is not very high, both send and recv task work well, if the frequency is high enough, there will be a good chance that MQTTPublish method does not return, thus both send and recv task got suspended.

1)STACK SIZE and PRIORITY of the two tasks are as follows
#define MQTT_RECVTASK_PRIORITY ( tskIDLE_PRIORITY + 3 )
#define MQTT_SENDTASK_PRIORITY ( tskIDLE_PRIORITY + 3 )
#define MQTT_RECVTASK_STACKSIZE configMINIMAL_STACK_SIZE * 6 //768bytes
#define MQTT_SENDTASK_STACKSIZE configMINIMAL_STACK_SIZE * 4 //512bytes

2)The detailed implementation of the task is as follows

void mqttRecvMessageTask(void *pvParameters)
{
    Timer timer;
    TimerInit(&timer);
    int rc = 0;

    for (;;)
    {
        while (g_hostState.mqttState < MQTT_SUBSCRIBED)
        {
            vTaskDelay(200);
            continue;
        }

        TimerCountdownMS(&timer, 500); /* Don't wait too long if no traffic is incoming */
        if(MQTT_PINGERR == cycle(&client, &timer))
        {
            LED_GREEN_OFF();
            LED_BLUE_ON();
            PDEBUG("PING ERROR\r\n");
            MQTTDisconnect(&client);
            FreeRTOS_disconnect(&network);
            g_hostState.mqttState = MQTT_READY;
        }
    }
}
void mqttSendMessageTask(void *pvParameters)
 {
   int rc = 0;

   for (;;)
   {
       while (g_hostState.mqttState < MQTT_CONNECTED)
       {
           vTaskDelay(200);
           continue;
       }

       MessageBuffer *pSendData = NULL;
       BaseType_t xStatus = xQueueReceive(mqttSendQueue, &pSendData, 100);
       if (xStatus == pdPASS)
       {
          if ((rc = MQTTPublish(&client, pSendData->topic, &pSendData->message)) != MQTT_SUCCESS)
          {
            LED_GREEN_OFF();
            LED_BLUE_ON();
            PDEBUG("SEND ERROR\r\n");
            MQTTDisconnect(&client);
            FreeRTOS_disconnect(&network);
            g_hostState.mqttState = MQTT_READY;
          }
          vPortFree(pSendData->message.payload);
          vPortFree(pSendData);
          pSendData = NULL;
          PDEBUG("3\r\n");
       }
   }
}

I doubt the reason is related to that both mqtt send and recv tasks are running concurrently, because if I comment out MQTTPublish in send task, there will be no hangs any more. I noticed that the MQTTEcho.c example used MutexLock and MutexUnLock and I tried them too, but gave up because the result was out of control. Is that the key?

Reconnection logic in the synchronous embedded C client

migrated from Bugzilla #442030
status RESOLVED severity enhancement in component MQTT-Embedded-C for 1.2
Reported in version 1.0 on platform PC
Assigned to: Ian Craggs

On 2014-08-19 05:55:46 -0400, Ian Craggs wrote:

At the moment, the synchronous embedded C++ client does not automatically reconnect.
It does not make a call to a connectionLost callback either.
You have to call connect when a call fails, by checking the return code.

People seem to expect or want automatic reconnection - should we add this?

Also, resending any inflight QoS 2 message on reconnect needs to be sorted.

On 2015-04-15 07:59:55 -0400, Ian Craggs wrote:

Dealing with resending inflight QoS 2 messages has been added.

No one has yet asked for automatic reconnect, and as this would require extra code, I'm leaving it out unless it is asked for.

A networked error on .read() will not make the client disconnected.

Hi again,

I found another issue while working on the arduino-mqtt library.

It looks like that errors from the read() method in the Network class do not traverse up in the client and set the internal flag to disconnected. This has the effect that clients, that never send any packets and only read from the connection, never change the internal "connected" flag if the underlying connection fails.

A fix would be to set the client to disconnected if any serious errors happen while reading from the underlying connection. That way, a future call to isConnected() would correctly return false.

can't build with -DREVERSED

migrated from Bugzilla #445038
status RESOLVED severity blocker in component MQTT-Embedded-C for 1.1
Reported in version unspecified on platform Other
Assigned to: Al Stockdill-Mander

On 2014-09-25 02:57:47 -0400, Akihiro Yamazaki wrote:

How to repeat

$ cd paho/MQTTPacket/samples

$ git remote -v
origin http://git.eclipse.org/gitroot/paho/org.eclipse.paho.mqtt.embedded-c.git (fetch)
origin http://git.eclipse.org/gitroot/paho/org.eclipse.paho.mqtt.embedded-c.git (push)

$ git log -1 --pretty=short
commit SHA: 8e6d4a4
Author: Al S-M [email protected]

c client layer and cc3200 implementation

$ cc qos0pub.c -DREVERSED -I ../src ../src/MQTTConnectClient.c
../src/MQTTSerializePublish.c ../src/MQTTPacket.c -o qos0pub -Os -s
In file included from ../src/MQTTPacket.h:91:0,
from qos0pub.c:17:
../src/MQTTConnect.h:113:18: error: �y� undeclared here (not in a function)
unsigned int : y; /**< unused */
^
(snip)

Patch

diff --git a/MQTTPacket/src/MQTTConnect.h b/MQTTPacket/src/MQTTConnect.h
index 8577289..db90251 100644
--- a/MQTTPacket/src/MQTTConnect.h
+++ b/MQTTPacket/src/MQTTConnect.h
@@ -110,7 +110,7 @@ typedef union
struct
{
unsigned int sessionpresent : 1; /**< session present flag */

  •           unsigned int : y;                         /**< unused */
    
  •           unsigned int : 7;                         /**< unused */
    } bits;
    
    #else
    struct

On 2014-09-25 06:00:34 -0400, Ian Craggs wrote:

Assigning to Al.

On 2014-09-25 06:55:10 -0400, Al Stockdill-Mander wrote:

I have pushed a fix for this to Gerrit

CC3200 port breaks FreeRTOS scheduler

migrated from Bugzilla #448039
status NEW severity major in component MQTT-Embedded-C for 1.1
Reported in version unspecified on platform Other
Assigned to: Ian Craggs

On 2014-10-21 05:51:51 -0400, Tiit Rätsep wrote:

The CC3200 port of paho client configures the SysTick timer and interrupt and that seems to break the FreeRTOS scheduler. Most example code for the CC3200 runs technically single threaded after the network configuration so this bug doesn't seem to affect most examples but when tasks need to be switched it's evident that the interrupt is misconfigured.

On 2014-10-21 12:00:44 -0400, Al Stockdill-Mander wrote:

I am speaking to TI atm on an alternative way to run the timer I need without using SysTick

On 2014-10-21 12:08:26 -0400, Tiit Rätsep wrote:

The way I solved it for myself was that I removed the part that messed up SysTick and I manually call the millisecond interrupt in my SysTick handler. That may not be the best solution but it works for me.

On 2014-10-21 12:15:13 -0400, Al Stockdill-Mander wrote:

If that resolves the issue and other examples still work, please feel free to submit your change, we have Gerrit enabled on the repository, you would need to sign the CLA first (https://www.eclipse.org/legal/CLA.php) and this page talks about how to use Gerrit http://wiki.eclipse.org/Gerrit

On 2014-10-21 12:21:11 -0400, Tiit Rätsep wrote:

I will work a bit more on this before I do anything as drastic as commit code here. The solution is not very elegant either as it requires one to manually call the function to increment the millisecond counter and for that one needs to enable the SysTick handler from FreeRTOS config and rebuild that. After that it does work.

I seem to still have problems with my example. With one connection everything works but I want to have two threads. Both will have their own client and connection. At the moment it seems that calling MQTTYield from both breaks everything (something is not thread safe most likely). Calling MQTTYield only from the subscriber thread makes the other thread time out and generally work extremely slow...

On 2014-10-21 12:53:30 -0400, Tiit Rätsep wrote:

Ok ... fixed the multithread issue. It seems that sl_Select can only be called from one thread at a time. I had one thread doing a really long MQTTYield wait (1 s) and the other one needed a short time there. The way I got it to work was to add some osi_Sleep after the waiting to give time for the other thread to do it's thing.

Back to the timer issue ... I'm still not sure if my solution is the best for this issue as this would not be compatible with most of the code already written for this library as it needs the user to manually call a function inside the SysTick handler. If you can suggest a better solution I'd be more than glad to use that instead but I think this thread here could save someone the whole day of head-scratching I just finished...

Race condition between MQTTSubscribe and Rx of queued publications

migrated from Bugzilla #477971
status ASSIGNED severity normal in component MQTT-Embedded-C for 1.2
Reported in version unspecified on platform Other
Assigned to: Ian Craggs

Original attachment names and IDs:

On 2015-09-21 11:36:27 -0400, Alex Lennon wrote:

Hi,

Thanks for the great work on the embedded-C libraries. I am currently using these on a Kinetis platform with lwIP.

I think I see a race condition occurring when I bring up the device.

The execution path on power up is

ConnectNetwork()
MQTTConnect() clean session is 0
MQTTSubscribe(topic) qos is 1
while(running)
MQTTYield()

I can see we have queued messages on the server from the existing subscription (last time device ran) which are being lost

Debugging I can see

Connecting to server 'xxx:1883 socket'
Connecting as client: 'xxx', user: '', password: ''
Got ACK packet: 2
Subscribing to xxx
Got PUBLISH packet: 3
Got ACK packet: 9
Subscribed OK

So I think what is happening is that MQTTSubscribe() is blocking waiting on the subscription ACK when the publication of a queued message comes in.

MQTTSubscribe() hasn't yet set-up the message handler so the message is lost.

I have worked around this by pre-setting the message handler before I issue the MQTTSubscribe but thought I would let you know.

Regards, Alex

On 2015-09-21 11:46:56 -0400, Alex Lennon wrote:

Created attachment 256718
Workaround to preset handler before subscription

On 2015-09-24 16:26:37 -0400, Ian Craggs wrote:

Hi Alex.

yes, I can see that would be a problem.

Why don't we just change the subscribe function so that the callback is set before the subscribe packet is sent, and then if the subscribe fails, we can remove the callback?

Then, no API changes are needed.

On 2015-09-24 18:23:03 -0400, Alex Lennon wrote:

Hi Ian,

"Why don't we just change the subscribe function so that the callback is set before the subscribe packet is sent, and then if the subscribe fails, we can remove the callback?"

It's a long time since I looked at MQisdp. I'm not sure I can remember the details of the original implementation completely, and I certainly don't know what the current implementation is doing to be able to make sensible commentary.

I see what you're suggesting and I agree up to a point. My patch isn't offered as a solution so much as a talking point. I completely agree on avoiding API changes and your suggestion would be preferable to my workaround.

That said, I am not clear on when a broker may provide a message after a connection is established. If it were the case that a retained message on the broker could be provided at any point after a connection ack then we'd still have a race against a subscription call and should probably ensure topic subscriptions are in place before the connection is made?

But I don't know. What do you think?

Fix for Makefile for org.eclipse.paho.mqtt.embedded-c

migrated from Bugzilla #472694
status UNCONFIRMED severity normal in component MQTT-Embedded-C for 1.2
Reported in version 1.2 on platform PC
Assigned to: Ian Craggs

Original attachment names and IDs:

On 2015-07-15 03:40:39 -0400, nice sw wrote:

Created attachment 255201
Makefile fix

Hi there,

to fix the following error (occurring under GNU/Linux):

me@deb:~/mqtt/org.eclipse.paho.mqtt.embedded-c$ make
mkdir -p build/output/samples
mkdir -p build/output/test
cc -o build/output/samples/pub0sub1 MQTTPacket/src/../samples/pub0sub1.c -lpaho-embed-mqtt3c -I MQTTPacket/src -L build/output
/tmp/cc9gmSDV.o: In function main': pub0sub1.c:(.text+0x13b): undefined reference totransport_open'
pub0sub1.c:(.text+0x1c5): undefined reference to transport_sendPacketBuffer' pub0sub1.c:(.text+0x1d7): undefined reference totransport_getdata'
pub0sub1.c:(.text+0x29e): undefined reference to transport_sendPacketBuffer' pub0sub1.c:(.text+0x2b0): undefined reference totransport_getdata'
pub0sub1.c:(.text+0x345): undefined reference to transport_getdata' pub0sub1.c:(.text+0x430): undefined reference totransport_sendPacketBuffer'
pub0sub1.c:(.text+0x479): undefined reference to transport_sendPacketBuffer' pub0sub1.c:(.text+0x486): undefined reference totransport_close'
collect2: error: ld returned 1 exit status
Makefile:106: recipe for target 'build/output/samples/pub0sub1' failed
make: *** [build/output/samples/pub0sub1] Error 1

please change the Makefile to the following:

${SYNC_SAMPLES}: ${blddir}/samples/%: ${srcdir}/../samples/%.c ${srcdir}/../samples/transport.o
${CC} -o $@ $^ -l${MQTT_EMBED_LIB_C} ${FLAGS_EXE}

It's also in the attachment.
(Note: this is fix for ifeq ($(OSTYPE),Linux). Possibly it also works for ifeq ($(OSTYPE),Darwin))

Please add as commit.

Regards,
Nice Sw.

On 2015-07-15 04:10:10 -0400, nice sw wrote:

Oh and general question
(see also here https://bugs.eclipse.org/bugs/show_bug.cgi?id=471765#comment_link_1)

Can you comment on the state of this library?
Experimental, Stable, in transition, etc?

Perhaps also comparison with other libraries such as
http://git.eclipse.org/c/mosquitto/org.eclipse.mosquitto.git/tree/lib/cpp
(What I do not like about mosquittopp c++ client library is that I cannot even define a callback for a specific subscription.
Instead there's a general on_message(),
http://git.eclipse.org/c/mosquitto/org.eclipse.mosquitto.git/tree/lib/cpp/mosquittopp.h#n98
which is horribly inefficient, since I have to do string comparisons etc.
I think the C++ interface of mqtt.embedded-c is much better in this regard, right?)

Thanks for comments.

On 2015-07-15 05:14:16 -0400, nice sw wrote:

Oh another thing:
In the directory MQTTClient/samples/linux

build.sh (commit it as executable) fails with memcpy.

Add the line

include <string.h>

to MQTTClient/src/MQTTClient.h

(By the way: is there a particular reason why you use #include <string.h> and not #include ?? Also e.g. in MQTTClient/samples/linux/main.cpp )

Oh and in this sample:
MQTTClient/samples/linux/hello

I get the error line
"Socket error Resource temporarily unavailable in read for socket 3"
The reason for this is that the function IPStack::Socket_error() gets triggered (file is MQTTClient/src/linux/linux.cpp); and errno == EAGAIN.

Is it possible, that to solve this, one needs to go to around line 128 in MQTTClient/src/linux/linux.cpp; and check when a MQTT-packet is completely received. ??
(Along the lines described here: http://developerweb.net/viewtopic.php?pid=25219#p25219 i.e. using length-field)

Thanks.

PUBREL packet should be QoS 1

migrated from Bugzilla #455961
status RESOLVED severity normal in component MQTT-Embedded-C for 1.1
Reported in version unspecified on platform PC
Assigned to: Ian Craggs

On 2014-12-22 10:23:06 -0500, Ian Craggs wrote:

The PUBREL packet should be QoS 1, not QoS 0, in MQTTSerializePublish.c

On 2014-12-23 09:33:13 -0500, Ian Craggs wrote:

Fixed in master branch

Signed function call result stored into unsigned variable

migrated from Bugzilla #449221
status RESOLVED severity trivial in component MQTT-Embedded-C for 1.1
Reported in version v0.5 on platform All
Assigned to: Ian Craggs

On 2014-10-29 12:14:33 -0400, Mario Malenica wrote:

File: MQTTClient.c
function: int cycle(Client *c, Timer *timer)

unsigned short packet_type = readPacket(c, timer);

readPacket returns int value and if the call fails for some reason (network connection error), negative int value (FAILURE) will be converted to 0xFFFF and returned to the caller (in my case it was the MQTTYield function). It will then call cycle() in a loop until the timer expires.

Proposed change: Change the variable packet_type to signed int.

On 2015-02-04 10:18:25 -0500, Ian Craggs wrote:

Thanks Mario. I seem to have fixed this a while back, I don't remember the details, sorry.

Uninitlized variable.

migrated from Bugzilla #444792
status RESOLVED severity major in component MQTT-Embedded-C for 1.1
Reported in version v0.5 on platform PC
Assigned to: Ian Craggs

On 2014-09-23 02:55:55 -0400, Kamal Baker wrote:

The variable 'c' which is used to read the header bytes from the socket is used before initilization in MQTTPacket_decode. This variable caused the client to believe that there were data to read. The OS used is Freescale MQX with the RTCS stack. The fix is to set the variable to '0' before read in the do/while loop

Regards
Kamal Baker

On 2014-09-23 06:14:15 -0400, Ian Craggs wrote:

The first use of the variable c is to be written to by the function getcharfn, which is why it is not initialized.

The function getcharfn should return 0 or -1 if if fails to read the data, 1 if successful. This is the test that determines whether the network read was successful or not.

We can initialize the variable c, but if getcharfn is behaving as intended, then it will make no difference. Maybe the socket read call on this platform is returning a different value?

On 2015-01-13 05:53:19 -0500, Ian Craggs wrote:

The return code from getcharfn, 0 or -1, determines the success of the read call, not the value in c.

Max message size for embedded c?

Hi,

is there a max size for messages?

When I get a few more than 1000 Bytes (+ the topic Bytes I guess) no Message will be sent to the Broker.
Or might there be a HW limitation from the embedded device (Bosch XDK)?

I know this problem from the ESP8266, which would fail at around120 Bytes, where I had to use a modified MQTT client (not Paho) version which streams the messages instead of sendig it as a single packet.

Thanks & BR
Daniel

Asynchronous reading from and writing to the network

I need to be able to publish to the MQTT broker directly when an event is available in my application. This is not possible in the two current implementations of using this library:

  • MQTTYield() only returns when a message has been received or when there is a time-out. I cannot cancel the wait so that I can publish
  • Using the worker thread, there is a read time-out of 500 ms while a mutex is locked. This same mutex is locked when publishing a message

I propose using threads or socket callbacks to separate read and write operations.

Using Threads

The user thread is the only thread that performs write operations. The read thread spawned by the library is the only thread that performs read operations. The read thread is the producer of incoming messages, and the user thread is the consumer of them.

In the case when a response is required after a write operation, the user thread waits with a time-out on the read thread to put the response message in a shared variable and release a lock on it (produce) so that the user thread can read and process it (consume). If the read thread reads a non-response message (e.g. a publish from the broker), then it should call back to the user application.

So what the read thread does is:

while (true) {
    msg_t m = receive();
    if (is_response_type(m)) {
        lock(message_mutex);
        message = m;
        unlock(message_mutex);
    } else {
        message_received(m);
    }
}

Using Callbacks

This would work similar to threads, but there instead of having a thread that reads continuously, there is a callback set that gets called when data is available on the socket. This may be a more efficient way of working with sockets as they don't need a thread, but it requires the operating system's sockets to support these callbacks. Since this library is intended for embedded use, I would not require this to be supported by the network interface.

MQTTPacket_decodenb() failure mode

Hi everyone, hi Ian
I happened to have found a bug in my MQTTPacket.c non-blocking
functions, particularly the one that extracts the message length:
MQTTPacket_decodenb()

On really slow links, if TCP (or whatever underlying transport) fails to
provide the whole length bytes before this function is called 4 times,
next call will exit with an error code. The problem is that the function
is also counting "additional entries" in addition to properly counting
received bytes.
Correction is attached: correctdecodenb.zip
Basically:

diff --git a/MQTTPacket/src/MQTTPacket.c b/MQTTPacket/src/MQTTPacket.c
index bd5f90a..e4746cd 100644
--- a/MQTTPacket/src/MQTTPacket.c
+++ b/MQTTPacket/src/MQTTPacket.c
@@ -333,14 +333,15 @@ static int MQTTPacket_decodenb(MQTTTransport *trp)
 	}
 	do {
 		int frc;
-		if (++(trp->len) > MAX_NO_OF_REMAINING_LENGTH_BYTES)
+		if (trp->len >= MAX_NO_OF_REMAINING_LENGTH_BYTES)
 			goto exit;
 		if ((frc=(*trp->getfn)(trp->sck, &c, 1)) == -1)
 			goto exit;
 		if (frc == 0){
 			rc = 0;
 			goto exit;
-		}
+		}
+		++(trp->len);
 		trp->rem_len += (c & 127) * trp->multiplier;
 		trp->multiplier *= 128;
 	} while ((c & 128) != 0);

PS: This bug hunting has been done as part of a project ending nov 30th, which will also provide new samples and a serial transport to Paho MQTT. See you later guys.

pub0sub1_nb.c does not receive published message

Moved from issue eclipse/paho.mqtt.c#21 - wrong repo.

migrated from Bugzilla #476397
status UNCONFIRMED severity critical in component MQTT-C for 1.2
Reported in version unspecified on platform PC
Assigned to: Ian Craggs

On 2015-09-02 03:31:11 -0400, philippe smadja wrote:

pub0sub1.c and pub0sub1_nb.c do not work (receive message)
qos0pub.c published properly (I gor the message with java client.
Environement: windows 7.
NOTE. I updated transport.c for Windows: call to WSAStartup() to initialize socket library
Any idea.?
Thanks
Philippe

Remove Buffer Size from C++ Client Template

Update: Sorry I initially sent the issue without a body, here it is:

I'm working on the arduino-mqtt library.

The Arduino build system currently has no way of configuring a library through compiler macros. In that sense we cannot offer a way to easily select different buffer sizes. The only way is to use multiple internal pointers to different clients with different buffer size and let the user select from them:
256dpi/arduino-mqtt#30

Is there a reason why you choose to configure the buffer via the template?

target 'MQTTPacket/src/../test/test1' doesn't match the target pattern

I use cross compiler "arm-linux-gnueabihf-gcc" to make the makefile, but it warns as fellows:

Makefile:101: target 'MQTTPacket/src/../test/test1' doesn't match the target pattern
Makefile:105: target 'MQTTPacket/src/../samples/pub0sub1' doesn't match the target pattern
Makefile:105: target 'MQTTPacket/src/../samples/qos0pub' doesn't match the target pattern

/home/tcwg-buildslave/workspace/tcwg-make-release/label/tcwg-x86_64-ex40/target/arm-linux-gnueabihf/snapshots/glibc.git~release-2.21-master/csu/../sysdeps/arm/start.S:119: undefined reference to `main'

So, do I need to alter the Makefile?

MQTT embedded client with QoS 2 subscribe does not respond to PUBREL messages from server.

migrated from Bugzilla #458512
status RESOLVED severity major in component MQTT-Embedded-C for 1.2
Reported in version 1.0 on platform Other
Assigned to: Ian Craggs

Original attachment names and IDs:

On 2015-01-27 07:41:57 -0500, Roger Fowler wrote:

Created attachment 250259
Mosquitto message log

The HELLO.INO program eventually hangs when the Mosquitto MAX_INFLIGHT_MSGS limit is reached. Running Mosquitto in verbose mode (output attached) shows that the client has subscribed to a topic with QoS=2 but is not responding to the PUBREL messages i.e. it never issues a PUBCOMP in response. Eventually this hits the max_inflight_msgs limit which causes the hang. The log shows the first PUBREL is sent by the broker at 1422353538 with message id 2 but no corresponding PUBCOMP is ever returned by the client.

The necessary code to respond to an incoming PUBREL appears to be missing from:
MQTTClient -> MQTTClient.h (around line 568) and
MQTTClientC -> MQTTClient.c (around line 270)

Hope I'm not standing on anyone's toes here, and apologies if I've reported this incorrectly - I'm a newbie to Bugzilla, Eclipse and Git !

Regards
Roger Fowler

On 2015-01-27 07:54:18 -0500, Roger Fowler wrote:

Created attachment 250261
Mosquitto message log

Annotated with <<< to identify the PUBREL messages from the server that were not responded to

On 2015-01-28 05:12:00 -0500, Ian Craggs wrote:

Hi Roger,

thanks for the report -- you've done exactly the right thing by raising this bug! I was going to invite you to raise any bugs you found when I saw your comments on Twitter, but I didn't actually do so yet.

I think I've fixed this on the mbed version. I'll look into it.

On 2015-01-28 05:41:06 -0500, Ian Craggs wrote:

Roger, I've pushed a fix. Should work now. Let me know. Thanks!

On 2015-01-28 06:04:59 -0500, Ian Craggs wrote:

Actually, where are you getting the code from? I've updated the git repo, but not any other packages yet.

On 2015-01-28 06:35:12 -0500, Roger Fowler wrote:

Hi Ian
I got the original code from https://www.eclipse.org/downloads/download.php?file=/paho/arduino.zip which is the Arduino download link on https://www.eclipse.org/paho/clients/c/embedded/
(I noticed that it contained a couple of other bugs which have already been fixed so I'm guessing that the zip file is back-level.(

The repository link on that page, https://www.eclipse.org/paho/clients/c/embedded/ doesn't appear to work (for me) but I've managed to do a git clone from https://git.eclipse.org/r/paho/org.eclipse.paho.mqtt.embedded-c
This is how I've picked up your updated MQTTClient.h

First test shows that the client is now responding with PUBCOMPs to the incoming PUBREL packets nicely. However, the HELLO.INO has just hung with just the occasional PINGREQ being issued by the client. I need to investigate and will send you an update soon.

Cheers
Roger

On 2015-01-28 09:24:39 -0500, Roger Fowler wrote:

Created attachment 250301
Mosquitto log 28-1-2015

Mosquitto log after the MQTTClient.h patch has been installed

On 2015-01-28 09:38:50 -0500, Roger Fowler wrote:

With the MQTTClient patch included, the message flow from the Mosquito log appears as you would expect (attached as MOSQUITO.OUT). However, the HELLO.INO program still hangs after a while.

I've narrowed this down to client.publish() calls by the client for QoS=2 payloads (QoQ 0 and 1 are working fine). On the eleventh iteration of loop(), the code hangs in the yield() call immediately after the call to client.publish(). The publish call by the client goes through the full PUBLISH/PUBREC/PUBREL/PUBCOMP exchange (client msg id 12). Next, the broker sends the message back to client (as the client is subscribed to the same topic), again at QoS=2. This too goes through the full PUBLISH/PUBREC/PUBREL/PUBCOMP exchange (broker msg id 11). But the messageArrived() function on the client doesn't get driven this time.

My original thought that we were hitting max_inflight_msgs in the broker may have been a red herring. I've increased this limit to 38 but the code still hangs in yield() on the eleventh iteration of loop. After the hang, the only activity on the Mosquito log is the occasional PINGREQ/PINGRESP exchange.

On 2015-01-28 09:40:36 -0500, Roger Fowler wrote:

BTW, the log shows the activity after the QoS=0 and QoS=1 calls have been excluded from the run

On 2015-01-28 09:47:18 -0500, Roger Fowler wrote:

Actually, the hang is not within yield() itself. I've just confirmed it is stuck in the loop which repeatedly calls yield(), because 'arrivedcount' is never being updated by messageArrived().

On 2015-01-29 12:23:58 -0500, Ian Craggs wrote:

Are you using an ethernet shield?

Does messageArrived get called for the last QoS 2 message?

If you comment out the section that sends and receives QoS 2 messages, leaving QoS 0 or 1 messages being sent and received only, does it go on for longer?

I've been doing some debugging and sometimes things are getting a bit unstable making things tricky. I've used some code I found to display the free memory (http://playground.arduino.cc/Code/AvailableMemory) which was very low (177 bytes). I've reduced the memory use in my test code, but we have to be very careful not to overflow memory in the basic Arduino. If you don't want to send/receive QoS 1 messages, that code can be conditionally compiled out, for example.

On 2015-01-29 13:10:46 -0500, Benjamin Cabé wrote:

(In reply to Ian Craggs from comment # 10)

I've reduced the memory use in my test code, but we
have to be very careful not to overflow memory in the basic Arduino.

I think that is a very good point!
How about getting rid of all the sprintf's in the example code? AFAICT they can all be replaced by Serial.print/Serial.println calls and this would allow to get rid of the printbuffer that would become essentially useless, plus this would also make the binary code a few KBs smaller by not having to link to sprintf (but having to use Serial.print(int) would mitigate this �small� saving: removing sprintf save 1.5K, Serial.print(int) costs 500B...)

Also there are many "almost-duplicated" string that could probably be simplified/factored

On 2015-01-29 18:08:56 -0500, Ian Craggs wrote:

Benjamin,

I wasn't being that careful with the example. I'll remove the sprintfs as you suggest.

Quite a lot of code can also be removed if we don't have a message handler per subscription. I can make that conditionally compiled too.

I can save a few more bytes by optimizing the data types too. Int return types should be one byte for instance.

There are also error checks in the low-level code. These could be conditionally compiled for environments like this where every byte counts.

On 2015-01-30 05:42:12 -0500, Roger Fowler wrote:

(In reply to Ian Craggs from comment # 10)
Hi Ian - thanks for this.

Are you using an ethernet shield?
Yes

Does messageArrived get called for the last QoS 2 message?
No. Last QoS 2 msg sent by client gets full PUBLISH/PUBREC/PUBREL/PUBCOMP exchange. Then the broker issues a QoS 2 msg back to client (as it subscribed to this topic). This also goes through the PUBLISH/PUBREC/PUBREL/PUBCOMP exchange. But messageArrived() doesn't get called on the client after the final PUBCOMP is received.

If you comment out the section that sends and receives QoS 2 messages,
leaving QoS 0 or 1 messages being sent and received only, does it go on for
longer?
There doesn't appear to be any problem with QoS 1 or 2 msgs - the code runs freely as long as QoS 2 is avoided. If QoS 2 msgs are sent then the code hangs on the eleventh iteration of loop(). This is regardless of whether just QoS 2 msgs are being sent or all three types.

I've been doing some debugging and sometimes things are getting a bit
unstable making things tricky. I've used some code I found to display the
free memory (http://playground.arduino.cc/Code/AvailableMemory) which was
very low (177 bytes). I've reduced the memory use in my test code, but we
have to be very careful not to overflow memory in the basic Arduino. If you
don't want to send/receive QoS 1 messages, that code can be conditionally
compiled out, for example.
I'm using an Arduino Mega 2560 so have a little more SRAM to play with. Using the code at that link, the available memory is showing as 5856 bytes.

Cheers, Roger

On 2015-01-30 09:17:10 -0500, Ian Craggs wrote:

After removing the sprintfs, I realized that they contributed to sketch size more than use of RAM. Nevertheless I've reduced my use of RAM enough to make the program run reliably, and I found the problem. QoS 2 message ids weren't being freed up when the PUBREL arrived.

As I write, my own Arduino Uno is up to packet id 1320 :-)

I've pushed a fix to the master branch.

On 2015-01-30 09:21:03 -0500, Roger Fowler wrote:

Ian
That's great news, thanks. I'll download and test when I get home this evening.
Have a good weekend
Roger.

On 2015-01-31 04:37:20 -0500, Roger Fowler wrote:

Looks like it is fixed - no more hangs :-)
Cheers

Compilation errors (introduced when Linux build created)

migrated from Bugzilla #444075
status RESOLVED severity normal in component MQTT-Embedded-C for 1.1
Reported in version 1.0 on platform PC
Assigned to: Ian Craggs

On 2014-09-15 06:02:34 -0400, Ian Craggs wrote:

Hi,

I�m trying to use the Embedded MQTT C/C++ Client, following exactly Benjamin�s Cabé�s webcast, with the TI CC3200. In contrast to him I get a lot of errors/warnings (see build log below). Has the Embedded MQTT C/C++ Client been changed since the Benjamin�s webcast? The oob project (that I�m using with the MQTT client) without the MQTT client library builds without problems.



Thanks.

Guy

**** Build of configuration Release for project oob ****

c:\ti\ccsv6\utils\bin\gmake -k all

'Building file: C:/Users/guy/git/org.eclipse.paho.mqtt.embedded-c/MQTTPacket/src/MQTTConnectClient.c'

'Invoking: ARM Compiler'

c:/ti/ccsv6/tools/compiler/arm_5.1.8/bin/armcl -mv7M4 --code_state=16 --float_support=vfplib --abi=eabi -me --include_path="c:/ti/ccsv6/tools/compiler/arm_5.1.8/include" --include_path="C:/Users/guy/git/org.eclipse.paho.mqtt.embedded-c/MQTTPacket/src" --include_path="C:/TI/CC3200SDK/cc3200-sdk/example/out_of_box/" --include_path="C:/TI/CC3200SDK/cc3200-sdk/example/common" --include_path="C:/TI/CC3200SDK/cc3200-sdk/inc" --include_path="C:/TI/CC3200SDK/cc3200-sdk/simplelink/" --include_path="C:/TI/CC3200SDK/cc3200-sdk/simplelink/Include/" --include_path="C:/TI/CC3200SDK/cc3200-sdk/simplelink/Source/" --include_path="C:/TI/CC3200SDK/cc3200-sdk/driverlib/" --include_path="C:/TI/CC3200SDK/cc3200-sdk/oslib/" --include_path="C:/TI/CC3200SDK/cc3200-sdk/third_party/FreeRTOS/" --include_path="C:/TI/CC3200SDK/cc3200-sdk/third_party/FreeRTOS/source/" --include_path="C:/TI/CC3200SDK/cc3200-sdk/third_party/FreeRTOS/source/include" --include_path="C:/TI/CC3200SDK/cc3200-sdk/third_party/FreeRTOS/source/portable/CCS/ARM_CM3" -g --define=ccs --define=SL_PLATFORM_MULTI_THREADED --define=USE_FREERTOS --define=cc3200 --display_error_number --diag_warning=225 --diag_wrap=off --preproc_with_compile --preproc_dependency="MQTTConnectClient.pp" "C:/Users/guy/git/org.eclipse.paho.mqtt.embedded-c/MQTTPacket/src/MQTTConnectClient.c"

C:\Users\guy\git\org.eclipse.paho.mqtt.embedded-c\MQTTPacket\src\MQTTPacket.h, line 37: warning # 230-D: trailing comma is nonstandard

C:\Users\guy\git\org.eclipse.paho.mqtt.embedded-c\MQTTPacket\src\MQTTConnect.h, line 126: error # 80: expected a type specifier

C:\Users\guy\git\org.eclipse.paho.mqtt.embedded-c\MQTTPacket\src\MQTTConnect.h, line 126: error # 142-D: unnamed prototyped parameters not allowed when body is present

C:\Users\guy\git\org.eclipse.paho.mqtt.embedded-c\MQTTPacket\src\MQTTConnect.h, line 126: error # 131: expected a "{"

c:/ti/ccsv6/tools/compiler/arm_5.1.8/include/stdarg.h, line 49: warning # 12-D: parsing restarts here after previous syntax error

c:/ti/ccsv6/tools/compiler/arm_5.1.8/include/stdarg.h, line 50: warning # 179-D: variable "__ap" was declared but never referenced

c:/ti/ccsv6/tools/compiler/arm_5.1.8/include/stdarg.h, line 51: error # 78-D: this declaration has no storage class or type specifier

c:/ti/ccsv6/tools/compiler/arm_5.1.8/include/stdio.h, line 255: error # 760: variable "va_list" is not a type name

c:/ti/ccsv6/tools/compiler/arm_5.1.8/include/stdio.h, line 257: error # 760: variable "va_list" is not a type name

c:/ti/ccsv6/tools/compiler/arm_5.1.8/include/stdio.h, line 259: error # 760: variable "va_list" is not a type name

c:/ti/ccsv6/tools/compiler/arm_5.1.8/include/stdio.h, line 261: error # 760: variable "va_list" is not a type name

c:/ti/ccsv6/tools/compiler/arm_5.1.8/include/stdio.h, line 264: error # 760: variable "va_list" is not a type name

c:/ti/ccsv6/tools/compiler/arm_5.1.8/include/stdio.h, line 267: error # 760: variable "va_list" is not a type name

c:/ti/ccsv6/tools/compiler/arm_5.1.8/include/stdio.h, line 269: error # 760: variable "va_list" is not a type name

C:\Users\guy\git\org.eclipse.paho.mqtt.embedded-c\MQTTPacket\src\MQTTPacket.h, line 112: error # 80: expected a type specifier

C:\Users\guy\git\org.eclipse.paho.mqtt.embedded-c\MQTTPacket\src\MQTTPacket.h, line 112: error # 249: function "attribute" has already been defined

C:\Users\guy\git\org.eclipse.paho.mqtt.embedded-c\MQTTPacket\src\MQTTPacket.h, line 112: error # 142-D: unnamed prototyped parameters not allowed when body is present

C:\Users\guy\git\org.eclipse.paho.mqtt.embedded-c\MQTTPacket\src\MQTTPacket.h, line 112: error # 131: expected a "{"

C:/Users/guy/git/org.eclipse.paho.mqtt.embedded-c/MQTTPacket/src/MQTTConnectClient.c, line 28: warning # 12-D: parsing restarts here after previous syntax error

C:/Users/guy/git/org.eclipse.paho.mqtt.embedded-c/MQTTPacket/src/MQTTConnectClient.c, line 33: error # 20: identifier "options" is undefined

C:/Users/guy/git/org.eclipse.paho.mqtt.embedded-c/MQTTPacket/src/MQTTConnectClient.c, line 67: warning # 225-D: function "MQTTSerialize_connectLength" declared implicitly

16 errors detected in the compilation of "C:/Users/guy/git/org.eclipse.paho.mqtt.embedded-c/MQTTPacket/src/MQTTConnectClient.c".

On 2014-09-15 06:04:16 -0400, Ian Craggs wrote:

This is due to the introduction of DLLExport and DLLImport definitions on the functions, to help with the creation of a shared library on Linux (and Windows).

These need to be omitted when we aren't building a shared library.

On 2014-09-15 06:22:31 -0400, Ian Craggs wrote:

A fix added to the master branch.

Remove the DLLExport and DLLImport definitions if we aren't building a shared library.

Add makefile to Embedded C client

migrated from Bugzilla #442039
status RESOLVED severity normal in component MQTT-Embedded-C for ---
Reported in version v0.5 on platform PC
Assigned to: Rong Xiang

On 2014-08-19 06:16:14 -0400, Ian Craggs wrote:

The makefile should build MQTTPacket as a library on Linux. See the Paho C client makefile for an example.

This should also enable MQTTPacket to be built from within the Eclipse IDE.

On 2014-08-28 11:00:07 -0400, Ian Craggs wrote:

Assigning to Rong.

On 2015-02-20 06:14:48 -0500, Ian Craggs wrote:

Basic make completed.

Sequence of session present flag in MQTTConnackFlags

Hi all,

I have a question about the struct of MQTTConnackFlags.
According to MQTT3.1.1 specification, bit 0 of Connect Acknowledge Flags is the Session Present Flag. Does the implementation follow the specification?

typedef union
{
unsigned char all; /< all connack flags */
#if defined(REVERSED)
struct
{
unsigned int sessionpresent : 1; /
< session present flag */
unsigned int : 7; /< unused */
} bits;
#else
struct
{
unsigned int : 7; /
< unused */
unsigned int sessionpresent : 1; /< session present flag */
} bits;
#endif
} MQTTConnackFlags; /
< connack flags byte */

Regards,
TC

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.