Example project to publish messages to a MQTT-SN broker using the u-blox SARA-N200 NB-IoT modem

Dependencies:   MQTTSNPacket X-NUCLEO-SARA-N200

Revision:
1:70b751b7a189
Parent:
0:c0cf12ee5420
Child:
4:df0aab6b9120
--- a/main.cpp	Mon Aug 20 12:59:35 2018 +0000
+++ b/main.cpp	Mon Aug 20 16:42:45 2018 +0200
@@ -1,12 +1,181 @@
-#include "mbed.h"
+#include <stdio.h>
+#include <Serial.h>
 
-DigitalOut led1(LED1);
+#include "mbed.h"
+#include "sara_n2.h"
+#include "MQTTmbed.h"
+#include "MQTTSNUDP.h"
+#include "MQTTSNClient.h"
+#include "mbed_config.h"
+
+Serial pc(SERIAL_TX, SERIAL_RX, 115200);
+DigitalOut myled(LED1);
+InterruptIn button(USER_BUTTON);
+UARTSerial sara(PA_9, PA_10, 9600);
+DigitalOut sara_reset(D7);
 
-// main() runs in its own thread in the OS
-int main() {
-    while (true) {
-        led1 = !led1;
-        wait(0.5);
+//#define INFO_TRACE(_class, _string, ...)    printf( "%8s: " _string, _class, ##__VA_ARGS__)
+#undef TRACE
+#define TRACE(_string, ...)    INFO_TRACE( "MQTT", _string,  ##__VA_ARGS__ )
+
+float led_flash_rate = 0.5;
+
+void messageArrived(MQTTSN::MessageData& md)
+{
+    MQTTSN::Message &message = md.message;
+    TRACE("Message arrived: qos %d, retained %d, dup %d, packetid %d\n",
+    		message.qos,
+			message.retained,
+			message.dup,
+			message.id);
+
+    TRACE("Payload %s\n", message.payload);
+    char *ptr;
+    float new_rate = strtof((const char*)message.payload, &ptr);
+    if(new_rate > 0)
+    {
+    	TRACE("New rate %f\n", new_rate);
+    	led_flash_rate = new_rate;
     }
 }
 
+enum eMQTTstates
+{
+	MQTT_SOCKET_DISCONNECTED,
+	MQTT_SOCKET_CONNECTED,
+	MQTT_CLIENT_CONNECTED,
+	MQTT_CLIENT_PUBLISH,
+	MQTT_CLIENT_SUBSCRIBED
+}mMQTTstate;
+
+
+SARA_N2 sara_mdm(&sara, &sara_reset);
+MQTTSNUDP ipsocket = MQTTSNUDP(&sara_mdm);
+MQTTSNPacket_connectData data = MQTTSNPacket_connectData_initializer;
+MQTTSN_topicid topicid;
+MQTTSN::QoS grantedQoS;
+char topicString[64];
+char publishMessage[100];
+
+bool buttonPressed = false;
+
+void mqtt_fsm(MQTTSN::Client<MQTTSNUDP, Countdown> *client)
+{
+	static int pub_count = 0;
+	switch(mMQTTstate)
+	{
+	case MQTT_SOCKET_DISCONNECTED:
+	{
+		const char* hostname = MBED_CONF_APP_MQTT_SN_HOST;
+		int port = MBED_CONF_APP_MQTT_SN_PORT;
+		TRACE("Connecting to %s:%d\n", hostname, port);
+		int socket  = ipsocket.connect((char*)hostname, port);
+		if(socket >= 0)
+		{
+			TRACE("Socket connected - %d\n", socket);
+			mMQTTstate = MQTT_SOCKET_CONNECTED;
+		}
+	}
+	break;
+
+	case MQTT_SOCKET_CONNECTED:
+	{
+		data.clientID.cstring = (char*)"NUCLEO_NB-IoT";
+		data.duration = 100;
+		int rc = client->connect(data);
+		TRACE("Connect - %d\n", rc);
+		if(rc == MQTTSN::SUCCESS)
+		{
+			printf("Client Connected\n");
+			mMQTTstate = MQTT_CLIENT_CONNECTED;
+		}
+	}
+	break;
+	case MQTT_CLIENT_CONNECTED:
+	{
+		topicid.type = MQTTSN_TOPIC_TYPE_NORMAL;
+		topicid.data.long_.name = topicString;
+		topicid.data.long_.len = strlen(topicString);
+		int rc = client->subscribe(topicid, MQTTSN::QOS1, grantedQoS, messageArrived);
+		TRACE("Subscribe - %d\n", rc);
+		if(rc == MQTTSN::SUCCESS)
+		{
+			printf("Client Subscribed\n");
+			mMQTTstate = MQTT_CLIENT_PUBLISH;
+		}
+	}
+	break;
+	case MQTT_CLIENT_PUBLISH:
+		{
+			pub_count = 0;
+
+			MQTTSN::Message message;
+			message.qos = MQTTSN::QOS0;
+			message.retained = false;
+			message.dup = false;
+			message.payload = (void*)publishMessage;
+			message.payloadlen = strlen(publishMessage)+1;
+			int rc = client->publish(topicid, message);
+			if(rc == MQTTSN::SUCCESS)
+			{
+				TRACE("Publishes %s\n", publishMessage);
+			}
+
+			mMQTTstate = MQTT_CLIENT_SUBSCRIBED;
+		}
+		break;
+	case MQTT_CLIENT_SUBSCRIBED:
+	{
+		client->yield(100);
+
+		if(buttonPressed)
+		{
+			buttonPressed = false;
+			mMQTTstate = MQTT_CLIENT_PUBLISH;
+			sprintf(publishMessage, "Button pressed");
+		}
+
+		if(pub_count++ > 50)
+		{
+			mMQTTstate = MQTT_CLIENT_PUBLISH;
+
+			static int aliveCount = 0;
+			sprintf(publishMessage, "I am alive %d", aliveCount++);
+		}
+
+	}
+	break;
+	}
+}
+
+void pressedEvent()
+{
+	buttonPressed = true;
+}
+
+int main(void)
+{
+	printf("\n\nNUCLEO_X_SARA-N200 HelloMQTT-SN\n");
+	printf("Version: 0x%08X\n", MBED_CONF_APP_VERSION);
+	printf("mbed-os: %d.%d.%d\n", MBED_MAJOR_VERSION, MBED_MINOR_VERSION, MBED_PATCH_VERSION);
+
+	strcpy(topicString, MBED_CONF_APP_TOPIC);
+	sprintf(publishMessage, "NUCLEO NB-IoT online");
+	MQTTSN::Client<MQTTSNUDP, Countdown> client = MQTTSN::Client<MQTTSNUDP, Countdown>(ipsocket);
+
+	button.fall(&pressedEvent);
+
+	while(1)
+	{
+		wait(led_flash_rate);
+		myled = 1;
+		wait(led_flash_rate);
+		myled = 0;
+
+		sara_mdm.fsm();
+		mqtt_fsm(&client);
+	}
+
+
+	return 0;
+}