botletics / SIM7000-LTE-Shield

Botletics SIM7000 LTE CAT-M1/NB-IoT Shield for Arduino
https://www.botletics.com/products/sim7000-shield
GNU General Public License v3.0
477 stars 215 forks source link

Confused by which MQTT functions to use for FONA 3G SIM5320 #177

Closed OscarVanL closed 4 years ago

OscarVanL commented 4 years ago

Hi,

I'm a little confused on what I should use for MQTT on my FONA 3G SIM5320.

I see you've got an MQTT example here, however this uses the Adafruit MQTT library which does not support the FONA 3G from what I can tell.

Then I see you've also extended the Adafruit FONA library to add MQTT functionality into this library for SIM7000 with an example here.

It seems I'm stuck in a position where I can't use the official Adafruit library as it doesn't support FONA 3G, but in your second example it uses functions specific to Adafruit_FONA_LTE like openWirelessConnection and wirelessConnStatus which aren't supported on FONA 3G.

// Open wireless connection if not already activated
if (!fona.wirelessConnStatus()) {
  while (!fona.openWirelessConnection(true)) {
    Serial.println(F("Failed to enable connection, retrying..."));
    delay(2000); // Retry every 2s
  }
  Serial.println(F("Enabled data!"));
}
else {
  Serial.println(F("Data already enabled!"));
}

How would you suggest I get MQTT to work on the SIM5320?

Additionally, thank you for all the work and documentation you've done on this. I've been pulling my hair out over the official Adafruit FONA libraries which really suck, your improvements and documentation has helped a lot.

botletics commented 4 years ago

This library currently does not support MQTT for the SIM5320.

OscarVanL commented 4 years ago

That's a shame. I guess I'm going to need to Frankenstein some of your code then. Thanks anyway :)

OscarVanL commented 4 years ago

Hi botletics, I have a question about your Adafruit_FONA::mqtt_connect_message function.

I suspect the protocol name length (mqtt_message[3] in mqtt_connect_message) is being set incorrectly as well as the length calculated in mqtt_sendPacket in Adafruit_FONA::MQTTconnect when using "MQTT" instead of "MQIsdp" as the protocol name. This is always being assumed to be 6 long, even if using 'MQTT' as the protocol which is 4 long.

Here's the packet sent by my FONA using AT+CIPSEND:


14:04:33.741 ->     ---> AT+CIPSEND=0,48
14:04:34.283 ->     <--- >
14:04:34.283 ->     ---> 16 44 0 6 77 81 84 84 3 194 0 15 0 15 56 54 55 48 53 55 48 51 49 54 57 53 56 54 49 0 5 111 115 99 97 114 0 8 99 101 110 115 111 114 101 100 48 69 26
14:04:34.451 ->     <--- OK

which becomes Hex

10 2C 00 06 4D 51 54 54 03 C2 00 0F 00 0F 38 36 37 30 35 37 30 33 31 36 39 35 38 36 31 00 05 6F 73 63 61 72 00 08 63 65 6E 73 6F 72 65 64 30 45 1A

And now with hex digits replaced by characters where relevant

10 2C 00 06 M Q T T 3 C2 00 0F 00 0F 38 36 37 30 35 37 30 33 31 36 39 35 38 36 31 00 05 o s c a r 00 08 c e n s o r e d 30 45 1A

00 06 = Protocol name length (6). This should be 00 04 according to heading 3.1.2.1 in the MQTT 3 Protocol specification.

30 45 = Random garbage appended due to incorrect length calculation in mqtt_sendPacket.

1A = <^Z> (end of packet character added by mqtt_sendPacket)

The resolution is to set mqtt_message[3] using protocol_length, and to use 14+strlen(protocol)+strlen(clientID)+strlen(username)+strlen(password) instead of 20+strlen(clientID)+strlen(username)+strlen(password)

If you agree with this change I can make a PR :)

botletics commented 4 years ago

Sorry it took so long to reply but thanks for the catch! You're right, I think mqtt_message[3] = 6; just needs to be changed to mqtt_message[3] = protocol_length;

I don't see the 20+strlen(clientID)+... line that you mentioned though.

OscarVanL commented 4 years ago

Apologies for not being clearer. The 20+strlen(clientID)+... line is in Adafruit_FONA::MQTTconnect in Adafruit_FONA.cpp.

Line 2387 saying

if (! mqtt_sendPacket(mqtt_message, 20+strlen(clientID)+strlen(username)+strlen(password))) return false;

should be changed to

if (! mqtt_sendPacket(mqtt_message, 14+strlen(protocol)+strlen(clientID)+strlen(username)+strlen(password))) return false;

botletics commented 4 years ago

Ahh yes you're right, thanks. Fixed it.