IOT - Bosch
  • Introduction
  • Devices
    • Bosch XDK 110
      • Introduction
      • Operating System
      • Hardware
        • Sensors
          • Accelerometer
            • C
          • Gyroscope
            • C
            • Mita
          • Magnetometer
            • C
          • Environmental
            • C
            • Mita
          • Ambient Light
            • C
            • Mita
          • Acoustic
            • C
      • Software
        • XDK WorkSpace
          • Structure
          • Debug
          • Supported languages
            • C
              • Static Library (.a)
            • XDK Live - Mita
            • MicroFlo
      • Connectivity
        • Bluetooth Low Energy (BLE)
          • Overview
          • General Info
          • Implementation
            • C
            • XDK Live
        • WI-FI
          • OverView
          • Implementation
            • C
            • XDK Live
        • WI-FI Enterprise
      • Protocols
        • CoAP
          • Overview
          • Implementation -TBD
        • HTTP
          • Overview
          • Structure and Methods
          • Implementation
            • C - Rest
            • C - Post
            • XDK Live
        • HTTPS
          • Overview
          • Implementation TBD
        • LWM2M
          • Overview
          • Implementation TBD
        • MQTT
          • Overview
          • Implementation
            • C
            • XDK Live
        • USB
          • Overview
          • Implementation TBD
      • Data Storage
      • XDK Extension Bus
      • Community
      • Applications
        • Language C
          • HomeAssitant - MQTT
            • Prerequisites
            • Server
            • Device
          • IOTA-MQTT-XDK
            • Prerequisites
            • XDK110
            • Mqtt JSON to MAM
            • SensorHub
            • Demo
        • Language XDK Live
          • MQTT
            • Hello World
            • HomeAssistant
              • Prerequisites
              • Server
              • Device
            • Docker-HomeAssistant
          • HTTP
            • Roku Remote Control
              • Roku API
              • MITA
                • Example
    • Bosch AMRA
    • Bosch GLM 100C
    • Bosch FLEXIDOME IP panoramic
    • Bosch GLM 100C
    • Bosch Rexroth Nexo
    • Bosch Rexroth PRC 7000
    • Bosch RRC / CT100
    • Bosch Rexroth IoT Gateway
  • Bosch IOT Solutions
    • Bosch IOT Projects
      • Smart Home
      • Industry 4.0
      • Smart Cities
      • Connected-mobility
    • Bosch IOT Suite
      • Bosch Analytics
      • Bosch IOT Hub
      • Bosch Iot Permission
      • IoT Remote Manager
      • IoT Rollouts
      • IoT Things
      • Demo TBD **
    • BPM and BRM
  • IOTA
    • Introduction
      • Tangle
      • Glossary
      • Differences with other tech
      • How does iota work
      • Developers
    • Qubic
      • What is Qubic?
      • Target
      • Qubic Protocol
    • Ecosystem
    • Applications
      • Python
      • XDK110
        • Prerequisites
        • XDK110
        • Mqtt JSON to MAM
        • SensorHub
    • Bosch/IOTA
  • ByteBall
    • SmartContract
    • Use Case
      • BoshCoins
Powered by GitBook
On this page

Was this helpful?

  1. Devices
  2. Bosch XDK 110
  3. Protocols
  4. MQTT
  5. Implementation

C

To make the API available to the application, the header file Serval_Mqtt.h has to be included in the implementation files

Additionally, in your project browse to

SDK > xdk110 > Libraries > ServalStack > 3rd-party > Serval Stack > api > Serval_Defines.h

And set the define of SERVAL_ENABLE_MQTT to 1, if this is not already done. If this is set to 0, the API will not be available in the application.

/* system header files */
#include <stdio.h>
/* additional interface header files */
#include "FreeRTOS.h"
#include "timers.h"
// MQTT API
#include "Serval_Mqtt.h"

/* own header files */
#include "BCDS_CmdProcessor.h"
#include "BCDS_Assert.h"

#include "BCDS_NetworkConfig.h"
#include "BCDS_WlanConnect.h"
#include "PAL_initialize_ih.h"
#include "PAL_socketMonitor_ih.h"

Some important constants and variables will be used throughout the guide. They are listed in the code below. The first two macros define the MQTT Host address and port respectively. The global variables for the session and a pointer to the session are relevant throughout the guide. The session must persist through the entire runtime of the MQTT application, as it will contain all the connection and server information, and is used by nearly every function of the MQTT API.

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

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

#define MQTT_BROKER_HOST "broker.hivemq.com"
#define MQTT_BROKER_PORT 1883
static MqttSession_T session;
static MqttSession_T *session_ptr = &session;

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

/* inline functions ********************************************************* */

/* local functions ********************************************************** */

/* global functions ********************************************************* */

We create this function that will help us to initialized the wifi con the XDK

void networkSetup(void) {
    WlanConnect_SSID_T connectSSID = (WlanConnect_SSID_T) "yourWifiNetworkSSID";
    WlanConnect_PassPhrase_T connectPassPhrase = (WlanConnect_PassPhrase_T) "yourWifiNetworkPW";
    WlanConnect_Init();
    NetworkConfig_SetIpDhcp(0);
    WlanConnect_WPA(connectSSID, connectPassPhrase, NULL);

    PAL_initialize();
    PAL_socketMonitorInit();

    NetworkConfig_IpSettings_T myIp;
    NetworkConfig_GetIpSettings(&myIp);

    // insert a delay here, if the IP is not properly printed
    printf("The IP was retrieved: %u.%u.%u.%u \n\r",
        (unsigned int) (NetworkConfig_Ipv4Byte(myIp.ipV4, 3)),
        (unsigned int) (NetworkConfig_Ipv4Byte(myIp.ipV4, 2)),
        (unsigned int) (NetworkConfig_Ipv4Byte(myIp.ipV4, 1)),
        (unsigned int) (NetworkConfig_Ipv4Byte(myIp.ipV4, 0)));
}

MQTT module must first be initialized. The initialization of the MQTT client is accomplished in two steps. First, the MQTT module itself is initialized by calling Mqtt_initialize(). Then, the variable session of type MqttSession_T is initialized.

retcode_t init(void) {
    retcode_t rc_initialize = Mqtt_initialize();
    if (rc_initialize == RC_OK) {
        session_ptr = &session;
        Mqtt_initializeInternalSession(session_ptr);
    }
    return rc_initialize;
}

As soon as the event MQTT_CONNECTION_ESTABLISHED occurs, it is possible to subscribe to a topic on the MQTT Server using Mqtt_subscribe().

The function Mqtt_subscribe() requires an array of topics and the corresponding Qualities of Service in another array. The first array is of type StringDescr_T, which is why each topic has to be wrapped into a StringDescr_T by using the function StringDescr_wrap. The array of QoS is of type Mqtt_qos_t, but the possible values are essentially numbers. The possible values are listed at the type definition of Mqtt_qos_t in Serval_Mqtt.h.

static void subscribe(void) {
    static char *sub_topic = "your/subscribe/topic";
    static StringDescr_T subscription_topics[1];
    static Mqtt_qos_t qos[1];
    StringDescr_wrap(&(subscription_topics[0]), sub_topic);
    qos[0] = MQTT_QOS_AT_MOST_ONE;
    Mqtt_subscribe(session_ptr, 1, subscription_topics, qos);
}

As soon as the event MQTT_CONNECTION_ESTABLISHED occurs, it is possible to publish on a topic on the MQTT Server to which the XDK is connected.

Parameters:

  • packetID

  • topicName

  • qos

  • retainFlag

  • payload

  • dupFlag

static void publish(void) {
    static char *pub_message = "Hello World";
    static char *pub_topic = "your/publish/topic";
    static StringDescr_T pub_topic_descr;
    StringDescr_wrap(&pub_topic_descr, pub_topic);

    Mqtt_publish(session_ptr, pub_topic_descr, pub_message, strlen(pub_message),
            MQTT_QOS_AT_MOST_ONE, false);
}

The current API is event-based. That means that the application reacts to every pre-defined event with a callback. The type of the variable eventData depends on the event.

The function handle_connection() is used in both MQTT_CONNECTION_ESTABLISHED and MQTT_CONNECTION_ERROR, because these events have the same data-type. It simply prints the connect return code sent by the server, at which the connection attempt was directed.

static void handle_incoming_publish(MqttPublishData_T publishData) {
    int topic_length = publishData.topic.length + 1;
    int data_length = publishData.length + 1;
    char published_topic_buffer[topic_length];
    char published_data_buffer[data_length];
    snprintf(published_topic_buffer, topic_length, publishData.topic.start);
    snprintf(published_data_buffer, data_length, (char *) publishData.payload);
    printf("Incoming Published Message:\n\r"
            "\tTopic: %s\n\r"
            "\tPayload: %s\n\r", published_topic_buffer, published_data_buffer);
}

static void handle_connection(MqttConnectionEstablishedEvent_T connectionData) {
    int rc_connect = (int) connectionData.connectReturnCode;
    printf("Connection Event:\n\r"
            "\tServer Return Code: %d (0 for success)\n\r", (int) rc_connect);
}

retcode_t event_handler(MqttSession_T* session, MqttEvent_t event,
        const MqttEventData_t* eventData) {
    BCDS_UNUSED(session);
    switch (event) {
    case MQTT_CONNECTION_ESTABLISHED:
        handle_connection(eventData->connect);
        // subscribing and publishing can now be done
        // subscribe();
        // publish();
        break;
    case MQTT_CONNECTION_ERROR:
        handle_connection(eventData->connect);
        break;
    case MQTT_INCOMING_PUBLISH:
        handle_incoming_publish(eventData->publish);
        break;
    case MQTT_SUBSCRIPTION_ACKNOWLEDGED:
        printf("Subscription Successful\n\r");
        break;
    case MQTT_PUBLISHED_DATA:
        printf("Publish Successful\n\r");
        break;
    default:
        printf("Unhandled MQTT Event: %d\n\r", event);
        break;
    }
    return RC_OK;
}

void config_set_target(void) {
    static char mqtt_broker[64];
    const char *mqtt_broker_format = "mqtt://%s:%d";
    char server_ip_buffer[13];
    Ip_Address_T ip;

    PAL_getIpaddress((uint8_t *) MQTT_BROKER_HOST, &ip);
    Ip_convertAddrToString(&ip, server_ip_buffer);
    sprintf(mqtt_broker, mqtt_broker_format, server_ip_buffer,
            MQTT_BROKER_PORT);

    SupportedUrl_fromString(mqtt_broker, (uint16_t) strlen(mqtt_broker),
            &session_ptr->target);
}

void config_set_connect_data(void) {
    static char *device_name = "XDK110_Guide_Device";
    session_ptr->MQTTVersion = 3;
    session_ptr->keepAliveInterval = 100;
    session_ptr->cleanSession = true;
    session_ptr->will.haveWill = false;

    StringDescr_T device_name_descr;
    StringDescr_wrap(&device_name_descr, device_name);
    session_ptr->clientID = device_name_descr;
}

void config_set_event_handler(void) {
    session_ptr->onMqttEvent = event_handler;
}

retcode_t connect(void) {
    retcode_t rc = RC_INVALID_STATUS;
    rc = Mqtt_connect(session_ptr);
    if (rc != RC_OK) {
        printf("Could not connect, error 0x%04x\n", rc);
    }
    return rc;
}

We declared the main function so we could initialized the application with all the methods that we all ready define.

void appInitSystem(void *CmdProcessorHandle, uint32_t param2) {
    if (CmdProcessorHandle == NULL) {
        printf("Command processor handle is null \n\r");
        assert(false);
    }
    BCDS_UNUSED(param2);

    retcode_t rc = RC_MQTT_NOT_CONNECTED;
    networkSetup();
    rc = init();
    if (rc == RC_OK) {
        config_set_target();
        config_set_connect_data();
        config_set_event_handler();
        connect();
    } else {
        printf("Initialize Failed\n\r");
    }
}
/**@} */
PreviousImplementationNextXDK Live

Last updated 5 years ago

Was this helpful?