Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

net: added emCute - introducing MQTT-SN support #6633

Merged
merged 2 commits into from
Feb 28, 2017

Conversation

haukepetersen
Copy link
Contributor

@haukepetersen haukepetersen commented Feb 20, 2017

Finally found some time last weekend to look into MQTT-SN... I am happy to introduce emCute, my 'from-scratch' approach to implementing MQTT-SN. I tried to make it very user-friendly and leight-weight -> on the iotlab-m3 it takes currently ~2.1k of ROM and 1245b RAM (of which are 1180b buffers + sock).

The implementation supports most major features defined for MQTT-SN except gateway discovery and QoS > 0. The doxygen in sys/include/net/emcute.h should give a pretty good overview on supported, missing, and planned features.

Currently, there are two major things left, that have to be fixed until this PR can be merged (all other things can be handled in follow up PRs):

  • the message re-send is broken. This is most probably caused by a bug in thread_flags -> see core: thread_flags seem to be broken on native #6624
  • sending of periodic ping request is currently commented out. I am not sure if I did something wrong here (its late...), or if sock_udp_recv() has a bug when setting the timeout value...

@haukepetersen haukepetersen added Impact: major The PR changes a significant part of the code base. It should be reviewed carefully Area: network Area: Networking Type: new feature The issue requests / The PR implemements a new feature for RIOT labels Feb 20, 2017
@haukepetersen haukepetersen added this to the Release 2017.04 milestone Feb 20, 2017
@aabadie
Copy link
Contributor

aabadie commented Feb 21, 2017

That looks awesome. I would be happy to give a try.

// uint8_t buf[2] = { 2, PINGREQ };
// sock_udp_send(&sock, &buf, 2, &gateway);
// }
// }
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

please remove or use c-style comments

@miri64 miri64 added the State: WIP State: The PR is still work-in-progress and its code is not in its final presentable form yet label Feb 27, 2017
@haukepetersen haukepetersen removed the State: WIP State: The PR is still work-in-progress and its code is not in its final presentable form yet label Feb 27, 2017
@haukepetersen
Copy link
Contributor Author

Periodic sending of ping messages and handling of topics with QoS_1 are now also working.

This PR is now ready for review (and hopefully for merge). All open todos will/should be addressed in follow up PRs... Happy testing :-)

static volatile uint16_t waitonid = 0;
static volatile int result;

static inline uint16_t get_u16(const uint8_t *buf)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why not use byteorder.h?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

no reason -> fixed.

#endif
}

static inline void set_u16(uint8_t *buf, uint16_t val)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why not use byteorder.h?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

fixed

./RIOTDIR/dist/tools/tapsetup/tapsetup
```

2. Assign a site-global prefix to the `tabbr0` interface:
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The bridge is named differently under OSX and FreeBSD.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

How should I know :-) Will fix

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There was just a PR about this: #6647 ;-)

3. Assign a site-global address with the same prefix to the RIOT `native`
instance:
```
ifconfig 5 add fec0:affe:99
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Colon missing

*/

/**
* @defgroup net_emcute emCute (MQTT-SN)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Would prefer the name "MQTT-SN client (emCute)" so it jumps into the eyes of newbies ;-).

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

fixed

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Where?

* - handling re-transmits
*
* The following features are however still missing (but planned):
* @todo Geteway discovery (so far there is no support for handling
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Gateway

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

fixed

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Don't see it :-/

const char *emcute_type_str(uint8_t type)
{
switch (type) {
case ADVERTISE: return "ADVERTISE";
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think a lookup-table is way more efficient here.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

actually, gcc should convert this to a lookup table, as the type IDs are up-counting without gaps... Also its just for debugging, so efficiency is not uttermost important...

*/
enum {
ADVERTISE = 0x00, /**< advertise message */
SEARCHGW = 0x01, /**< search gateway message */
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why enum if you enumerate manually anyways?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Didn't we have discussions some time ago, that this is the preferred way to define flags like this? Apart from that, I think this looks much nicer than having a bunch of defines...

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nope it was the other way around, that flags shouldn't be defined as enums, but defines. But these are no flags, but field values.

* @brief MQTT-SN return codes
*/
enum {
ACCEPT = 0x00, /**< all good */
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Dito

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

see above

#else
return (uint16_t)((buf[1] << 8) | buf[0]);
#endif
network_uint16_t ns = { .u16 = *((uint16_t *)buf) };
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nope, like this it leads to alignment problems.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

hmm, I knew there was something off... I was looking for something that is as efficient as my manual solution I had here before. Any tips?

@haukepetersen
Copy link
Contributor Author

@miri64: @kaspar030 had a point, the code using byteorder.h was prone to alignment faults. Switched back to my original code -> I will change this only if somebody can show me a at least as efficient solution...

@haukepetersen
Copy link
Contributor Author

rebased

@@ -32,6 +32,10 @@ ifneq (,$(filter oneway_malloc,$(USEMODULE)))
USEMODULE_INCLUDES += $(RIOTBASE)/sys/oneway-malloc/include
endif

ifneq (,$(filter emcute,$(USEMODULE)))
USEMODULE_INCLUDES += $(RIOTBASE)/sys/net/application_layer/emcute/include
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

git mv sys/net/application_layer/emcute/include/emcute_internal.h sys/net/application_layer/emcute/

then this isn't necessary.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

fixed

Copy link
Member

@miri64 miri64 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Tested on native and samr21-xpro. ACK. Please squash.

@miri64 miri64 added the CI: needs squashing Commits in this PR need to be squashed; If set, CI systems will mark this PR as unmergable label Feb 28, 2017
@miri64 miri64 dismissed kaspar030’s stale review February 28, 2017 15:55

Was addressed and dismissal sanctioned by @kaspar030

@haukepetersen
Copy link
Contributor Author

rebased and squashed

@haukepetersen haukepetersen added the CI: ready for build If set, CI server will compile all applications for all available boards for the labeled PR label Feb 28, 2017
@haukepetersen haukepetersen removed the CI: needs squashing Commits in this PR need to be squashed; If set, CI systems will mark this PR as unmergable label Feb 28, 2017
@miri64 miri64 added CI: ready for build If set, CI server will compile all applications for all available boards for the labeled PR and removed CI: ready for build If set, CI server will compile all applications for all available boards for the labeled PR labels Feb 28, 2017
@haukepetersen
Copy link
Contributor Author

all green: go go go

@haukepetersen haukepetersen merged commit 9b7489b into RIOT-OS:master Feb 28, 2017
@haukepetersen haukepetersen deleted the add_mqttsn branch February 28, 2017 17:55
mutex_lock(&txlock);

int pos = set_len(tbuf, (len + 1));
len += (pos + 1);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@haukepetersen
This len += (pos + 1); looks suspicious. Coverity Scan tells us that there is a potential buffer overflow.

If you ask me, I would say that this statement should not there. And if it is intended then the if condition above needs to be changed.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

len comes from a local user call. This could just be solved by an appropriate assert().

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe I wasn't clear. My point is that this statement should not be there at all.

len is the length of the data. It does not make sense to increase it by 4. The three bytes for the length field are already copied into tbuf through set_len. Then WILLMSGUPD is copied into the buffer. What is left to do with memcpy is to copy the data with length len. Notice the &tbuf[pos] being the destination of memcpy.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@haukepetersen any comment to this?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

See issue #15028 to discuss this further

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Area: network Area: Networking CI: ready for build If set, CI server will compile all applications for all available boards for the labeled PR Impact: major The PR changes a significant part of the code base. It should be reviewed carefully Type: new feature The issue requests / The PR implemements a new feature for RIOT
Projects
None yet
Development

Successfully merging this pull request may close these issues.

6 participants