Hi,
I struggled with giving this an appropriate subject. ![]()
I am using the MQTTSN library for arduino for which the developer is AWOL. I have forked his/her lib and dug into the code to determine why this messaging protocol is not working.
To explain my problem I think I need to explain the MQTTSN protocol structure quickly:
There are many message types but the one I will use as exampleis the CONNECT msg that looks like this:
[length][Msg Type][flags][protocolId][duration][clientId] and the length of each msg part in bytes being
[ 1 ][ 1 ][ 1 ][ 1 ][ 2 ][ n ]
My CONNECT data sent on the wire should be (hex)
[ 0d ][ 04 ][ 24 ][ 01 ][ 2121 ][ 6d6f74653232 ]
However it is:
[ 0d ][ 04 ] 00 [ 24 ][ 01 ][ 2121 ][ 6d6f74653232 ]
and the decoding end [server ] for this msg cant recognise it cause things are not where they should be.
So the lib constructs the message this way:
defines a struct for the HEADER - first 2 parts of the message:
struct message_header {
  uint8_t length;
  message_type type;
};
then the CONNECT struct inherits from the HEADER struct [I think] adding four other msg parts:
struct msg_connect : public message_header {
  uint8_t flags;
  uint8_t protocol_id;
  uint16_t duration;
  char client_id[0];
};
The connect method is:
void MQTTSN::connect(const uint8_t flags, const uint16_t duration, const char* client_id) {
  msg_connect* msg = reinterpret_cast<msg_connect*>(message_buffer);
  msg->length = sizeof(msg_connect) + strlen(client_id);
  msg->type = CONNECT;
  msg->flags = flags;
  msg->protocol_id = PROTOCOL_ID;
  msg->duration = bswap(duration);
  strcpy(msg->client_id, client_id);
  send_message();
  waiting_for_response = true;
}
and send_message() is:
void MQTTSN::send_message() {
  message_header* hdr = reinterpret_cast<message_header*>(message_buffer);
#ifdef USE_RF12
  while (!rf12_canSend()) {
    rf12_recvDone();
    Sleepy::loseSomeTime(32);
  }
  rf12_sendStart(_gateway_id, message_buffer, hdr->length);
  rf12_sendWait(2);
#endif
#ifdef USE_SERIAL
  //Serial.print("mqttsn-messages:send_message: message_buffer=");
  //printByteA(message_buffer);
  Serial.write(message_buffer, hdr->length);
  Serial.flush();
#endif
  if (!waiting_for_response) {
    _response_timer = millis();
    _response_retries = N_RETRY;
    // Cheesy hack to ensure two messages don't run-on into one send.
//Â Â Â Â delay(10);
  }
}
In this case we are using SERIAL and not RF12.
The sketch is:
#include <mqttsn.h>
MQTTSNHandlers mqttsn;
int slow;
Â
uint8_t flagz;
uint16_t kat;
char* clientid;
//LED
int ledPin;
void setup() {
 // put your setup code here, to run once:
 Serial.begin(115200);
 ledPin = 13;   // default arduino uno LED
 pinMode(ledPin, OUTPUT);
Â
 slow=1000;
 flagz = FLAG_QOS_0; //0x00
 kat = 4369; //think this is 5 sec
 clientid= "mote22";
 mqttsn.connect(flagz, kat, clientid);
 delay(50);
 mqttsn.searchgw(0xff);
 delay(50);
}
So to me all looks good in the lib but I am beginner in arduino.
I cant understand why there is that extra 00 that get placed on the wire between the msgType and flag parts of the message [or if the 00 is on fact a part of either of those]
This happends for other message types as well that have the flags message part in them.
I tried googling for solution and changed the type of the flags from uint8_t to byte but this did not help.
I also tried to compile with the -fpacked-struct but with no success.
I am out of options and pulling my hair out :~ =( and though I would ask the experts here in this forum.
Code attached.
mqttsn02.ino (1.19 KB)
mqttsn.zip (10.4 KB)