Setup MQTT connection
Answer
7/25/17 8:27 AM

Good afternoon community,

I’m new into the world of the Bosch XDK and would be very glad for some help :) !
I tried some of the preprogrammed examples on the Bosch XDK (e.g. to stream sensor data via the usb interface) which were working smoothly.
Afterwards I tried to build my own project in which I try to send sensor data (e.g. temperature or acceleration) from a publisher via a MQTT protocol to a broker. Later on it should be possible to access the data from an external laptop (acting as a subscriber).
In my case the broker is set up on a raspberry pi microcontroller. For this purpose, I was following the steps within the ‘XDK MQTT Guide’ . The aim of the guide is to send a simple script ('Hello') to the broker. I would like to use this later on as a basis to establish my own project. After following the guide I tried to flash the program to the XDK. Unfortunately, I’m receiving an error message.

I tried already several approaches to arrange the scripts in the correct way but they all led to an error message so far.... I added the data structure (inculding the error message) for two of my approaches as images to the attachments of this mail.

Unfortunately, I cannot post my Word document including snapshots for each of my steps in the forum...

So, I would like to ask if somebody, who already sucessfully implemented the MQTT guide, could show me the data structure of his/her resulting project. Maybe it is possible to exchange the projects via mail ? So, i could compare a functioning project with my own approach to find possible mistakes.

The pdf version of the MQTT guide I used can be accessed via:

https://webcache.googleusercontent.com/search?q=cache:Bx3Vv0wAlXYJ:https://xdk.bosch-connectivity.com/documents/37728/87798/XDK_Guide_MQTT.pdf/d8573a86-ca7a-411b-9675-8f7b5e9393a8+&cd=2&hl=de&ct=clnk&gl=de

I would be very glad for any help

 

Thank you very much in advance

 

Best regards

 

Nils

 

 

0 (0 Votes)
RE: Setup MQTT connection
Answer
7/25/17 2:00 PM as a reply to Nils Hilser.

Hello Nils,

I think you simply have the wrong directory structure in the first imaged you showed.
The structure should be like this:

source
│---main.c
│---XdkApplicationTemplate.c
│---XdkApplicationTemplate.h
|--- ...
|
\---paho
    │---MQTTClient.c
    │---MQTTClient.h
    │---All the other files from paho
    │
    \---XDK
        |---mqttXDK.c
        \---mqttXDK.h

In comparison, yours is like this:

source
│---main.c
│---XdkApplicationTemplate.c
│---XdkApplicationTemplate.h
|--- ...
|
\---paho
    │---MQTTClient.c
    │---MQTTClient.h
    │---All the other files from paho
    │
    \---paho
        |
        \---XDK
            |---mqttXDK.c
            \---mqttXDK.h

Now, if you take a look at the proposed makefile adjustments in the guide, the first exported variable is

export BCDS_XDK_INCLUDES =
  -I$(BCDS_APP_SOURCE_DIR)/paho/XDK \
  -I$(BCDS_APP_SOURCE_DIR)/paho \
  -I$(BCDS_APP_SOURCE_DIR)

This tells the compiler where to look for header-files within your implementation, and as you can see, /paho/paho/XDK is not part of it, which is why the compiler can't find your mqttXDK.h. You can either change the first line to -I$(BCDS_APP_SOURCE_DIR)/paho/paho/XDK, or restructure your directory.

As for the second image, please tell me if the compiler errors shown there are still an issue after ensuring the correct directory structure.

Please tell me if this was helpful, and do not hesitate to ask further questions.

Kind regards,
Franjo

+1 (1 Vote)
RE: Setup MQTT connection
Answer
7/31/17 4:40 AM as a reply to Franjo Stjepandic.

Good morning Franjo & community,

 

thank you very much for your reply.
As you recommended I restructured the folders of my project. My new folder structure can be seen within the attached image (image 1: Folder structure MQTT project). I hope it is correct this time.

But I’m still receiving an error message. There are two errors occurring within the XDKapplication template. The errors are shown within the attached image ‘Error-msg within XDK application template’.

 

The first error (line 83) states:

‘unused parameter ‘pvParameters’ – [Wunused-parameter]

 

While, the second error (line 93) states:

Multiple markers at this line:

-       Each undeclared identifier is reported only once for each function it appears in’

-       ‘C’ undeclared (first use in this function)

 

 

In the following, I add the entire source code of my ’applicationTemplate’:

 

#include "BCDS_Basics.h"

#include "BCDS_WlanConnect.h"

#include "BCDS_NetworkConfig.h"

#include "MQTTClient.h"

#include "MQTTConnect.h"

#include "FreeRTOS.h"

#include "timers.h"

#include "XdkApplicationTemplate.h"

 

 

#define CLIENT_BUFF_SIZE 1000

#define CLIENT_TASK_STACK_SIZE 1024

#define CLIENT_TASK_PRIORITY 1

#define CLIENT_YIELD_TIMEOUT 10

#define SECONDS(x) ((portTickType) (x * 1000) / portTICK_RATE_MS)

 

 

 

 

// STATIC VOID CLIENT RECVR()

static void clientRecvr(MessageData* md)

{

MQTTMessage* message = md->message;

printf("Subscribed Topic, %.*s, Message Received: %.*s\r\n",

md->topicName->lenstring.len, md->topicName->lenstring.data,

(int)message->payloadlen, (char*)message->payload);

 

}

 

 

/** ************************************************************************* */

//STATIC VOID CLIENT TASK()

 

static uint32_t clientMessageId = 0;

 

static void clientTask(void*pvParameters) / FIRST ERROR

{

MQTTMessage msg;

for(;;)

{

vTaskDelay(SECONDS(1));

msg.id = clientMessageId++;

msg.qos = 2;

msg.payload = "Hello";

msg.payloadlen = sizeof("Hello")-1;

MQTTPublish(&c, "hello/world/xdk/send", &msg); / SECOND ERROR

MQTTYield(&c, CLIENT_YIELD_TIMEOUT);

}

}

 

//VOID APPINITSYSTEM (xTimerHandle xTimer)

 

static unsigned char buf[CLIENT_BUFF_SIZE];

static unsigned char readbuf[CLIENT_BUFF_SIZE];

Network n;

Client c;

void appInitSystem(xTimerHandle xTimer)

{

    (void) (xTimer);

    WlanConnect_SSID_T connectSSID = (WlanConnect_SSID_T) "RF_401";

    WlanConnect_PassPhrase_T connectPassPhrase = (WlanConnect_PassPhrase_T)

    "Support4You";

    WlanConnect_Init();

    NetworkConfig_SetIpDhcp(0);

    WlanConnect_WPA(connectSSID, connectPassPhrase, NULL);

 

    NewNetwork(&n);

    ConnectNetwork(&n, "10,4,1,110", 1883);

    MQTTClient(&c, &n, 1000, buf, CLIENT_BUFF_SIZE, readbuf,

    CLIENT_BUFF_SIZE);

 

    MQTTPacket_connectData data = MQTTPacket_connectData_initializer;

    data.willFlag = 0;

    data.MQTTVersion = 3;

    data.clientID.cstring = "xdk123";

    data.keepAliveInterval = 100;

    data.cleansession = 1;

    MQTTConnect(&c, &data);

 

    MQTTSubscribe(&c, (char*) "hello/world/xdk", QOS0, clientRecvr);

 

    xTaskCreate(clientTask, (const char * const) "Mqtt Client App",

    CLIENT_TASK_STACK_SIZE, NULL, CLIENT_TASK_PRIORITY, null);

 

}

 

As visible within image ‘Error-msg within XDK application template’ as well a warning sign is appearing within the ‘MQTTPacket.c’ folder of the project.

 

I would be very glad if somebody could review my approach.

 

Thanks so far for the great support.

 

Hope you had a nice weekend & kind regards

 

Nils

0 (0 Votes)
RE: Setup MQTT connection
Answer
7/31/17 11:07 AM as a reply to Nils Hilser.

Hello Nils,

the first message is not an issue and will not cause unexpected behaviour. It's simply a warning message, because it is usually expected in programming to use the declared input variables of a function in the function's body. In this case, the variable is pvParamters. You can suppress the warning by wrapping the variable in the macro BCDS_UNUSED(pvParameters), to tell the compiler that the variable is not used intentionally. Add this as the first line in the function.

As for the issue regarding the variable 'c', this is the variable declared for the Client, which you see in line 101. In the programming-langauge C, variables can not be used before they are declared. In your case, the variable c is used in clientTask() in line 91 and declared in line 101. To fix this, simply move the lines 100 and 101 (Network n; Client c;) to the top of your code, preferably below the defines.

Please tell me if this was helpful, and as always do not hesitate to ask further questions.

Kind regards,
Franjo

+1 (1 Vote)
RE: Setup MQTT connection
Answer
8/14/17 6:46 AM as a reply to Franjo Stjepandic.

Good morning Franjo,

Thanks a lot !

The script is working now properly and I'm able to send the string "hello" from the XDK to my broker and as well to subscribe the string from the broker by using another client.

Now I will continue my XDK project by trying to combine the 'MQTT hello string' script with a pre-installed script that is capable to stream sensor data.

I will keep you updated about the progress of the project.

Thanks so far for your help.

Regards

Nils

 

0 (0 Votes)
RE: Setup MQTT connection
Answer
8/14/17 2:02 PM as a reply to Nils Hilser.

Hello Nils,

I am glad to hear that your application is now working properly, I am looking forward to hearing about your progress.

Please feel free to ask, if you have further questions or any kind of issue.

Kind regards,
Franjo

0 (0 Votes)
RE: Setup MQTT connection
Answer
9/29/17 12:35 PM as a reply to Franjo Stjepandic.

Good afternoon Franjo,

After a while I started the XDK skript for some test purpose. Unfortunately I can receive  the message "hello" only once on my MQTT broker. Not every second as intended and as it was working before. Only when I activate the broker the message "hello" appears. Afterwards, no new messages are incoming.

 

I'm sure that I was not changing the source code since the last approach. You have any idea what might the reason ?

 

Thank you in advance

Regards

 

Nils

0 (0 Votes)
RE: Setup MQTT connection
Answer
9/29/17 4:40 PM as a reply to Nils Hilser.

Hello Nils,

In which way did you confirm, that the XDK only sends hello once? Do you confirm that by looking at the messages your second client or your broker receive? Since you didn't change the implementation, the behaviour should not have changed either.

Would you be so kind and clarify what you mean by Only when I activate the broker? Does that mean, you start the broker, and the client receives a message? If that is the case, perhaps the message is a retained message, which gets sent to clients as soon as they subscribe.

Did you check if the XDK is connected to the local WiFi at all?

Kind regards,
Franjo

0 (0 Votes)
RE: Setup MQTT connection
Answer
10/4/17 10:18 AM as a reply to Franjo Stjepandic.

Hello Franjo,

you are right, my previous description was a bit fuzzy.. sorry for that.

The XDK is sending the message to a raspberry pi. On the raspberry pi a mosquitto broker is running.

Iam using a laptop for subscribing (via a python script or using node red). At the broker (raspberry pi), the published messages from the XDK are not arriving. As a consequence, i cannot subscribe to them by using another client. In oder to verify the broker isnt the source of error, I was using another device to send a message via MQTT (instead of XDK). In this case the message is arriving at the broker and Iam as well able to receive the message on my client by subscribing to the broker.

So I'm quite sure the soure of error must be somewhere in my ApplicationTemplate (appended it again at the bottom of this message). I checked as well if all devices involved are connected to same network.

Thank you in advance

 

Code-snippet:

/* system header files */
#include "BCDS_Basics.h"
#include "BCDS_WlanConnect.h"
#include "BCDS_NetworkConfig.h"
#include "MQTTClient.h"
#include "MQTTConnect.h"
/* additional interface header files */
#include "FreeRTOS.h"
#include "timers.h"

/* own header files */
#include "XdkApplicationTemplate.h"

/* constant definitions ***************************************************** */
#define CLIENT_BUFF_SIZE 1000

/* local variables ********************************************************** */

#define CLIENT_TASK_STACK_SIZE 1024
#define CLIENT_TASK_PRIORITY 1
#define CLIENT_YIELD_TIMEOUT 10
#define SECONDS(x) ((portTickType) (x * 1000) / portTICK_RATE_MS)

Network n;
Client c;

static unsigned char buf[CLIENT_BUFF_SIZE];
static unsigned char readbuf[CLIENT_BUFF_SIZE];
// PUBLISH TASK IMPLEMENTATION

static uint32_t clientMessageId = 0;

static void clientTask(void*pvParameters)
{
MQTTMessage msg;
for(;;)
{
vTaskDelay(SECONDS(1));
msg.id = clientMessageId++;
msg.qos = 2;
msg.payload = "Hello";
msg.payloadlen = sizeof("Hello")-1;
MQTTPublish(&c, "hello/world/xdk/send", &msg);
MQTTYield(&c, CLIENT_YIELD_TIMEOUT);
}
}

//CLIENT RECEIVE ! INCOMING DATA HANDLING


    static void clientRecvr(MessageData* md)
    {
    MQTTMessage* message = md->message;
    printf("Subscribed Topic, %.*s, Message Received: %.*s\r\n",
    md->topicName->lenstring.len, md->topicName->lenstring.data,
    (int)message->payloadlen, (char*)message->payload);

    }


//VOID APPINITSYSTEM (xTimerHandle xTimer) ! PUBLISH TASK CREATION


void appInitSystem(xTimerHandle xTimer)
{
    (void) (xTimer);
    WlanConnect_SSID_T connectSSID = (WlanConnect_SSID_T) "XXXX";
    WlanConnect_PassPhrase_T connectPassPhrase = (WlanConnect_PassPhrase_T)
    "1234";
    WlanConnect_Init();
    NetworkConfig_SetIpDhcp(0);
    WlanConnect_WPA(connectSSID, connectPassPhrase, NULL);

    NewNetwork(&n);
    ConnectNetwork(&n, "10.4.1.125", 1883); //10.11.1.116
    MQTTClient(&c, &n, 1000, buf, CLIENT_BUFF_SIZE, readbuf,
    CLIENT_BUFF_SIZE);

    MQTTPacket_connectData data = MQTTPacket_connectData_initializer;
    data.willFlag = 0;
    data.MQTTVersion = 3;
    data.clientID.cstring = "xdk123";
    data.keepAliveInterval = 100;
    data.cleansession = 1;
    MQTTConnect(&c, &data);

 

    MQTTSubscribe(&c, (char*) "hello/world/xdk", QOS0, clientRecvr);

    xTaskCreate(clientTask, (const char * const) "Mqtt Client App",
    CLIENT_TASK_STACK_SIZE, NULL, CLIENT_TASK_PRIORITY, null);

}

P.S.: the topic I'm subscribing to is "hello/world/xdk/send"

Kind regards

Nils

0 (0 Votes)
RE: Setup MQTT connection
Answer
10/4/17 12:19 PM as a reply to Nils Hilser.

Hello Nils,

I have tried out your code with the following setup: XDK with Workbench Version 3.0.1, flashed your application onto it. The XDK sends messages to a mosquitto broker on a raspberry Pi. On a Ubuntu Laptop, used as the client, I receive the messages using the command line application mosquitto_sub (for subscribing).

The client receives a Hello every second, so I cannot exactly confirm that the implementation is not working properly. And to be honest, I am a little bit confused. Does the client receive the message Hello only once? Or does the client not receive messages from the XDK at all?

Have you checked the mosquitto log on the raspberry? You can enable the verbose mode of the mosquitto broker by using the the option -v (verbose) when running mosquitto from the command line.

$ mosquitto -v

The log will look as follows, for each message that you received

1507118519: Received PUBLISH from xdk123 (d0, q2, r1, m45, 'hello/world/xdk/send', ... (5 bytes))
1507118519: Sending PUBREC to xdk123 (Mid: 45)
1507118519: Received PUBREL from xdk123 (Mid: 45)
1507118519: Sending PUBCOMP to xdk123 (Mid: 45)
1507118519: Sending PUBLISH to mosqsub/27647-your_notebook (d0, q0, r0, m0, 'hello/world/xdk/send', ... (5 bytes))

Mid is the Message ID.

The log will also reflect connection details as follows:

1507118469: New connection from your_xdk_ip_address on port 1883.
1507118469: New client connected from your_xdk_ip_address as xdk123 (c1, k100).
1507118469: Sending CONNACK to xdk123 (0)

Finally, make sure that the Broker-IP you use in your XDK's application is correct.

Please tell me if this was helpful and do not hesitate to ask further questions.

Kind regards,
Franjo

0 (0 Votes)
RE: Setup MQTT connection
Answer
10/5/17 9:05 AM as a reply to Franjo Stjepandic.

Good morning Franjo,

Thanks for your answer. Glad to hear that the script seems to be correct and should work. I've checked all your advices but sill receiving no message. Sorry for the confusion..currently I'm not receiving any message. After i restarted my old approach I was first receiving only one message and after an update of the workbench I'm not receiving any string. Which is very strange..

For a better illiustration I will add some pictures in the following.

First I used the terminal command hostname -I to figure out the correct IP address of my broker (raspberry). Then, as you advised me I used the terminal command mosquitto -v to review the log of the broker.

Even after adding the IP address to my Application Template (pic.: Workbench and XDK), the log of the broker remains empty (pic.: Terminal raspy).

In addition, I added again a snip of the entire folder structure.

Dont know how to solve this issue. Maybe I'm overseeing an obvious mistake ?

 

Thanks for your help

 

Kind regards

 

Nils

 

 

0 (0 Votes)
RE: Setup MQTT connection
Answer
10/5/17 2:34 PM as a reply to Nils Hilser.

Hello Nils,


I understand the situation now, but finding the cause of the issue will be difficult, since this is definitely not an obvious mistake. I assume that something is wrong with the setup, regarding the connection to Raspberry.

But first, since you updated the Workbench recently, it should be version 3.0.1 now, is that correct? If it is, did you make the correct changes in Main.c and XdkApplicationTemplate.h? The function main() in Main.c has changed with version 3.0.1.

The quickest way to migrate your project to version 3.0.1 would be by creating a new project from an XdkApplicationTemplate, and copy the code including the makefile from your old project's XdkApplicationTemplate.c file to the new. Be aware that the signature of the function appInitSystem() has changed and you should copy the function's content separately. The rest can be copied without problems.

Additionally, in the file source > paho > XDK > mqttXdk.c, every occurence of

long left = timer->end_time - PowerMgt_GetSystemTimeMs();

should be replaced with

long left = timer->end_time - xTaskGetTickCount()/portTICK_PERIOD_MS;

If you migrated the project correctly, I have two guesses as to what causes your issue:


1. The raspberry is connected via LAN, and the WiFi is not turned on
2. The XDK can't connect because the credentials are not entirely correct

Regarding the first case, the command $ hostname -I would print only the active network interfaces. If only the LAN connection is active (the interface's name is eth0 or similar) then only the address for this interface would be printed. You can check which interfaces are up and have an address associated with them via the command $ ip address. The output should be like this, if no address is given:

3: wlan0: <NO-CARRIER,BROADCAST,MULTICAST,UP> mtu 1500 qdisc pfifo_fast state DOWN group default qlen 1000
    link/ether xx:xx:xx:xx:xx:xx brd ff:ff:ff:ff:ff:ff

And as follows, if an address is given:

3: wlan0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP group default qlen 1000
    link/ether xx:xx:xx:xx:xx:xx brd ff:ff:ff:ff:ff:ff
    inet 10.4.1.131/xx brd 192.168.10.255 scope global wlan0
       valid_lft forever preferred_lft forever
    inet6 xxxx::xxxx:xxxx:xxxx:xxxx/xx scope link
       valid_lft forever preferred_lft forever

If no address is given, I'd recommend to look into that, since the XDK can only connect via the wlan0 interface.
Regarding the second case, in the code you presented in your last post the SSID and PW for the WiFi you use are XXXX and 1234 respectively. While I understand that you changed these to prevent others from seeing the PW to your SSID, make sure that the SSID and PW in your code are correct. Perhaps you changed the SSID or PW lately, and didn't make the corresponding changes in the code.
Finally, for debugging purposes, I recommend printing the return codes of the function WlanConnect_WPA() and ConnectNetwork() in your code, as follows:

Retcode_T rc_wlan = WlanConnect_WPA(connectSSID, connectPassPhrase, NULL);
printf("rc_wlan: %d\n\r", (int) Retcode_getCode(rc_wlan));

and

int rc_connect = ConnectNetwork(&n, "10.4.1.131", 1883);
printf("rc_connect: %d\n\r", rc_connect);

For WlanConnect_WPA(), the return codes have the following names associated with them, if they are not 0

65: RETCODE_NO_NW_AVAILABLE
66: RETCODE_ALREADY_DISCONNECTED,
67: RETCODE_CONNECTION_ERROR,
68: RETCODE_ERROR_WRONG_PASSWORD,
69: RETCODE_ERROR_IP_NOT_ACQ,
70: RETCODE_DISCONNECT_ERROR,
71: RETCODE_SIMPLELINK_ERROR,
72: RETCODE_TIMERCREATE_FAILURE,
73: RETCODE_TIMERSTART_FAILURE,
74: RETCODE_TIME_NULL

For ConnectNetwork(), if the return code is 0, it is an error code. You can find the error codes defined in the file socket.h at

SDK > xdk110 > Libraries > WiFi > 3rd-party > TI > simplelink > include


Simply search for the error code inside the function, and you will find the associated macro name / comment.


Please tell me if this was helpful, and do not hesitate to ask further questions.

Kind regards,
Franjo

0 (0 Votes)
RE: Setup MQTT connection
Answer
10/23/17 10:38 AM as a reply to Franjo Stjepandic.

Hello Franjo,

sorry for my late reply.

Thanks for your answer it helped me a lot. But I'm still not receiving any message at my client.

In the following i will document my approach to fix my bug by following your advices.

I was not aware that functions change their name after each upgrade of the workbench. Is there a kind of a history available where it is possible to see the changes occuring within functions after each update?

It is correct, the version of my workbench is now: 3.0.1.

The Xdk ApplicationTemplate.h is now looking like the following: 

/* header definition ******************************************************** */

#ifndef XDK110_XDKAPPLICATIONTEMPLATE_H_

#define XDK110_XDKAPPLICATIONTEMPLATE_H_

 

/* local interface declaration ********************************************** */

/* Priorities */

#define TASK_PRIO_MAIN_CMD_PROCESSOR (UINT32_C(1))

#define TASK_STACK_SIZE_MAIN_CMD_PROCESSOR (UINT16_C(700))

#define TASK_Q_LEN_MAIN_CMD_PROCESSOR (UINT32_C(10))

/* local type and macro definitions */

 

/* local function prototype declarations */

 

/* local module global variable declarations */

 

/* local inline function definitions */

/**

* @brief This is a template function where the user can write his custom application.

*

* @param[in] CmdProcessorHandle Handle of the main commandprocessor

*

* @param[in] param2 Currently not used will be used in future

*/

void appInitSystem(void * CmdProcessorHandle, uint32_t param2);

 

#endif /* XDK110_XDKAPPLICATIONTEMPLATE_H_ */

 

/** ************************************************************************* */

The Main.c template is looking like:

/* system header files */

#include <stdio.h>

#include "BCDS_Basics.h"

 

/* additional interface header files */

#include "XdkSystemStartup.h"

#include "BCDS_Assert.h"

#include "BCDS_CmdProcessor.h"

#include "FreeRTOS.h"

#include "task.h"

#include "MQTT_3.1_new.h"

 

/* own header files */

 

/* global variables ********************************************************* */

static CmdProcessor_T MainCmdProcessor;

 

/* functions */

 

int main(void)

{

/* Mapping Default Error Handling function */

Retcode_T returnValue = Retcode_initialize(DefaultErrorHandlingFunc);

if (RETCODE_OK == returnValue)

{

returnValue = systemStartup();

}

if (RETCODE_OK == returnValue)

{

returnValue = CmdProcessor_initialize(&MainCmdProcessor, (char *) "MainCmdProcessor", TASK_PRIO_MAIN_CMD_PROCESSOR, TASK_STACK_SIZE_MAIN_CMD_PROCESSOR, TASK_Q_LEN_MAIN_CMD_PROCESSOR);

}

if (RETCODE_OK == returnValue)

{

/* Here we enqueue the application initialization into the command

* processor, such that the initialization function will be invoked

* once the RTOS scheduler is started below.

*/

returnValue = CmdProcessor_enqueue(&MainCmdProcessor, appInitSystem, &MainCmdProcessor, UINT32_C(0));

}

if (RETCODE_OK != returnValue)

{

printf("System Startup failed");

assert(false);

}

/* start scheduler */

vTaskStartScheduler();

}

I was creating a new project with an XDK application template and copied all other templates(from my ´working workbench 2.1 project) to the new project. Before I copied all files to the new project I was clicking  'building a new project' for the respective project in the 3.0.1 workbench in order to retrieve the required binary files.

Within my new XDKApplication Template.c i changed the appInitSystem() function.
As a result my new application template looks like the following:

/* system header files */

#include <stdio.h>

#include "BCDS_Basics.h"

#include "BCDS_WlanConnect.h"

#include "BCDS_NetworkConfig.h"

#include "MQTTClient.h"

#include "MQTTConnect.h"

/* additional interface header files */

#include "FreeRTOS.h"

#include "timers.h"

 

/* own header files */

#include "MQTT_3.1_new.h"

#include "BCDS_CmdProcessor.h"

#include "BCDS_Assert.h"

 

/* constant definitions ***************************************************** */

#define CLIENT_BUFF_SIZE 1000

/* local variables ********************************************************** */

#define CLIENT_TASK_STACK_SIZE 1024

#define CLIENT_TASK_PRIORITY 1

#define CLIENT_YIELD_TIMEOUT 10

#define SECONDS(x) ((portTickType) (x * 1000) / portTICK_RATE_MS)

 

Network n;

Client c;

 

static unsigned char buf[CLIENT_BUFF_SIZE];

static unsigned char readbuf[CLIENT_BUFF_SIZE];

 

// PUBLISH TASK IMPLEMENTATION

 

static uint32_t clientMessageId = 0;

 

static void clientTask(void*pvParameters)

{

MQTTMessage msg;

for(;;)

{

vTaskDelay(SECONDS(1));

msg.id = clientMessageId++;

msg.qos = 2;

msg.payload = "Hello";

msg.payloadlen = sizeof("Hello")-1;

MQTTPublish(&c, "hello/world/xdk/send", &msg);

MQTTYield(&c, CLIENT_YIELD_TIMEOUT);

}

}

 

//CLIENT RECEIVE ! INCOMING DATA HANDLING

 

 

static void clientRecvr(MessageData* md)

{

MQTTMessage* message = md->message;

printf("Subscribed Topic, %.*s, Message Received: %.*s\r\n",

md->topicName->lenstring.len, md->topicName->lenstring.data,

(int)message->payloadlen, (char*)message->payload);

 

}

 

 

//VOID APPINITSYSTEM (xTimerHandle xTimer) ! PUBLISH TASK CREATION

 

void appInitSystem(void * CmdProcessorHandle, uint32_t param2)

{

if (CmdProcessorHandle == NULL)

{

printf("Command processor handle is null \n\r");

assert(false);

}

BCDS_UNUSED(param2);

WlanConnect_SSID_T connectSSID = (WlanConnect_SSID_T) "XXXXX";

WlanConnect_PassPhrase_T connectPassPhrase = (WlanConnect_PassPhrase_T)

"1234";

WlanConnect_Init();

NetworkConfig_SetIpDhcp(0);

Retcode_T rc_wlan=WlanConnect_WPA(connectSSID, connectPassPhrase, NULL);

printf("rc_wlan: %d\n\r", (int) Retcode_getCode(rc_wlan));

NewNetwork(&n);

int rc_connect=ConnectNetwork(&n, "10.11.7.201", 1883);

printf("rc_connect: %d\n\r", rc_connect);

MQTTClient(&c, &n, 1000, buf, CLIENT_BUFF_SIZE, readbuf,

CLIENT_BUFF_SIZE);

 

MQTTPacket_connectData data = MQTTPacket_connectData_initializer;

data.willFlag = 0;

data.MQTTVersion = 3;

data.clientID.cstring = "xdk123";

data.keepAliveInterval = 100;

data.cleansession = 1;

MQTTConnect(&c, &data);

 

 

 

MQTTSubscribe(&c, (char*) "hello/world/xdk", QOS0, clientRecvr);

 

xTaskCreate(clientTask, (const char * const) "Mqtt Client App",

CLIENT_TASK_STACK_SIZE, NULL, CLIENT_TASK_PRIORITY, null);

}

/**@} */

/** ************************************************************************* */

Additionally i changed the in the file source > paho > XDK > mqttXdk.c, every occurence of

long left = timer->end_time - PowerMgt_GetSystemTimeMs();

with

long left = timer->end_time - xTaskGetTickCount()/portTICK_PERIOD_MS;

This can be seen in the following code snippet:

/* system header files */

#include <stdint.h>

 

/* interface header files */

//#include "BCDS_PowerMgt.h"

 

/* own header files */

#include "mqttXDK.h"

 

char expired(Timer* timer) {

long left = timer->end_time - xTaskGetTickCount()/portTICK_PERIOD_MS();

return (left < 0);

}

 

 

void countdown_ms(Timer* timer, unsigned int timeout) {

timer->end_time = PowerMgt_GetSystemTimeMs() + timeout;

}

 

 

void countdown(Timer* timer, unsigned int timeout) {

timer->end_time = PowerMgt_GetSystemTimeMs() + (timeout * 1000);

}

 

 

int left_ms(Timer* timer) {

long left = timer->end_time - xTaskGetTickCount()/portTICK_PERIOD_MS();

return (left < 0) ? 0 : left;

}

 

 

void InitTimer(Timer* timer) {

timer->end_time = 0;

}

 

 

int xdk_read(Network* n, uint8_t* buffer, int len, int timeout_ms) {

SlTimeval_t timeVal;

SlFdSet_t fdset;

int rc = 0;

int recvLen = 0;

 

SL_FD_ZERO(&fdset);

SL_FD_SET(n->my_socket, &fdset);

 

timeVal.tv_sec = 0;

timeVal.tv_usec = timeout_ms * 1000;

if (sl_Select(n->my_socket + 1, &fdset, NULL, NULL, &timeVal) == 1) {

do {

rc = sl_Recv(n->my_socket, buffer + recvLen, len - recvLen, 0);

recvLen += rc;

} while(recvLen < len);

}

return recvLen;

}

 

int xdk_write(Network* n, uint8_t* buffer, int len, int timeout_ms) {

SlTimeval_t timeVal;

SlFdSet_t fdset;

int rc = 0;

int readySock;

 

SL_FD_ZERO(&fdset);

SL_FD_SET(n->my_socket, &fdset);

 

timeVal.tv_sec = 0;

timeVal.tv_usec = timeout_ms * 1000;

do {

readySock = sl_Select(n->my_socket + 1, NULL, &fdset, NULL, &timeVal);

} while(readySock != 1);

rc = sl_Send(n->my_socket, buffer, len, 0);

return rc;

}

void xdk_disconnect(Network* n) {

sl_Close(n->my_socket);

}

 

void NewNetwork(Network* n) {

n->my_socket = 0;

n->mqttread = xdk_read;

n->mqttwrite = xdk_write;

n->disconnect = xdk_disconnect;

}

 

int TLSConnectNetwork(Network *n, char* addr, int port, SlSockSecureFiles_t* certificates, unsigned char sec_method, unsigned int cipher, char server_verify) {

SlSockAddrIn_t sAddr;

int addrSize;

int retVal;

unsigned long ipAddress;

 

retVal = sl_NetAppDnsGetHostByName((_i8*) addr, strlen(addr), &ipAddress, AF_INET);

if (retVal < 0) {

return -1;

}

 

sAddr.sin_family = AF_INET;

sAddr.sin_port = sl_Htons((unsigned short)port);

sAddr.sin_addr.s_addr = sl_Htonl(ipAddress);

 

addrSize = sizeof(SlSockAddrIn_t);

 

n->my_socket = sl_Socket(SL_AF_INET,SL_SOCK_STREAM, SL_SEC_SOCKET);

if (n->my_socket < 0) {

return -1;

}

 

SlSockSecureMethod method;

method.secureMethod = sec_method;

retVal = sl_SetSockOpt(n->my_socket, SL_SOL_SOCKET, SL_SO_SECMETHOD, &method, sizeof(method));

if (retVal < 0) {

return retVal;

}

 

SlSockSecureMask mask;

mask.secureMask = cipher;

retVal = sl_SetSockOpt(n->my_socket, SL_SOL_SOCKET, SL_SO_SECURE_MASK, &mask, sizeof(mask));

if (retVal < 0) {

return retVal;

}

 

if (certificates != NULL) {

retVal = sl_SetSockOpt(n->my_socket, SL_SOL_SOCKET, SL_SO_SECURE_FILES, certificates->secureFiles, sizeof(SlSockSecureFiles_t));

if(retVal < 0)

{

return retVal;

}

}

 

retVal = sl_Connect(n->my_socket, ( SlSockAddr_t *)&sAddr, addrSize);

if( retVal < 0 ) {

if (server_verify || retVal != -453) {

sl_Close(n->my_socket);

return retVal;

}

}

 

return retVal;

}

 

int ConnectNetwork(Network* n, char* addr, int port)

{

SlSockAddrIn_t sAddr;

int addrSize;

int retVal = -1;

unsigned long ipAddress;

 

sl_NetAppDnsGetHostByName((_i8*) addr, strlen((char*)addr), &ipAddress, AF_INET);

 

sAddr.sin_family = AF_INET;

sAddr.sin_port = sl_Htons((unsigned short)port);

sAddr.sin_addr.s_addr = sl_Htonl(ipAddress);

 

addrSize = sizeof(SlSockAddrIn_t);

 

n->my_socket = sl_Socket(SL_AF_INET,SL_SOCK_STREAM, 0);

if( n->my_socket < 0 ) {

// error

return -1;

}

 

retVal = sl_Connect(n->my_socket, ( SlSockAddr_t *)&sAddr, addrSize);

if( retVal < 0 ) {

// error

sl_Close(n->my_socket);

return retVal;

}

 

return retVal;

}

Regarding your points (1 & 2, see below).

1. The raspberry is connected via LAN, and the WiFi is not turned on
2. The XDK can't connect because the credentials are not entirely correct

In case 1 I was using as recommended the command $ ip address instead of $hostname-I. It gave me the output like in the case if an address is given. I received the IP address: inet 10.11.7.201, which I added as well to my ApplicationTemplate.c.

I checked as well the SSID and PW --> they are still correct. Furhtermore, I added as well the lines for dbugging purpose:

Retcode_T rc_wlan = WlanConnect_WPA(connectSSID, connectPassPhrase, NULL);
printf("rc_wlan: %d\n\r", (int) Retcode_getCode(rc_wlan));

and

int rc_connect = ConnectNetwork(&n, "10.4.1.131", 1883);
printf("rc_connect: %d\n\r", rc_connect);

I added these two debugging lines to my Application template (see corresponding code snippet).

But i cannot see any results on my Console.

When i flash the project to my XDK in the Console is standing:

INFO | New device has been discovered in application mode. Changing to bootloader mode to extract bootloader version...

INFO | Connecting to XDK device 'XDK Device 1' in port 'COM3'...

INFO | Connection to port 'COM3' established

INFO | Flashing file 'C:/XDK-Workbench/workspace/MQTT_3.1_new_copy/debug/MQTT_3.1_new_copy.bin'...

INFO | Application checksum 'ee4f' successfully verified.

INFO | Transmission successfully completed!

INFO | Booting application...

INFO | XDK DEVICE 1: Jumping to application

INFO | Disconnecting XDK device 'XDK Device 1' from port 'COM3'...

INFO | Port 'COM3' has been disconnected

INFO | Connecting to XDK device 'XDK Device 1' in port 'COM3'...

INFO | Connection to port 'COM3' established

So i assume the project is now running on the XDK device. However, after flashing the project to the XDK i see the following error within my folder structure (see screenshot attached: 'folder structure' . In snippet ('error line') you can see that the mqttXDK.c skript seems not to be correct? By moving the cursor across the cross i see the following error message:

 

$(BCDS_APP_DIR)/source/paho/XDK/mqttXDK.c

$(BCDS_APP_DIR)/source/paho/MQTTClient.c

$(BCDS_APP_DIR)/source/paho/MQTTConnectClient.c

$(BCDS_APP_DIR)/source/paho/MQTTConnectServer.c

$(BCDS_APP_DIR)/source/paho/MQTTDeserializePublish.c

$(BCDS_APP_DIR)/source/paho/MQTTFormat.c

$(BCDS_APP_DIR)/source/paho/MQTTPacket.c

$(BCDS_APP_DIR)/source/paho/MQTTSerializePublish.c

$(BCDS_APP_DIR)/source/paho/MQTTSubscribeClient.c

$(BCDS_APP_DIR)/source/paho/MQTTSubscribeServer.c

$(BCDS_APP_DIR)/source/paho/MQTTUnsubscribeClient.c

$(BCDS_APP_DIR)/source/paho/MQTTUnsubscribeServer.c

What does this exactly mean?

Is there maybe another way to test the application without using a raspberry pi ?

Thank you very much !

Kind regards

 

Nils

 

0 (0 Votes)
RE: Setup MQTT connection
Answer
10/23/17 12:50 PM as a reply to Nils Hilser.

Good afternoon Franjo,

 

 

regarding the error message within the makefile ive found a mistake.


There was a backslash missing. I changed the the skript now to:

 

 

export BCDS_XDK_APP_SOURCE_FILES = \

$(BCDS_APP_SOURCE_DIR)/Main.c \

$(BCDS_APP_SOURCE_DIR)/MQTT_3.1_new_copy.c \

$(BCDS_APP_SOURCE_DIR)/paho/XDK/mqttXDK.c \

$(BCDS_APP_SOURCE_DIR)/paho/MQTTClient.c \

$(BCDS_APP_SOURCE_DIR)/paho/MQTTConnectClient.c \

$(BCDS_APP_SOURCE_DIR)/paho/MQTTConnectServer.c \

$(BCDS_APP_SOURCE_DIR)/paho/MQTTDeserializePublish.c \

$(BCDS_APP_SOURCE_DIR)/paho/MQTTFormat.c \

$(BCDS_APP_SOURCE_DIR)/paho/MQTTPacket.c \

$(BCDS_APP_SOURCE_DIR)/paho/MQTTSerializePublish.c \


$(BCDS_APP_SOURCE_DIR)/paho/MQTTSubscribeClient.c \

$(BCDS_APP_SOURCE_DIR)/paho/MQTTSubscribeServer.c \

$(BCDS_APP_SOURCE_DIR)/paho/MQTTUnsubscribeClient.c \

$(BCDS_APP_SOURCE_DIR)/paho/MQTTUnsubscribeServer.c


But now the error is shifting to debug line at the last part of the skript.

 

 

I keep on trying..

 

 

Regards

 

Nils

0 (0 Votes)
RE: Setup MQTT connection
Answer
10/23/17 4:52 PM as a reply to Nils Hilser.

Hello Nils,

the only issue I see is in mqttXDK.c, in the functions countdown() and countdown_ms(). I did not state the changes regarding PowerMgt_GetSystemTimeMs() correctly.

PowerMgt_GetSystemTimeMs() is a function from the interface BCDS_PowerMgt.h. But since the interface does not exist anymore, the previously mentioned function cannot be called either. So, replace

PowerMgt_GetSystemTimeMs()

with

xTaskGetTickCount()/portTICK_PERIOD_MS()

in countdown() and countdown_ms. I apologize for the partial statement in my previous post. Of course, the other changes are still appropriate, in that regard.

Regarding the error indicator in your makefile, the line 46 will always get marked when any error during building occurs. To be sure, there should be other error messages.

And on a sidenote, when you press the Flash-Button, and if you have a correctly built binary in your project, the XDK will still flash the old binary, even if the build process has failed.

Anyway, without seeing your project, I can only make guesses regarding the cause of your issues. The easiest way to determine the issues would be to take a look at your entire project. If you don't mind, could you leave your e-mail address here so I can contact you directly? Alternatively, you could upload your project as a zip-archive and post the download link here.

Finally, regarding your question "Is there maybe another way to test the application without using a raspberry pi ?", you can use broker.hivemq.com as the host for your broker, and connect via a websocket client on this website. This client can subscribe to topics and publish messages on topics, and would remove any obstacles regarding network configuration. You only need to connect your XDK to the internet for that, via a WiFI network.

Please tell me if this was helpful, and do not hesitate to ask further questions.

Kind regards,
Franjo

0 (0 Votes)
RE: Setup MQTT connection
Answer
10/27/17 1:32 PM as a reply to Franjo Stjepandic.

Good afternoon Franjo,

Thanks for your reply.

I made the changes as you suggested but now I'm not able to flash the programm to my XDK.

After adapting and saving the project the binaries were gone. I clicked on 'build project' but still the binaies are not getting recreated. Am I right that this is in general the correct way to do this ?

However, i receive a compilation error.

Indeed, i think the best way is that you have a look by your own at the project.
Thanks for this proposal.

I dont see any opportunity to upload a file in this 'chat'. So you can send me your mail address and I will forward you a ZIP file of my project ?!

You can contact via the following Mail address:

Nils_XDK_communication@gmx.de

Thanks a lot & have a nice weekend !

 

Kind regards

0 (0 Votes)
RE: Setup MQTT connection
Answer
10/30/17 3:30 PM as a reply to Nils Hilser.

Hello Nils,

Yes, clicking Build Project is the correct way to do this. The fact that no binary is created is because you have compilation errors, but with the information I have right now, I am not able to determine the cause. I have sent an email to the address you posted, to exchange the project. Once I receive the project, I will post my findings here.

Kind regards,
Franjo

0 (0 Votes)
RE: Setup MQTT connection
Answer
11/2/17 4:37 PM as a reply to Franjo Stjepandic.

Hello Nils,

as I took a look at the code you sent me via Email, I can see the errors now.

I've mistakenly added parantheses at the end of the statement

xTaskGetTickCount()/portTICK_PERIOD_MS()

Remove the parantheses, which I marked red, for each statement of this kind, and the expression should become valid. Additionally, you have to include the header files freeRTOS.h and task.h in mqttXdk.c.

Finally, when I imported the project, the makefile missed the implementation source file MQTT_3.1_new.c in the variable export BCDS_XDK_APP_SOURCE_FILES (this is the variable, where all implementation files are stored). This was probably just an issue because you renamed the project before you sent it to me, but if an error such as

No rule to make target '/opt/XDK-Workbench-3.0.1/workspace/MQTT_3.1_new/debug/objects/MQTT_3.1_new_copy.o', needed by '/opt/XDK-Workbench-3.0.1/workspace/MQTT_3.1_new/debug/MQTT_3.1_new.out'.  Stop.

appears, then it is because the implementation file MQTT_3.1_new_copy.c cannot be found.

I have tested the code after making these changes, and it worked as intended. I.e. sending a Hello Message every second.

Please tell me if this was helpful, and do not hesitate to ask further questions

Kind regards,
Franjo

0 (0 Votes)
RE: Setup MQTT connection
Answer
11/3/17 1:54 PM as a reply to Franjo Stjepandic.

Good afternoon Franjo,

 

Thank you very much !

the script is now running properly.

On the basis of this script I will try to build a project, which is able to send sensor data instead of the string "Hello".

I would like to post possible questions in this regard into the same chat. Or is it better to create a new chat for this?

 

Kind regards

 

Nils 

 

 

0 (0 Votes)
RE: Setup MQTT connection
Answer
11/3/17 4:01 PM as a reply to Nils Hilser.

Hello Nils,

I am glad to hear that it is working now.

You can, of course, extend your XDK project to send sensor data.

Regarding that, I would ask you to open up a new thread, since the initial issue is solved and other users with similar questions will more easily find a solution to an issue, if a thread does not cover many issues at once.

Kind regards,
Franjo

0 (0 Votes)