David Fletcher
/
cc3100_Test_mqtt_CM4F
TI's MQTT Demo with freertos CM4F
Diff: main.cpp
- Revision:
- 0:1e7b5dd9edb4
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/main.cpp Thu Sep 03 14:07:01 2015 +0000 @@ -0,0 +1,854 @@ +/* + * mqtt_client.c - Sample application to connect to a MQTT broker and + * exercise functionalities like subscribe, publish etc. + * + * Copyright (C) 2014 Texas Instruments Incorporated - http://www.ti.com/ + * + * + * All rights reserved. Property of Texas Instruments Incorporated. + * Restricted rights to use, duplicate or disclose this code are + * granted through contract. + * + * The program may not be used without the written permission of + * Texas Instruments Incorporated or against the terms and conditions + * stipulated in the agreement under which this program has been supplied, + * and under no circumstances can it be used with non-TI connectivity device. + * + * + * Application Name - MQTT Client + * Application Overview - This application acts as a MQTT client and connects + * to the IBM MQTT broker, simultaneously we can + * connect a web client from a web browser. Both + * clients can inter-communicate using appropriate + * topic names. + * + * Application Details - http://processors.wiki.ti.com/index.php/CC31xx_MQTT_Client + * docs\examples\mqtt_client.pdf + * + */ + +/* + * + *! \addtogroup mqtt_client + *! @{ + * + */ + +/* Standard includes */ +#include "mbed.h" + +#include "simplelink/cc3100_simplelink.h" +#include "simplelink/cc3100_sl_common.h" +#include "simplelink/G_functions/fPtr_func.h" +#include "simplelink/cc3100.h" + +#include "myBoardInit.h" + +/* Free-RTOS includes */ +#include "FreeRTOS.h" +#include "task.h" +#include "semphr.h" +#include "portmacro.h" + +#include "osi.h" + +#include <stdio.h> +#include <stdlib.h> + +#include "mqtt_client.h" +#include "sl_mqtt_client.h" +#include "mqtt_config.h" + +#include "cli_uart.h" + +using namespace mbed_cc3100; +using namespace mbed_mqtt; + +int32_t demo = 0; + +/* Warning Changing pins below you will need the same changes in the following files: + * + * sl_mqtt_client.cpp + * cc31xx_sl_net.cpp + * fPtr_func.cpp + */ + +#if (THIS_BOARD == EA_MBED_LPC4088) +//Serial pc(USBTX, USBRX);//EA_lpc4088 + DigitalOut led1(LED1); + DigitalOut led2(LED2); + DigitalOut led3(LED3); + DigitalOut led4(LED4); +cc3100 _cc3100(p14, p15, p9, p10, p8, SPI(p5, p6, p7));//LPC4088 irq, nHib, cs, mosi, miso, sck +#elif (THIS_BOARD == Seeed_Arch_Max) +/* Off board leds */ + DigitalOut led1(PB_15); + DigitalOut led2(PB_14); +cc3100 _cc3100(PB_9, PB_8, PD_12, PD_13, PD_11, SPI(PB_5, PB_4, PB_3));//Seeed_Arch_Max irq, nHib, cs, mosi, miso, sck +#elif (THIS_BOARD == LPCXpresso4337) +Serial pc(UART0_TX, UART0_RX); +cc3100 _cc3100(P2_2, P3_5, P1_2, SPI(P1_4, P1_3, PF_4));//LPCXpresso4337 irq, nHib, cs, mosi, miso, sck +#else + +#endif + +#define APPLICATION_VERSION "1.1.0" +#define SL_STOP_TIMEOUT 0xFF + +#undef LOOP_FOREVER +#define LOOP_FOREVER() \ + {\ + while(1) \ + { \ + osi_Sleep(10); \ + } \ + } + + +#define PRINT_BUF_LEN 128 +int8_t print_buf[PRINT_BUF_LEN]; + +/* Application specific data types */ +typedef struct connection_config +{ + SlMqttClientCtxCfg_t broker_config; + void *clt_ctx; + const char *client_id; + uint8_t *usr_name; + uint8_t *usr_pwd; + bool is_clean; + uint32_t keep_alive_time; + SlMqttClientCbs_t CallBAcks; + int32_t num_topics; + char *topic[SUB_TOPIC_COUNT]; + uint8_t qos[SUB_TOPIC_COUNT]; + SlMqttWill_t will_params; + bool is_connected; +} connect_config; + +/* + * GLOBAL VARIABLES -- Start + */ +uint32_t g_publishCount = 0; +OsiMsgQ_t g_PBQueue; /*Message Queue*/ + +/* + * GLOBAL VARIABLES -- End + */ + +/* + * STATIC FUNCTION DEFINITIONS -- Start + */ +static void displayBanner(void); +static void Mqtt_Recv(void *application_hndl, const char *topstr, int32_t top_len, + const void *payload, int32_t pay_len, bool dup,uint8_t qos, bool retain); +static void sl_MqttEvt(void *application_hndl,int32_t evt, const void *buf, uint32_t len); +static void sl_MqttDisconnect(void *application_hndl); +static int32_t Dummy(const char *inBuff, ...); +static void MqttClient(void *pvParameters); +void buttonHandler_1(void); +void buttonHandler_2(void); +void toggleLed(int ind); +void initLEDs(void); +namespace mbed_cc3100 { +void stackDump(uint32_t stack[]); +} +void printErrorMsg(const char *errMsg); + +/* + * STATIC FUNCTION DEFINITIONS -- End + */ + +/* + * APPLICATION SPECIFIC DATA -- Start + */ +/* Connection configuration */ +connect_config usr_connect_config[] = +{ + { + { + { + SL_MQTT_NETCONN_URL, + SERVER_ADDRESS, + PORT_NUMBER, + 0, + 0, + 0, + NULL + }, + SERVER_MODE, + true, + }, + NULL, + "user007", +// CLIENT_ID, /* Must be unique */ + NULL, + NULL, + true, + KEEP_ALIVE_TIMER, + {&Mqtt_Recv, &sl_MqttEvt, &sl_MqttDisconnect}, + SUB_TOPIC_COUNT, + {SUB_TOPIC1, SUB_TOPIC2}, + {QOS2, QOS2}, + {WILL_TOPIC, WILL_MSG, WILL_QOS, WILL_RETAIN}, + false + } +}; + +/* library configuration */ +SlMqttClientLibCfg_t Mqtt_Client = +{ + LOOPBACK_PORT_NUMBER, + TASK_PRIORITY, + RCV_TIMEOUT, + true, + (int32_t(*)(const char *, ...))Dummy +}; + +void initLEDs(void){ + +#if (THIS_BOARD == EA_MBED_LPC4088) + led1 = 1; + led2 = 1; + led3 = 0; + led4 = 0; +#elif (THIS_BOARD == Seeed_Arch_Max) +/* Off board leds */ + led1 = 0; + led2 = 0; +#endif + +} + +void toggleLed(int ind){ + + if(ind == 1){ + led1 = !led1; + } + if(ind == 2){ + led2 = !led2; + } + +} + +/*Publishing topics and messages*/ +const char *pub_topic_1 = PUB_TOPIC_1; +const char *pub_topic_2 = PUB_TOPIC_2; +const char *data_1={"Push button s1 is pressed: Data 1"}; +const char *data_2={"Push button s2 is pressed: Data 2"}; +void *g_application_hndl = (void*)usr_connect_config; +/* + * APPLICATION SPECIFIC DATA -- End + */ + +/*Dummy print message*/ +static int32_t Dummy(const char *inBuff, ...) +{ + return 0; +} + +/*! + \brief Defines Mqtt_Pub_Message_Receive event handler. + Client App needs to register this event handler with sl_ExtLib_mqtt_Init + API. Background receive task invokes this handler whenever MQTT Client + receives a Publish Message from the broker. + + \param[out] topstr => pointer to topic of the message + \param[out] top_len => topic length + \param[out] payload => pointer to payload + \param[out] pay_len => payload length + \param[out] retain => Tells whether its a Retained message or not + \param[out] dup => Tells whether its a duplicate message or not + \param[out] qos => Tells the Qos level + + \return none + */ +static void +Mqtt_Recv(void *application_hndl, const char *topstr, int32_t top_len, const void *payload, + int32_t pay_len, bool dup,uint8_t qos, bool retain) +{ + int8_t *output_str=(int8_t*)malloc(top_len+1); + memset(output_str,'\0',top_len+1); + strncpy((char*)output_str, topstr, top_len); + output_str[top_len]='\0'; + + if(strncmp((char*)output_str, SUB_TOPIC1, top_len) == 0) + { + toggleLed(1); + } + else if(strncmp((char*)output_str, SUB_TOPIC2, top_len) == 0) + { + toggleLed(2); + } + + Uart_Write((uint8_t*)"\n\r Publish Message Received\r\n"); + + memset(print_buf, 0x00, PRINT_BUF_LEN); + sprintf((char*) print_buf, "\n\r Topic: %s", output_str); + Uart_Write((uint8_t*)print_buf); Uart_Write((uint8_t*)"\r\n"); + free(output_str); + + memset(print_buf, 0x00, PRINT_BUF_LEN); + sprintf((char*) print_buf, " [Qos: %d] ", qos); + Uart_Write((uint8_t*)print_buf); Uart_Write((uint8_t*)"\r\n"); + + if(retain){ + Uart_Write((uint8_t*)" [Retained]\r\n"); + } + if(dup){ + Uart_Write((uint8_t*)" [Duplicate]\r\n"); + } + output_str=(int8_t*)malloc(pay_len+1); + memset(output_str,'\0',pay_len+1); + strncpy((char*)output_str, (const char*)payload, pay_len); + output_str[pay_len]='\0'; + + memset(print_buf, 0x00, PRINT_BUF_LEN); + sprintf((char*) print_buf, " \n\r Data is: %s\n\r", (char*)output_str); + Uart_Write((uint8_t*)print_buf); Uart_Write((uint8_t*)"\r\n"); + + free(output_str); + + return; +} + +/*! + \brief Defines sl_MqttEvt event handler. + Client App needs to register this event handler with sl_ExtLib_mqtt_Init + API. Background receive task invokes this handler whenever MQTT Client + receives an ack(whenever user is in non-blocking mode) or encounters an error. + + \param[out] evt => Event that invokes the handler. Event can be of the + following types: + MQTT_ACK - Ack Received + MQTT_ERROR - unknown error + + + \param[out] buf => points to buffer + \param[out] len => buffer length + + \return none + */ +static void +sl_MqttEvt(void *application_hndl,int32_t evt, const void *buf,uint32_t len) +{ + int32_t i; + + switch(evt) + { + case SL_MQTT_CL_EVT_PUBACK: + { + Uart_Write((uint8_t*)" PubAck:\n\r"); + } + break; + + case SL_MQTT_CL_EVT_SUBACK: + { + Uart_Write((uint8_t*)"\n\r Granted QoS Levels\n\r"); + + for(i=0;i<len;i++) + { + memset(print_buf, 0x00, PRINT_BUF_LEN); + sprintf((char*) print_buf, " QoS %d\n\r",((uint8_t*)buf)[i]); + Uart_Write((uint8_t*)print_buf); Uart_Write((uint8_t*)"\r\n"); + } + } + break; + + case SL_MQTT_CL_EVT_UNSUBACK: + { + Uart_Write((uint8_t*)" UnSub Ack:\n\r"); + } + break; + + default: + { + Uart_Write((uint8_t*)" [MQTT EVENT] Unexpected event \n\r"); + } + break; + } +} + +/*! + + \brief callback event in case of MQTT disconnection + + \param application_hndl is the handle for the disconnected connection + + \return none + +*/ +static void +sl_MqttDisconnect(void *application_hndl) +{ + connect_config *local_con_conf; + osi_messages var = BROKER_DISCONNECTION; + local_con_conf = (connect_config*)application_hndl; + sl_ExtLib_MqttClientUnsub(local_con_conf->clt_ctx, local_con_conf->topic, + SUB_TOPIC_COUNT); + + memset(print_buf, 0x00, PRINT_BUF_LEN); + sprintf((char*) print_buf, " Disconnect from broker %s\r\n", + (local_con_conf->broker_config).server_info.server_addr); + Uart_Write((uint8_t*)print_buf); Uart_Write((uint8_t*)"\r\n"); + + local_con_conf->is_connected = false; + sl_ExtLib_MqttClientCtxDelete(local_con_conf->clt_ctx); + + /* + * Write message indicating publish message + */ + osi_MsgQWrite(&g_PBQueue, &var, OSI_NO_WAIT); +} + +/* + \brief Application defined hook (or callback) function - assert + + \param[in] pcFile - Pointer to the File Name + \param[in] ulLine - Line Number + + \return none +*/ +void vAssertCalled(const int8_t *pcFile, uint32_t ulLine) +{ + /* Handle Assert here */ + while(1) + { + } +} + +/* + + \brief Application defined idle task hook + + \param none + + \return none + + */ +void vApplicationIdleHook(void) +{ + /* Handle Idle Hook for Profiling, Power Management etc */ +} + +/* + + \brief Application defined malloc failed hook + + \param none + + \return none + + */ +void vApplicationMallocFailedHook(void) +{ + /* Handle Memory Allocation Errors */ + while(1) + { + } +} + +/* + + \brief Application defined stack overflow hook + + \param none + + \return none + + */ +void vApplicationStackOverflowHook( OsiTaskHandle *pxTask, + int8_t *pcTaskName ) +{ + /* Handle FreeRTOS Stack Overflow */ + while(1) + { + } +} + +/*! + \brief Publishes the message on a topic. + + \param[in] clt_ctx - Client context + \param[in] publish_topic - Topic on which the message will be published + \param[in] publish_data - The message that will be published + + \return none + */ +static void +publishData(void *clt_ctx, const char *publish_topic, uint8_t *publish_data) +{ +// printf("publishData\n\r"); + int32_t retVal = -1; + + /* + * Send the publish message + */ + retVal = sl_ExtLib_MqttClientSend((void*)clt_ctx, + publish_topic ,publish_data, strlen((const char*)publish_data), QOS2, RETAIN); + if(retVal < 0) + { + Uart_Write((uint8_t*)"\n\r CC3100 failed to publish the message\n\r"); + return; + } + + Uart_Write((uint8_t*)"\n\r CC3100 Publishes the following message \n\r"); + + memset(print_buf, 0x00, PRINT_BUF_LEN); + sprintf((char*) print_buf, " Topic: %s\n\r", publish_topic); + Uart_Write((uint8_t*)print_buf); Uart_Write((uint8_t*)"\r\n"); + + memset(print_buf, 0x00, PRINT_BUF_LEN); + sprintf((char*) print_buf, " Data: %s\n\r", publish_data); + Uart_Write((uint8_t*)print_buf); Uart_Write((uint8_t*)"\r\n"); +} + +/*! + + \brief Task implementing MQTT client communication to other web client through + a broker + + \param none + + This function + 1. Initializes network driver and connects to the default AP + 2. Initializes the mqtt library and set up MQTT connection configurations + 3. set up the button events and their callbacks(for publishing) + 4. handles the callback signals + + \return none + + */ +static void MqttClient(void *pvParameters) +{ + Uart_Write((uint8_t*)"MqttClient\r\n"); + int32_t retVal = -1; + int32_t iCount = 0; + int32_t iNumBroker = 0; + int32_t iConnBroker = 0; + osi_messages RecvQue; + + connect_config *local_con_conf = (connect_config *)g_application_hndl; + + /* Configure LED */ + initLEDs(); + _cc3100._spi.button1_InterruptEnable(); + _cc3100._spi.button2_InterruptEnable(); + +// registerButtonIrqHandler(buttonHandler, NULL); + + /* + * Following function configures the device to default state by cleaning + * the persistent settings stored in NVMEM (viz. connection profiles & + * policies, power policy etc) + * + * Applications may choose to skip this step if the developer is sure + * that the device is in its default state at start of application + * + * Note that all profiles and persistent settings that were done on the + * device will be lost + */ + retVal = _cc3100.configureSimpleLinkToDefaultState(); + if(retVal < 0) + { + if(DEVICE_NOT_IN_STATION_MODE == retVal) + Uart_Write((uint8_t*)" Failed to configure the device in its default state \n\r"); + + LOOP_FOREVER(); + } + + Uart_Write((uint8_t*)" Device is configured in default state \n\r"); + + /* + * Assumption is that the device is configured in station mode already + * and it is in its default state + */ + retVal = _cc3100.sl_Start(0, 0, 0); + if ((retVal < 0) || + (ROLE_STA != retVal) ) + { + Uart_Write((uint8_t*)" Failed to start the device \n\r"); + LOOP_FOREVER(); + } + + Uart_Write((uint8_t*)" Device started as STATION \n\r"); + + /* Connecting to WLAN AP */ + retVal = _cc3100.establishConnectionWithAP(); + if(retVal < 0) + { + Uart_Write((uint8_t*)" Failed to establish connection w/ an AP \n\r"); + LOOP_FOREVER(); + } + + Uart_Write((uint8_t*)"\r\n Connection established with AP\n\r"); + + /* Initialize MQTT client lib */ + retVal = sl_ExtLib_MqttClientInit(&Mqtt_Client); + if(retVal != 0) + { + /* lib initialization failed */ + Uart_Write((uint8_t*)"MQTT Client lib initialization failed\n\r"); + LOOP_FOREVER(); + } +// Uart_Write((uint8_t*)"MQTT Client lib initialized\n\r"); + + /* + * Connection to the broker + */ + iNumBroker = sizeof(usr_connect_config)/sizeof(connect_config); + if(iNumBroker > MAX_BROKER_CONN) + { + Uart_Write((uint8_t*)"Num of brokers are more then max num of brokers\n\r"); + LOOP_FOREVER(); + } + + while(iCount < iNumBroker) + { + /* + * create client context + */ + + local_con_conf[iCount].clt_ctx = + sl_ExtLib_MqttClientCtxCreate(&local_con_conf[iCount].broker_config, + &local_con_conf[iCount].CallBAcks, + &(local_con_conf[iCount])); + + /* + * Set Client ID + */ + sl_ExtLib_MqttClientSet((void*)local_con_conf[iCount].clt_ctx, + SL_MQTT_PARAM_CLIENT_ID, + local_con_conf[iCount].client_id, + strlen((local_con_conf[iCount].client_id))); + + /* + * Set will Params + */ + if(local_con_conf[iCount].will_params.will_topic != NULL) + { + sl_ExtLib_MqttClientSet((void*)local_con_conf[iCount].clt_ctx, + SL_MQTT_PARAM_WILL_PARAM, + &(local_con_conf[iCount].will_params), + sizeof(SlMqttWill_t)); + } + + /* + * Setting user name and password + */ + if(local_con_conf[iCount].usr_name != NULL) + { + sl_ExtLib_MqttClientSet((void*)local_con_conf[iCount].clt_ctx, + SL_MQTT_PARAM_USER_NAME, + local_con_conf[iCount].usr_name, + strlen((const char*)local_con_conf[iCount].usr_name)); + + if(local_con_conf[iCount].usr_pwd != NULL) + { + sl_ExtLib_MqttClientSet((void*)local_con_conf[iCount].clt_ctx, + SL_MQTT_PARAM_PASS_WORD, + local_con_conf[iCount].usr_pwd, + strlen((const char*)local_con_conf[iCount].usr_pwd)); + } + } + + /* + * Connecting to the broker + */ + if((sl_ExtLib_MqttClientConnect((void*)local_con_conf[iCount].clt_ctx, + local_con_conf[iCount].is_clean, + local_con_conf[iCount].keep_alive_time) & 0xFF) != 0) + { + memset(print_buf, 0x00, PRINT_BUF_LEN); + sprintf((char*) print_buf, "\n\r Broker connect failed for conn no. %d \n\r", (int16_t)iCount+1); + Uart_Write((uint8_t*)print_buf); Uart_Write((uint8_t*)"\r\n"); + + /* + * Delete the context for this connection + */ + sl_ExtLib_MqttClientCtxDelete(local_con_conf[iCount].clt_ctx); + + break; + } + else + { + memset(print_buf, 0x00, PRINT_BUF_LEN); + sprintf((char*) print_buf, "\n\r Success: conn to Broker no. %d \n\r ", (int16_t)iCount+1); + Uart_Write((uint8_t*)print_buf); Uart_Write((uint8_t*)"\r\n"); + + local_con_conf[iCount].is_connected = true; + iConnBroker++; + } + + /* + * Subscribe to topics + */ + if(sl_ExtLib_MqttClientSub((void*)local_con_conf[iCount].clt_ctx, + local_con_conf[iCount].topic, + local_con_conf[iCount].qos, SUB_TOPIC_COUNT) < 0) + { + memset(print_buf, 0x00, PRINT_BUF_LEN); + sprintf((char*) print_buf, "\n\r Subscription Error for conn no. %d \n\r", (int16_t)iCount+1); + Uart_Write((uint8_t*)print_buf); Uart_Write((uint8_t*)"\r\n"); + + Uart_Write((uint8_t*)"Disconnecting from the broker\r\n"); + + sl_ExtLib_MqttClientDisconnect(local_con_conf[iCount].clt_ctx); + local_con_conf[iCount].is_connected = false; + + /* + * Delete the context for this connection + */ + sl_ExtLib_MqttClientCtxDelete(local_con_conf[iCount].clt_ctx); + iConnBroker--; + break; + } + else + { + int32_t iSub; + + Uart_Write((uint8_t*)"Client subscribed on following topics:\n\r"); + for(iSub = 0; iSub < local_con_conf[iCount].num_topics; iSub++) + { + memset(print_buf, 0x00, PRINT_BUF_LEN); + sprintf((char*) print_buf, " %s\n\r", local_con_conf[iCount].topic[iSub]); + Uart_Write((uint8_t*)print_buf); Uart_Write((uint8_t*)"\r\n"); + } + } + iCount++; + } + + if(iConnBroker < 1) + { + /* + * No successful connection to broker + + */ + Uart_Write((uint8_t*)"No successful connections to a broker\r\n"); + goto end; + } + + iCount = 0; + + for(;;) + { + Uart_Write((uint8_t*)"Waiting for button push event\r\n"); + osi_MsgQRead( &g_PBQueue, &RecvQue, OSI_WAIT_FOREVER); + + if(PUSH_BUTTON_1_PRESSED == RecvQue) + { + publishData((void*)local_con_conf[iCount].clt_ctx, pub_topic_1, (uint8_t*)data_1); + _cc3100._spi.button1_InterruptEnable(); + } + else if(PUSH_BUTTON_2_PRESSED == RecvQue) + { + publishData((void*)local_con_conf[iCount].clt_ctx, pub_topic_2, (uint8_t*)data_2); + _cc3100._spi.button2_InterruptEnable(); + } + else if(BROKER_DISCONNECTION == RecvQue) + { + iConnBroker--; + if(iConnBroker < 1) + { + /* + * Device not connected to any broker + */ + goto end; + } + } + } + +end: + /* + * De-initializing the client library + */ + sl_ExtLib_MqttClientExit(); + + Uart_Write((uint8_t*)"\n\r Exiting the Application\n\r"); + + LOOP_FOREVER(); +} + + +/* + * Application's entry point + */ +int main(int argc, char** argv) +{ + int rv = 0; + + CLI_Configure(); + + memset(print_buf, 0x00, PRINT_BUF_LEN); + sprintf((char*) print_buf, " \r\nSystemCoreClock = %dMHz\r\n ", SystemCoreClock /1000000); + rv = Uart_Write((uint8_t *) print_buf); + if(rv < 0){ + while(1){ + toggleLed(1); + wait(0.1); + } + } + + int32_t retVal = -1; + + // + // Display Application Banner + // + displayBanner(); + + createMutex(); + + /* + * Start the SimpleLink Host + */ + retVal = VStartSimpleLinkSpawnTask(SPAWN_TASK_PRIORITY); + if(retVal < 0) + { + Uart_Write((uint8_t*)"VStartSimpleLinkSpawnTask Failed\r\n"); + LOOP_FOREVER(); + } + toggleLed(1); + + /* + * Start the MQTT Client task + */ + osi_MsgQCreate(&g_PBQueue,"PBQueue",sizeof(osi_messages),MAX_QUEUE_MSG); + retVal = osi_TaskCreate(MqttClient, + (const int8_t *)"Mqtt Client App", + OSI_STACK_SIZE, NULL, MQTT_APP_TASK_PRIORITY, NULL ); + + if(retVal < 0) + { + Uart_Write((uint8_t*)"osi_TaskCreate Failed\r\n"); + LOOP_FOREVER(); + } + + /* + * Start the task scheduler + */ + Uart_Write((uint8_t*)"Start the task scheduler\r\n"); + + osi_start(); + + return 0; +} + +/*! + \brief This function displays the application's banner + + \param None + + \return None +*/ +static void displayBanner() +{ + Uart_Write((uint8_t*)"\r\n"); + Uart_Write((uint8_t*)" *************************************************\r\n"); + Uart_Write((uint8_t*)" MQTT Client Application - Version\r\n"); + Uart_Write((uint8_t*)" *************************************************\r\n"); + Uart_Write((uint8_t*)"\r\n"); +} + + + +