socketsmqttiotesp8266

Socket error on client <>, disconnecting with Paho MQTT-SN Gateway and ESP8266 CLient


I'm trying to test MQTT-SN.

I'm using Mosquitto Broker, Paho MQTT-SN Gateway and this library (https://github.com/S3ler/arduino-mqtt-sn-client) for the clients.

I'm using an esp8266 as a client.

With this client, I can connect, subscribe, receive from subscribed topics but I cant publish into topics

memset(buffer, 0x0, buffer_length);
mqttSnClient.publish(buffer, publishTopicName , qos);

Every time I try to publish with this client, Mosquitto gives me

Socket error on client <clientid>, disconnecting

And my client disconnects from the Broker.

Any clues?

EDIT1

Client Code

#include <ESP8266WiFi.h>
#include <WiFiUdp.h>
#include "WiFiUdpSocket.h"
#include "MqttSnClient.h"
#include <NTPClient.h>

const char* ssid     = "example";
const char* password = "example1";

long utcOffsetInSeconds = -10800;

// Define NTP Client to get time
WiFiUDP ntpUDP;
NTPClient timeClient(ntpUDP, "pool.ntp.org", utcOffsetInSeconds);

#define buffer_length 10
char buffer[buffer_length + 1];
uint16_t buffer_pos = 0;

IPAddress gatewayIPAddress(192, 168, 0, 106);
uint16_t localUdpPort = 10000;


WiFiUDP udp;
WiFiUdpSocket wiFiUdpSocket(udp, localUdpPort);
MqttSnClient<WiFiUdpSocket> mqttSnClient(wiFiUdpSocket);

const char* clientId = "hamilton12";
char* subscribeTopicName = "ESP8266/123";
char* publishTopicName = "ESP8266/123";

int8_t qos = 1;

void mqttsn_callback(char *topic, uint8_t *payload, uint16_t length, bool retain) {
  timeClient.update();
  Serial.print("Received - Topic: ");
  Serial.print(topic);
  Serial.print(" Payload: ");
  for (uint16_t i = 0; i < length; i++) {
    char c =  (char) * (payload + i);
    Serial.print(c);
  }
  Serial.print(" Lenght: ");
  Serial.print(length);

  Serial.print(" Received Timestamp milliseconds: ");
  Serial.print(timeClient.getHours());
  Serial.print(":");
  Serial.print(timeClient.getMinutes());
  Serial.print(":");
  Serial.println(timeClient.getSeconds());
}

void setup() {

  Serial.begin(115200);
  delay(10);
  Serial.println();
  Serial.print("Connecting to ");
  Serial.println(ssid);

  /* Explicitly set the ESP8266 to be a WiFi-client, otherwise, it by default,
     would try to act as both a client and an access-point and could cause
     network-issues with your other WiFi-devices on your WiFi-network. */
  WiFi.mode(WIFI_STA);
  WiFi.begin(ssid, password);

  while (WiFi.status() != WL_CONNECTED) {
    delay(500);
    Serial.print(".");
  }

  Serial.println("");
  Serial.println("WiFi connected");
  Serial.println("IP address: ");
  Serial.println(WiFi.localIP());

  Serial.print("Starting MqttSnClient - ");
  mqttSnClient.setCallback(mqttsn_callback);
  if  (!mqttSnClient.begin()) {
    Serial.print("Could not initialize MQTT-SN Client ");
    while (true) {
      Serial.println(".");
      delay(1000);
    }
  }
  Serial.println(" ready!");
}

void convertIPAddressAndPortToDeviceAddress(IPAddress& source, uint16_t port, device_address& target) {
  // IPAdress 0 - 3 bytes
  target.bytes[0] = source[0];
  target.bytes[1] = source[1];
  target.bytes[2] = source[2];
  target.bytes[3] = source[3];
  // Port 4 - 5 bytes
  target.bytes[4] = port >> 8;
  target.bytes[5] = (uint8_t) port ;
}


void loop() {
  if (!mqttSnClient.is_mqttsn_connected()) {
#if defined(gatewayHostAddress)
    IPAddress gatewayIPAddress;
    if (!WiFi.hostByName(gatewayHostAddress, gatewayIPAddress, 20000)) {
      Serial.println("Could not lookup MQTT-SN Gateway.");
      return;
    }
#endif
    device_address gateway_device_address;
    convertIPAddressAndPortToDeviceAddress(gatewayIPAddress, localUdpPort, gateway_device_address);
    Serial.print("MQTT-SN Gateway device_address: ");
    printDeviceAddress(&gateway_device_address);


    if (!mqttSnClient.connect(&gateway_device_address, clientId, 180) ) {
      Serial.println("Could not connect MQTT-SN Client.");
      delay(1000);
      return;
    }
    Serial.println("MQTT-SN Client connected.");
    //mqttSnClient.set_mqttsn_connected();
    if (!mqttSnClient.subscribe(subscribeTopicName, qos)){
      Serial.println("Cant subscribe");
    }
    Serial.println("Subscribed");
  }

  //It never enters this IF
  if (Serial.available() > 0) {
    buffer[buffer_pos++] = Serial.read();
    if (buffer[buffer_pos - 1] == '\n') {
      // only qos -1, 0, 1 are supported
      if (!mqttSnClient.publish(buffer, publishTopicName , qos)) {
        Serial.println("Could not publish");
      }
      Serial.println("Published");
      memset(buffer, 0x0, buffer_length);
      buffer_pos = 0;
    }
  }

  //Uncommenting this line will give socket error
  //mqttSnClient.publish(buffer, publishTopicName , qos);


  mqttSnClient.loop();

}

etc/mosquitto/mosquitto.conf

pid_file /var/run/mosquitto.pid

persistence true
persistence_location /var/lib/mosquitto/

log_dest file /var/log/mosquitto/mosquitto.log

#include_dir /etc/mosquitto/conf.d

connection_messages true
log_timestamp true
log_dest stderr
log_type error
log_type warning
log_type debug

allow_anonymous true

gateway.conf

BrokerName=192.168.0.106
BrokerPortNo=1883
BrokerSecurePortNo=8883

#
# When AggregatingGateway=YES or ClientAuthentication=YES,
# All clients must be specified by the ClientList File  
#

ClientAuthentication=NO
AggregatingGateway=NO
QoS-1=NO
Forwarder=NO

#ClientsList=/path/to/your_clients.conf

PredefinedTopic=NO
#PredefinedTopicList=/path/to/your_predefinedTopic.conf

#RootCAfile=/etc/ssl/certs/ca-certificates.crt
#RootCApath=/etc/ssl/certs/
#CertsFile=/path/to/certKey.pem
#PrivateKey=/path/to/privateKey.pem

GatewayID=1
GatewayName=PahoGateway-01
KeepAlive=900
#LoginID=your_ID
#Password=your_Password


# UDP
GatewayPortNo=10000
MulticastIP=225.1.1.1
MulticastPortNo=1884

# UDP6
GatewayUDP6Bind=FFFF:FFFE::1 
GatewayUDP6Port=10000
GatewayUDP6Broadcast=FF02::1
GatewayUDP6If=wpan0

# XBee
Baudrate=38400
SerialDevice=/dev/ttyUSB0
ApiMode=2

# LOG
ShearedMemory=NO;

EDIT2

Terminal running mosquitto

hamilton@hamilton-note:~$ mosquitto
1574806892: mosquitto version 1.4.15 (build date Tue, 18 Jun 2019 11:42:22 -0300) starting
1574806892: Using default config.
1574806892: Opening ipv4 listen socket on port 1883.
1574806892: Opening ipv6 listen socket on port 1883.
1574806900: New connection from 192.168.0.106 on port 1883.
1574806900: New client connected from 192.168.0.106 as hamilton123 (c1, k46080).
1574806900: Socket error on client hamilton123, disconnecting.
^C1574806911: mosquitto version 1.4.15 terminating

Terminal running Paho Gateway

hamilton@hamilton-note:~/Downloads$ ./MQTT-SNGateway 

 ***************************************************************************
 * MQTT-SN Transparent Gateway
 * Part of Project Paho in Eclipse
 * (http://git.eclipse.org/c/paho/org.eclipse.paho.mqtt-sn.embedded-c.git/)
 *
 * Author : Tomoaki YAMAGUCHI
 * Version: 1.3.1
 ***************************************************************************

20191126 192134.372 PahoGateway-01 has been started.

 ConfigFile: ./gateway.conf
 PreDefFile: ./predefinedTopic.conf
 SensorN/W:  UDP Multicast 225.1.1.1:1884 Gateway Port 10000
 Broker:     192.168.0.106 : 1883, 8883
 RootCApath: (null)
 RootCAfile: (null)
 CertKey:    (null)
 PrivateKey: (null)



20191126 192140.660   CONNECT           <---  hamilton123                         12 04 04 01 B4 00 68 61 6D 69 6C 74 6F 6E 31 32 33 00
20191126 192140.660   CONNECT           ===>  hamilton123                         10 17 00 04 4D 51 54 54 04 02 B4 00 00 0B 68 61 6D 69 6C 74 6F 6E 31 32 33
20191126 192140.874   CONNACK           <===  hamilton123                         20 02 00 00
20191126 192140.874   CONNACK           --->  hamilton123                         03 05 00

20191126 192140.879   SUBSCRIBE   0200  <---  hamilton123                         11 12 20 02 00 45 53 50 38 32 36 36 2F 31 32 33 00
20191126 192140.879   SUBSCRIBE   0200  ===>  hamilton123                         82 10 02 00 00 0B 45 53 50 38 32 36 36 2F 31 32 33 01
20191126 192140.879   SUBACK      0200  <===  hamilton123                         90 03 02 00 01
20191126 192140.879   SUBACK      0200  --->  hamilton123                         08 13 20 00 01 02 00 00

20191126 192140.883   PUBLISH     0300  <---  hamilton123                         08 0C 22 00 01 03 00 00
20191126 192140.884   PUBLISH     0300  ===>  hamilton123                         32 07 00 02 00 01 03 00 00
^C20191126 192149.215 BrokerSendTask   stopped.
20191126 192149.215 PacketHandleTask stopped.
20191126 192149.215 ClientSendTask   stopped.
20191126 192149.386 BrokerRecvTask   stopped.
20191126 192150.158 ClientRecvTask   stopped.

20191126 192150.215 MQTT-SN Gateway  stoped

Solution

  • Thank you for the help Dalton Cézane.

    But I found the problem in an open issue in the client's library:

    Having trouble with your example WiFiUdpMqttSnClient program in that it does not successfully publish the test messages. I'm using paho-mqtt-sn gateway.

    I'm bashing around in the dark a bit but I think this is because it publishes the messages with the flag TopicIdType set to 2. I think it should be zero (normal) because it's not pre-registered nor is it a short topic.

    In file MqttSnClient.h line 216 the call to send_publish has short_topic set to true. But that's not all; in file mqttsn_messages.h around line 215 if short_topic flag is false it sets the flag to predefined. I've removed the latter 'else' clause so the flag is set to zero and I can now publish successfully.

    I suspect my hack is not a complete solution but I hope it helps you resolve this issue.

    This comment was made by @nottledim, big thanks!

    Now i can publish without a problem using my esp8266.

    Just leaving here if anyone has this problem.

    link to the issue: https://github.com/S3ler/arduino-mqtt-sn-client/issues/3