paho.mqtt.embedded-c
paho.mqtt.embedded-c copied to clipboard
Network Connection Troubles
Hi all,
I am using a Nucleo-144 board and enabled the FreeRTOS. Afterwards i've integrated FreeRTOS+TCP sources and headers and Paho MQTT application.
I created a thread to run a MQTT Echo Server but i am having troubles connecting. This is my code:
static void prvMQTTEchoTask(void *pvParameters)
{
printf("prvMQTTEchoTask\n\r");
/* connect to m2m.eclipse.org, subscribe to a topic, send and receive messages regularly every 1 sec */
MQTTClient client;
Network network;
unsigned char sendbuf[80], readbuf[80];
int rc = 0,
count = 0;
MQTTPacket_connectData connectData = MQTTPacket_connectData_initializer;
pvParameters = 0;
NetworkInit(&network);
printf("Network Initialized\n\r");
MQTTClientInit(&client, &network, 30000, sendbuf, sizeof(sendbuf), readbuf, sizeof(readbuf));
printf("MQTT Client Initialized\n\r");
//char* address = "iot.eclipse.org";
char* address = "0.0.0.0";
if ((rc = NetworkConnect(&network, address, 1883)) != 0)
printf("Return code from network connect is %d\n\r", rc);
#if defined(MQTT_TASK)
printf("MQTTStartTask\n\r");
if ((rc = MQTTStartTask(&client)) != pdPASS)
printf("Return code from start tasks is %d\n\r", rc);
#endif
connectData.MQTTVersion = 3;
connectData.clientID.cstring = "FreeRTOS_sample";
printf("Connection Attempt...\n\r");
if ((rc = MQTTConnect(&client, &connectData)) != 0)
printf("Return code from MQTT connect is %d\n\r", rc);
else
printf("MQTT Connected\n");
if ((rc = MQTTSubscribe(&client, "FreeRTOS/sample/#", 2, messageArrived)) != 0)
printf("Return code from MQTT subscribe is %d\n\r", rc);
while (++count)
{
MQTTMessage message;
char payload[30];
message.qos = 1;
message.retained = 0;
message.payload = payload;
sprintf(payload, "message number %d", count);
message.payloadlen = strlen(payload);
if ((rc = MQTTPublish(&client, "FreeRTOS/sample/a", &message)) != 0)
printf("Return code from MQTT publish is %d\n\r", rc);
#if !defined(MQTT_TASK)
if ((rc = MQTTYield(&client, 1000)) != 0)
printf("Return code from yield is %d\n\r", rc);
#endif
HAL_Delay(5000);
}
/* do not return */
}
I've tried passing an ip address or a name like "localhost" but it keeps giving me an error code at this point:
if ((rc = NetworkConnect(&network, address, 1883)) != 0)
printf("Return code from network connect is %d\n\r", rc);
Any suggestion? Thank you.
In short, you need 3 valuable tools: 1- Google and/or the API docs: check the returned code for its meaning, then, if you don't understand it, you can ask a specific question 2- a description of your networking scenario 3- Wireshark [https://www.wireshark.org/] and some means for it to see your board traffic Long explanation: When you are working with electrical stuff, you at least need a voltmeter. If you dive into electronics, you will quite likely need an oscilloscope. And if you do a parachute jump into networking, you will surely need Wireshark. Those you need to "see" what is going on. Developing embedded networking usually also requires a good old hub (not a switch, a hub) or a monitoring switch, a switch with monitor capability, so you can plug your board to it and watch its traffic on a different port (where you connect a suitable host running Wireshark). Some people (myself, for instance) use a computer as the Internet router and since all such traffic will route through it, then Wireshark can run there and there's no need for the hub/monitoring switch. Which brings me to the following doubt: did you happen to properly configure your network (IP) and gateway addresses (and mask) ? Are you running DHCP (which seems to be the default) ? Do you have a DHCP server, then ? What is your scenario (your network setup) ? Where do you want to connect to ? Do you know you need a name or an address for your MQTT server ? ("your" = the one you've chosen to use for this test, be it 'mqtt.eclipse.org' or whatever). You have to pass an address or a name (but probably the function only works with one of them... did you check the API for that function ?). "localhost" means "this board", do you have an MQTT server installed in your board ?
Thank you for your reply. As you said, I think my problem is the configuration of my network. I just found an Init API but it has to be adapted to my project. I'll let you know soon.
This is my main including IPInit:
int main(void) {
/* MCU Configuration--------------------------------------------------------*/
/* Reset of all peripherals, Initializes the Flash interface and the Systick. */ HAL_Init();
/* USER CODE BEGIN Init */
/* USER CODE END Init */
/* Configure the system clock */ SystemClock_Config();
/* USER CODE BEGIN SysInit */
/* USER CODE END SysInit */
/* Initialize all configured peripherals / MX_GPIO_Init(); MX_ETH_Init(); MX_USART3_UART_Init(); MX_USB_OTG_FS_PCD_Init(); / Initialise the RTOS’s TCP/IP stack. The tasks that use the network are created in the vApplicationIPNetworkEventHook() hook function below. The hook function is called when the network connects. */ FreeRTOS_IPInit( ucIPAddress, ucNetMask, ucGatewayAddress, ucDNSServerAddress, ucMACAddress );
uint32_t ulIPAddress, ulNetMask, ulGatewayAddress, ulDNSServerAddress; int8_t cBuffer[ 16 ]; /* Create the thread(s) / / definition and creation of defaultTask / //osThreadDef(defaultTask, StartDefaultTask, osPriorityNormal, 0, 128); //defaultTaskHandle = osThreadCreate(osThread(defaultTask), NULL); vStartMQTTTasks(ipconfigIP_TASK_STACK_SIZE_WORDS, 0); / USER CODE BEGIN RTOS_THREADS / / add threads, ... / / USER CODE END RTOS_THREADS / / The network is up and configured. Print out the configuration obtained from the DHCP server. */ FreeRTOS_GetAddressConfiguration( &ulIPAddress, &ulNetMask, &ulGatewayAddress, &ulDNSServerAddress );
/* Convert the address to a string then print it out. */ FreeRTOS_inet_ntoa( ulIPAddress, cBuffer ); printf("IP Address: %s\r\n", cBuffer); FreeRTOS_inet_ntoa( ulNetMask, cBuffer ); printf( "Subnet Mask: %s\r\n", cBuffer ); FreeRTOS_inet_ntoa( ulGatewayAddress, cBuffer ); printf( "Gateway Address: %s\r\n", cBuffer ); FreeRTOS_inet_ntoa( ulDNSServerAddress, cBuffer ); printf( "DNS Server Address: %s\r\n", cBuffer );
/* Start scheduler / //osKernelStart(); vTaskStartScheduler(); / We should never get here as control is now taken by the scheduler */
/* Infinite loop / / USER CODE BEGIN WHILE */ while (1) {
} /* USER CODE END 3 */ }
Those printfs give me the following prints: IP Address: 0.0.0.0 Subnet Mask: 255.255.255.0 Gateway Address: 10.9.23.1 DNS Server Address: 10.9.3.43
/* Define the network addressing. These parameters will be used if either ipconfigUDE_DHCP is 0 or if ipconfigUSE_DHCP is 1 but DHCP auto configuration failed. */ static const uint8_t ucIPAddress[ 4 ] = { 10, 9, 23, 44 }; static const uint8_t ucNetMask[ 4 ] = { 255, 255, 255, 0 }; static const uint8_t ucGatewayAddress[ 4 ] = { 10, 9, 23, 1 };
/* The following is the address of an OpenDNS server. */ static const uint8_t ucDNSServerAddress[ 4 ] = { 10, 9, 3, 43 };
Seems like i can't obtain the IP Address that i required. But the real issue is that i can't connect at all.
I beg to differ. The real issue is that you don't have proper networking. Not being able to connect is just a consequence of that. I suggest you ask for networking configuration of your board with your OS on your board/OS providers forums. And, I also suggest you do check your hardware is actually doing what you think you tell it to do by sniffing with Wireshark.
Ok i'll do that. I'm just not sure how it has to be done because i can install Wireshark on my laptop but the board is connected to the laptop by USB. Can i sniff the traffic of the board from my laptop anyway? Thank you.
Your board needs to be connected to your network, that would most likely be a) Ethernet (an RJ-45 connector) or b) WiFi (an antenna) if (a) then read my first msg again and go to your vendor hardware forums if you need help with your board and to your networking equipment or ISP provider if you need help with that. Usually a simple patchcord will do the trick. if (b) then your laptop wifi needs to have capturing capability. Otherwise you need to capture either on a suitable card/USB dongle or a suitable wireless router, e,g. running OpenWRT/LEDE or similar. That is also off-topic here but you have lots of buzz words to google that out.
Hi, i sniffed the traffic with Wireshark. I've saved the data in the file attached here. I started recording the packets since the moment i powered the mcu board up. Can you see any particular issue? Sniff_00.zip
I'm a lazy man. I'd rather like you to look at your capture, and ask what you don't understand, providing a complete and detailed description of your scenario. What I seem to see does not look consistent with a properly connected board and sniffer on a live network. If I was to take a wild guess, it looks as if you'd just plugged your board to your notebook running Wireshark. Since this is way off-topic (not at all a Paho problem), I will stop here. I suggest you check your board is properly connected to your router. If that does not solve your problem, then make sure your sniffer can see all traffic (you'll need to read my 1st msg again) and ask for help on a networking forum. Good luck.