AZ3166 board cannot connect to Mosquitto running on Synology NAS

Hi all,

I am a newbie to Arduino and just trying out the pre-formatted examples first :slight_smile:
I have the AZ3166 (MX chip) Board AKA the Azure IoT Starter Kit, which comes with a MQTT example.
Besides, I have installed Mosquitto on my Synology NAS (also hosting Domoticz), which is running fine: Domoticz is posting and Mosquitto is handling all the messages.

When I simply install the MQTT example on the AZ3166, it works fine (this sends out a loop of messages to mqtt.eclipse.org. Here is the example Sketch:

#include <AZ3166WiFi.h>
#include "MQTTClient.h"
#include "MQTTNetwork.h"
#include "Telemetry.h"

int status = WL_IDLE_STATUS;
int arrivedcount = 0;
bool hasWifi = false;

const char* mqttServer = "mqtt.eclipse.org";
int port = 1883;

void initWifi()
{
  Screen.print("IoT DevKit\r\n \r\nConnecting...\r\n");

  if (WiFi.begin() == WL_CONNECTED)
  {
    IPAddress ip = WiFi.localIP();
    Screen.print(1, ip.get_address());
    hasWifi = true;
    Screen.print(2, "Running... \r\n");
  }
  else
  {
    Screen.print(1, "No Wi-Fi\r\n ");
  }
}

void messageArrived(MQTT::MessageData& md)
{
    MQTT::Message &message = md.message;

    char msgInfo[60];
    sprintf(msgInfo, "Message arrived: qos %d, retained %d, dup %d, packetid %d", message.qos, message.retained, message.dup, message.id);
    Serial.println(msgInfo);

    sprintf(msgInfo, "Payload: %s", (char*)message.payload);
    Serial.println(msgInfo);
    ++arrivedcount;
}

int runMqttExample() {
  char* topic = "mqtt-sample";
  MQTTNetwork mqttNetwork;
  MQTT::Client<MQTTNetwork, Countdown> client = MQTT::Client<MQTTNetwork, Countdown>(mqttNetwork);
  arrivedcount = 0;
  
  char msgBuf[100];
  sprintf(msgBuf, "Connecting to MQTT server %s:%d", mqttServer, port);
  Serial.println(msgBuf);

  int rc = mqttNetwork.connect(mqttServer, port);
  if (rc != 0) {
    Serial.println("Connected to MQTT server failed");
  } else {
    Serial.println("Connected to MQTT server successfully");
  }

  MQTTPacket_connectData data = MQTTPacket_connectData_initializer;
  data.MQTTVersion = 3;
  data.clientID.cstring = "mqtt-sample";
  data.username.cstring = "testuser";
  data.password.cstring = "testpassword";
  
  if ((rc = client.connect(data)) != 0) {
      Serial.println("MQTT client connect to server failed");
  }
  
  if ((rc = client.subscribe(topic, MQTT::QOS2, messageArrived)) != 0) {
      Serial.println("MQTT client subscribe from server failed");
  }
  
  MQTT::Message message;

  // QoS 0
  char buf[100];
  sprintf(buf, "QoS 0 message from AZ3166!");
  message.qos = MQTT::QOS0;
  message.retained = false;
  message.dup = false;
  message.payload = (void*)buf;
  message.payloadlen = strlen(buf)+1;
  rc = client.publish(topic, message);
  while (arrivedcount < 1) {
      client.yield(100);
  }
 
  // QoS 1
  sprintf(buf, "QoS 1 message from AZ3166!");
  message.qos = MQTT::QOS1;
  message.payloadlen = strlen(buf)+1;
  rc = client.publish(topic, message);
  
  while (arrivedcount < 2) {
      client.yield(100);
  }
  
  if ((rc = client.unsubscribe(topic)) != 0) {
      Serial.println("MQTT client unsubscribe from server failed");
  }
  
  if ((rc = client.disconnect()) != 0) {
      Serial.println("MQTT client disconnect from server failed");
  }
  
  mqttNetwork.disconnect();
  Serial.print("Finish message count: ");
  Serial.println(arrivedcount);
      
  return 0;
}

void setup() {
  //Initialize serial and Wi-Fi:
  Serial.begin(115200);
  initWifi();
  if(hasWifi)
  {
    // Microsoft collects data to operate effectively and provide you the best experiences with our products. 
    // We collect data about the features you use, how often you use them, and how you use them.
    send_telemetry_data_async("", "MQTTClientSetup", "");
  }
}

void loop() {
  Serial.println("\r\n>>>Enter Loop");

  if (hasWifi) {
    runMqttExample();
  }

  delay(5000);
}

Now, when I only replace the address of the MQTT server with the Mosquitto one, I cannot connect to Mosquitto (Wifi connection is OK however, AZ3166 has an IP address assigned, which I can reach with ping from my computer):

const char* mqttServer = "192.168.178.250" //Mosquitto on NAS;

However, I am able to reach Mosquitto from my computer (using MQTT Explorer and MQTT.fx - both connect and are able to post test messages to Mosquitto). Besides, I added a line of code to the Sketch to show the return code (rc). This showed "-3004" which is a rather strange code - not a default Mosquitto response.

So it seems that:

  1. The Sketch code is OK (AZ3166 is able to post messages)
  2. Mosquitto is OK (can be reached from external client)
    But for some reason, my AZ3166 is not able to reach Mosquitto.

What am I doing wrong and what could I do to test/check things? (I tried Wireshark, but then realised that this only shows traffic to/from my computer and will not show the AZ3166 traffic to Mosquitto?).

Any help is appreciated!

First: Edit your post and insert code tags!

I'm missing a link to the MQTT library you used. It might be possible that it doesn't allow an IP address string to be provided instead of a hostname but that's pure speculation without having enough details.

Did you configure your Mosquitto server? Did you create user accounts?

Hi Pylon,

Thank you for your help - even though I am a bit late to respond :slight_smile:
Meanwhile, I found out that the MQTT server is OK, the MQTT client on the Arduino as well.
The real problem is in the networking: my Arduino sets up a Wifi connection, but is not able to reach my NAS on my internal network. The strange thing is however, that the Arduin gets an IP assigned (in the same network range as my NAS) - I can also ping the Arduino from my router, but the Arduino does not seem to be able to pass the router: I cannot ping it from my NAS and I cannot setup a WebClient on Arduino that is able to reach my NAS web server or any other internal web server that is "behind" my router.
When I try the MQTT client of the Webclient on my Arduino and I connect to a server on the internet (e.g. test.domoticz.org), it is working fine.
So in short: I do not understand why the Arduino cannot connect inside my LAN but can connect to internet servers?

So in short: I do not understand why the Arduino cannot connect inside my LAN but can connect to internet servers?

I guess that's your router. The functionality is often called "device isolation". It allows all devices to connect to the WAN port of the router but every device is isolated as if it were on a completely separate network.

Hi Pylon,

Thanks for your reply - that seems a plausible explanation. However, I checked at the Ziggo forum and I could not find any issue logged about this on my particular modem. I checked the modem/router setting, but unfornately, there is no setting for AP Client isolation whatsoever.
Besides, when I set up a Web Server on the Arduino, I am able to access it from my iphone (wifi) and also from my mac desktop (ethernet). So it seems that the Arduino can at least be reached by other (wifi) clients within my internal network.
Would you know any other tests I could run or is there maybe a sketch that is testing and logging network activity on the Arduino? Thanks again!

How do you access your NAS? By IP address or by name? If by name, do you run your own DNS server with your own domain? Because otherwise you're using a technology that the Arduino doesn't support by default and which isn't worth to be implemented there for your case.

I use an IP address to connect to my NAS, so no dns server.
I also did some additional tests: I have a WiFi extender which has a admin web page (wireless device). Setting up the arduino webclient, I was able to connect to this wireless WiFi extender too. I can also connect to my iPad and iPhone in the same way, so this seems to be a particular issue around my NAS. On the other hand, I can also access my NAS from iPad and iPhone and fron my NAS I could also ping my WiFi extender, but not the arduino :frowning:
Any clues left?

Any clues left?

Not without much more information about your network.

IPs are fixed or by DHCP? What IPs are in use? Check the MAC addresses, do you have any clashes? Do you have a standard netmask or some custom value?

Hello Pylon,

I did some additonal tests. My original goal was to connect Arduino as MQTT client to my NAS running Mosquitto (MQTT broker) in Docker. Since that was failing, I tried some tests with WebClients to check basic connection (this conversation). However, today I installed the same Docker image to my Mac desktop (wired). When I run the MQTT client on the Arduino, it now succeeds to connect with my Mac desktop. So: the Arduino sketch is OK, so that confirms once more that it is just a matter of network connectivity.
Besides, I also connected an additional router in bridge mode to my network. By doing so, I created a second Wifi access point. I connected the Arduino (MQTT client) to this Wifi access point and managed to get the same MQTT connection to my broker running on my Mac desktop. Then, I tried to connect to the MQTT broker on my NAS using this new wifi access point: this did not work, like it did not using my primary wifi access point on my modem/router. So that would confirm that there is an issue in reaching/accessing the NAS somehow. I cannot get my head around this: what is blocking the MQTT request of the Arduino?

For some additional info: I did a sniff on my Arduin-iMac connection for one test run with the Mosquitto broker. Please find attached the conversation details between the two :slight_smile:
Some new ideas?

More interesting would be the traffic you see on the network between the Arduino and the NAS (even though they cannot connect).

Fully agree Pylon! However, there is not much to see :frowning:
I tried running tcpdump on my NAS at the moment the Arduino joined the network. I was only able to see a couple of "who has" requests from the Arduino, asking for my NAS. Next, there was a similar message from the Arduino, asking for the default gateway (my modem/router) and after that, there was no traffic anymore. So, I concluded that the Arduino gets "stuck" at the gateway (my modem/router) and does not reach my NAS at all?
Then again, I still do not understand why running a MQTT broker on my dekstop and calling from the Arduino works OK? This would be:
Arduino --> wifi --> modem/router (wifi AP) --> desktop (wired)
While a similar route for my NAS would be:
Arduino-->wifi --> modem/router (wifi AP) --> NAS (wired)

I tried running tcpdump on my NAS at the moment the Arduino joined the network. I was only able to see a couple of "who has" requests from the Arduino, asking for my NAS. Next, there was a similar message from the Arduino, asking for the default gateway (my modem/router) and after that, there was no traffic anymore. So, I concluded that the Arduino gets "stuck" at the gateway (my modem/router) and does not reach my NAS at all?

There was no response to the ARP requests from your NAS? That gives you the reason for your problems, your NAS doesn't let the Arduino know that it has it's IP address. That's probably not a network issue but a local problem on the NAS. Either a misconfigured firewall or a wrong network setup.

Hi Pylon, thanks again for your reply!
I repeated the tcpdump on my NAS. Please find the results in the attachment.
My NAS seems to respond to the "who has" call of the Arduino, but somehow, the Arduino keeps asking this.
Then, in the end it makes the following call:
21:14:04.056357 ARP, Request who-has 192.168.178.1 tell 192.168.178.200, length 46
After this, the traffic is silent (I think Arduino is redirected to my router and is stuck there).

Here are the actors in this dramatic play:
192.168.178.1 = default gateway (my modem/router)
192.168.178.144 = NAS (wired)
192.168.178.200 = Arduino (Wifi)
Subnet maks = 255.255.255.0

In the attached screenshot, you will see the output of the Arduino serial monitor as well as the output of my NAS' tcpdump...

Do you have any clue about what is going on here?

Some additional info:
I also checked the routing rules and order (see screenshot)

The entry for my Arduino in the ARP table of my NAS:
(192.168.178.200) at c8:93:46:88:3a:64 [ether] on eth0

Schermafbeelding 2020-12-17 om 21.35.22.png
Schermafbeelding 2020-12-17 om 21.35.22.png

And here are the contents of the above mentioned routing tables:

Schermafbeelding 2020-12-17 om 21.42.51.png

Schermafbeelding 2020-12-17 om 21.35.22.png

Schermafbeelding 2020-12-17 om 21.42.51.png

The eth0-table is rather strange, if the source IP is 192.168.178.144 the traffic is routed over 192.168.178.144 (itself). I'm rather surprised that works at all. I guess that there are some iptables rules that does something else to make sense out of this. Can you post the output of

iptables -L -n

Meanwhile, I also tried to setup a bond on my NAS (using two network LAN ports), so eth0 changed into bond0, but the rest of the settings remained unchanged however. Unfortunately, this also did not help.
Here is the output of the iptable -L -n:

root@NAS:~# iptables -L -n
Chain INPUT (policy ACCEPT)
target     prot opt source               destination         

Chain FORWARD (policy ACCEPT)
target     prot opt source               destination         
DEFAULT_FORWARD  all  --  0.0.0.0/0            0.0.0.0/0           

Chain OUTPUT (policy ACCEPT)
target     prot opt source               destination         

Chain DEFAULT_FORWARD (1 references)
target     prot opt source               destination         
DOCKER-USER  all  --  0.0.0.0/0            0.0.0.0/0           
DOCKER-ISOLATION-STAGE-1  all  --  0.0.0.0/0            0.0.0.0/0           
ACCEPT     all  --  0.0.0.0/0            0.0.0.0/0            ctstate RELATED,ESTABLISHED
DOCKER     all  --  0.0.0.0/0            0.0.0.0/0           
ACCEPT     all  --  0.0.0.0/0            0.0.0.0/0           
ACCEPT     all  --  0.0.0.0/0            0.0.0.0/0           

Chain DOCKER (1 references)
target     prot opt source               destination         

Chain DOCKER-ISOLATION-STAGE-1 (1 references)
target     prot opt source               destination         
DOCKER-ISOLATION-STAGE-2  all  --  0.0.0.0/0            0.0.0.0/0           
RETURN     all  --  0.0.0.0/0            0.0.0.0/0           

Chain DOCKER-ISOLATION-STAGE-2 (1 references)
target     prot opt source               destination         
DROP       all  --  0.0.0.0/0            0.0.0.0/0           
RETURN     all  --  0.0.0.0/0            0.0.0.0/0           

Chain DOCKER-USER (1 references)
target     prot opt source               destination         
RETURN     all  --  0.0.0.0/0            0.0.0.0/0

To be honest, I don't understand the setup completely. It may be caused by the fact that they use docker to put important applications into containers.
I haven't found anything that would explain that ARP request from the Arduino were not responded, unfortunately.

This topic was automatically closed 120 days after the last reply. New replies are no longer allowed.