Webserver+3d print

Dependents:   Nucleo

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers main.c Source File

main.c

00001 /**
00002  * @file main.c
00003  * @brief Main routine
00004  *
00005  * @section License
00006  *
00007  * Copyright (C) 2010-2017 Oryx Embedded SARL. All rights reserved.
00008  *
00009  * This program is free software; you can redistribute it and/or
00010  * modify it under the terms of the GNU General Public License
00011  * as published by the Free Software Foundation; either version 2
00012  * of the License, or (at your option) any later version.
00013  *
00014  * This program is distributed in the hope that it will be useful,
00015  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00016  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00017  * GNU General Public License for more details.
00018  *
00019  * You should have received a copy of the GNU General Public License
00020  * along with this program; if not, write to the Free Software Foundation,
00021  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
00022  *
00023  * @author Oryx Embedded SARL (www.oryx-embedded.com)
00024  * @version 1.7.6
00025  **/
00026 
00027 //Dependencies
00028 #include <stdlib.h>
00029 #include "stm32f7xx.h"
00030 #include "stm32f7xx_hal.h"
00031 #include "stm32f7xx_nucleo_144.h"
00032 #include "os_port.h"
00033 #include "core/net.h"
00034 #include "drivers/stm32f7xx_eth.h"
00035 #include "drivers/lan8742.h"
00036 #include "dhcp/dhcp_client.h"
00037 #include "ipv6/slaac.h"
00038 #include "mqtt/mqtt_client.h"
00039 #include "yarrow.h"
00040 #include "debug.h"
00041 
00042 //Application configuration
00043 #define APP_MAC_ADDR "00-AB-CD-EF-07-46"
00044 
00045 #define APP_USE_DHCP ENABLED
00046 #define APP_IPV4_HOST_ADDR "192.168.0.20"
00047 #define APP_IPV4_SUBNET_MASK "255.255.255.0"
00048 #define APP_IPV4_DEFAULT_GATEWAY "192.168.0.254"
00049 #define APP_IPV4_PRIMARY_DNS "8.8.8.8"
00050 #define APP_IPV4_SECONDARY_DNS "8.8.4.4"
00051 
00052 #define APP_USE_SLAAC ENABLED
00053 #define APP_IPV6_LINK_LOCAL_ADDR "fe80::746"
00054 #define APP_IPV6_PREFIX "2001:db8::"
00055 #define APP_IPV6_PREFIX_LENGTH 64
00056 #define APP_IPV6_GLOBAL_ADDR "2001:db8::746"
00057 #define APP_IPV6_ROUTER "fe80::1"
00058 #define APP_IPV6_PRIMARY_DNS "2001:4860:4860::8888"
00059 #define APP_IPV6_SECONDARY_DNS "2001:4860:4860::8844"
00060 
00061 //MQTT server name
00062 #define APP_SERVER_NAME "iot.eclipse.org"
00063 
00064 //MQTT server port
00065 #define APP_SERVER_PORT 1883   //MQTT over TCP
00066 //#define APP_SERVER_PORT 8883 //MQTT over SSL/TLS
00067 //#define APP_SERVER_PORT 80   //MQTT over WebSocket
00068 //#define APP_SERVER_PORT 443  //MQTT over secure WebSocket
00069 
00070 //URI (for MQTT over WebSocket only)
00071 #define APP_SERVER_URI "/ws"
00072 
00073 //List of trusted CA certificates
00074 char_t trustedCaList[] =
00075    "-----BEGIN CERTIFICATE-----"
00076    "MIIDSjCCAjKgAwIBAgIQRK+wgNajJ7qJMDmGLvhAazANBgkqhkiG9w0BAQUFADA/"
00077    "MSQwIgYDVQQKExtEaWdpdGFsIFNpZ25hdHVyZSBUcnVzdCBDby4xFzAVBgNVBAMT"
00078    "DkRTVCBSb290IENBIFgzMB4XDTAwMDkzMDIxMTIxOVoXDTIxMDkzMDE0MDExNVow"
00079    "PzEkMCIGA1UEChMbRGlnaXRhbCBTaWduYXR1cmUgVHJ1c3QgQ28uMRcwFQYDVQQD"
00080    "Ew5EU1QgUm9vdCBDQSBYMzCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEB"
00081    "AN+v6ZdQCINXtMxiZfaQguzH0yxrMMpb7NnDfcdAwRgUi+DoM3ZJKuM/IUmTrE4O"
00082    "rz5Iy2Xu/NMhD2XSKtkyj4zl93ewEnu1lcCJo6m67XMuegwGMoOifooUMM0RoOEq"
00083    "OLl5CjH9UL2AZd+3UWODyOKIYepLYYHsUmu5ouJLGiifSKOeDNoJjj4XLh7dIN9b"
00084    "xiqKqy69cK3FCxolkHRyxXtqqzTWMIn/5WgTe1QLyNau7Fqckh49ZLOMxt+/yUFw"
00085    "7BZy1SbsOFU5Q9D8/RhcQPGX69Wam40dutolucbY38EVAjqr2m7xPi71XAicPNaD"
00086    "aeQQmxkqtilX4+U9m5/wAl0CAwEAAaNCMEAwDwYDVR0TAQH/BAUwAwEB/zAOBgNV"
00087    "HQ8BAf8EBAMCAQYwHQYDVR0OBBYEFMSnsaR7LHH62+FLkHX/xBVghYkQMA0GCSqG"
00088    "SIb3DQEBBQUAA4IBAQCjGiybFwBcqR7uKGY3Or+Dxz9LwwmglSBd49lZRNI+DT69"
00089    "ikugdB/OEIKcdBodfpga3csTS7MgROSR6cz8faXbauX+5v3gTt23ADq1cEmv8uXr"
00090    "AvHRAosZy5Q6XkjEGB5YGV8eAlrwDPGxrancWYaLbumR9YbK+rlmM6pZW87ipxZz"
00091    "R8srzJmwN0jP41ZL9c8PDHIyh8bwRLtTcm1D9SZImlJnt1ir/md2cXjbDaJWFBM5"
00092    "JDGFoqgCWjBH4d1QB7wCCZAA62RjYJsWvIjJEubSfZGL+T0yjWW06XyxV3bqxbYo"
00093    "Ob8VZRzI9neWagqNdwvYkQsEjgfbKbYK7p2CNTUQ"
00094    "-----END CERTIFICATE-----";
00095 
00096 //Connection states
00097 #define APP_STATE_NOT_CONNECTED 0
00098 #define APP_STATE_CONNECTING    1
00099 #define APP_STATE_CONNECTED     2
00100 
00101 //Global variables
00102 uint_t connectionState = APP_STATE_NOT_CONNECTED;
00103 
00104 RNG_HandleTypeDef RNG_Handle;
00105 
00106 DhcpClientSettings dhcpClientSettings;
00107 DhcpClientContext dhcpClientContext;
00108 SlaacSettings slaacSettings;
00109 SlaacContext slaacContext;
00110 MqttClientContext mqttClientContext;
00111 YarrowContext yarrowContext;
00112 uint8_t seed[32];
00113 
00114 
00115 /**
00116  * @brief System clock configuration
00117  **/
00118 
00119 void SystemClock_Config(void)
00120 {
00121    RCC_OscInitTypeDef RCC_OscInitStruct;
00122    RCC_ClkInitTypeDef RCC_ClkInitStruct;
00123 
00124    //Enable Power Control clock
00125    __HAL_RCC_PWR_CLK_ENABLE();
00126 
00127    //Enable HSE Oscillator and activate PLL with HSE as source
00128    RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSE;
00129    RCC_OscInitStruct.HSEState = RCC_HSE_BYPASS;
00130    RCC_OscInitStruct.HSIState = RCC_HSI_OFF;
00131    RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON;
00132    RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSE;
00133    RCC_OscInitStruct.PLL.PLLM = 8;
00134    RCC_OscInitStruct.PLL.PLLN = 432;
00135    RCC_OscInitStruct.PLL.PLLP = RCC_PLLP_DIV2;
00136    RCC_OscInitStruct.PLL.PLLQ = 9;
00137    HAL_RCC_OscConfig(&RCC_OscInitStruct);
00138 
00139    //Enable overdrive mode
00140    HAL_PWREx_EnableOverDrive();
00141 
00142    //Select PLL as system clock source and configure the HCLK, PCLK1 and PCLK2
00143    //clocks dividers
00144    RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_SYSCLK | RCC_CLOCKTYPE_HCLK | RCC_CLOCKTYPE_PCLK1 | RCC_CLOCKTYPE_PCLK2;
00145    RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK;
00146    RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1;
00147    RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV4;
00148    RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV2;
00149    HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_7);
00150 }
00151 
00152 
00153 /**
00154  * @brief MPU configuration
00155  **/
00156 
00157 void MPU_Config(void)
00158 {
00159    MPU_Region_InitTypeDef MPU_InitStruct;
00160 
00161    //Disable MPU
00162    HAL_MPU_Disable();
00163 
00164    //SRAM
00165    MPU_InitStruct.Enable = MPU_REGION_ENABLE;
00166    MPU_InitStruct.Number = MPU_REGION_NUMBER0;
00167    MPU_InitStruct.BaseAddress = 0x20000000;
00168    MPU_InitStruct.Size = MPU_REGION_SIZE_512KB;
00169    MPU_InitStruct.SubRegionDisable = 0;
00170    MPU_InitStruct.TypeExtField = MPU_TEX_LEVEL0;
00171    MPU_InitStruct.AccessPermission = MPU_REGION_FULL_ACCESS;
00172    MPU_InitStruct.DisableExec = MPU_INSTRUCTION_ACCESS_ENABLE;
00173    MPU_InitStruct.IsShareable = MPU_ACCESS_SHAREABLE;
00174    MPU_InitStruct.IsCacheable = MPU_ACCESS_CACHEABLE;
00175    MPU_InitStruct.IsBufferable = MPU_ACCESS_NOT_BUFFERABLE;
00176    HAL_MPU_ConfigRegion(&MPU_InitStruct);
00177 
00178    //SRAM2
00179    MPU_InitStruct.Enable = MPU_REGION_ENABLE;
00180    MPU_InitStruct.Number = MPU_REGION_NUMBER1;
00181    MPU_InitStruct.BaseAddress = 0x2004C000;
00182    MPU_InitStruct.Size = MPU_REGION_SIZE_16KB;
00183    MPU_InitStruct.SubRegionDisable = 0;
00184    MPU_InitStruct.TypeExtField = MPU_TEX_LEVEL0;
00185    MPU_InitStruct.AccessPermission = MPU_REGION_FULL_ACCESS;
00186    MPU_InitStruct.DisableExec = MPU_INSTRUCTION_ACCESS_ENABLE;
00187    MPU_InitStruct.IsShareable = MPU_ACCESS_SHAREABLE;
00188    MPU_InitStruct.IsCacheable = MPU_ACCESS_NOT_CACHEABLE;
00189    MPU_InitStruct.IsBufferable = MPU_ACCESS_NOT_BUFFERABLE;
00190    HAL_MPU_ConfigRegion(&MPU_InitStruct);
00191 
00192    //Enable MPU
00193    HAL_MPU_Enable(MPU_PRIVILEGED_DEFAULT);
00194 }
00195 
00196 
00197 /**
00198  * @brief Random data generation callback function
00199  * @param[out] data Buffer where to store the random data
00200  * @param[in] lenght Number of bytes that are required
00201  * @return Error code
00202  **/
00203 
00204 error_t webSocketRngCallback(uint8_t *data, size_t length)
00205 {
00206    //Generate some random data
00207    return yarrowRead(&yarrowContext, data, length);
00208 }
00209 
00210 
00211 /**
00212  * @brief SSL/TLS initialization callback
00213  * @param[in] context Pointer to the FTP client context
00214  * @param[in] tlsContext Pointer to the SSL/TLS context
00215  * @return Error code
00216  **/
00217 
00218 error_t mqttTlsInitCallback(MqttClientContext *context,
00219    TlsContext *tlsContext)
00220 {
00221    error_t error;
00222 
00223    //Debug message
00224    TRACE_INFO("MQTT: TLS initialization callback\r\n");
00225 
00226    //Set the PRNG algorithm to be used
00227    error = tlsSetPrng(tlsContext, YARROW_PRNG_ALGO, &yarrowContext);
00228    //Any error to report?
00229    if(error)
00230       return error;
00231 
00232    //Set the fully qualified domain name of the server
00233    error = tlsSetServerName(tlsContext, APP_SERVER_NAME);
00234    //Any error to report?
00235    if(error)
00236       return error;
00237 
00238    //Import the list of trusted CA certificates
00239    error = tlsSetTrustedCaList(tlsContext, trustedCaList, strlen(trustedCaList));
00240    //Any error to report?
00241    if(error)
00242       return error;
00243 
00244    //Successful processing
00245    return NO_ERROR;
00246 }
00247 
00248 
00249 /**
00250  * @brief Publish callback function
00251  * @param[in] context Pointer to the MQTT client context
00252  * @param[in] topic Topic name
00253  * @param[in] message Message payload
00254  * @param[in] length Length of the message payload
00255  * @param[in] dup Duplicate delivery of the PUBLISH packet
00256  * @param[in] qos QoS level used to publish the message
00257  * @param[in] retain This flag specifies if the message is to be retained
00258  * @param[in] packetId Packet identifier
00259  **/
00260 
00261 void mqttPublishCallback(MqttClientContext *context,
00262    const char_t *topic, const uint8_t *message, size_t length,
00263    bool_t dup, MqttQosLevel qos, bool_t retain, uint16_t packetId)
00264 {
00265    //Debug message
00266    TRACE_INFO("PUBLISH packet received...\r\n");
00267    TRACE_INFO("  Dup: %u\r\n", dup);
00268    TRACE_INFO("  QoS: %u\r\n", qos);
00269    TRACE_INFO("  Retain: %u\r\n", retain);
00270    TRACE_INFO("  Packet Identifier: %u\r\n", packetId);
00271    TRACE_INFO("  Topic: %s\r\n", topic);
00272    TRACE_INFO("  Message (%" PRIuSIZE " bytes):\r\n", length);
00273    TRACE_INFO_ARRAY("    ", message, length);
00274 
00275    //Check topic name
00276    if(!strcmp(topic, "board/leds/1"))
00277    {
00278       if(length == 6 && !strncasecmp((char_t *) message, "toggle", 6))
00279          BSP_LED_Toggle(LED2);
00280       else if(length == 2 && !strncasecmp((char_t *) message, "on", 2))
00281          BSP_LED_On(LED2);
00282       else
00283          BSP_LED_Off(LED2);
00284    }
00285    else if(!strcmp(topic, "board/leds/2"))
00286    {
00287       if(length == 6 && !strncasecmp((char_t *) message, "toggle", 6))
00288          BSP_LED_Toggle(LED3);
00289       else if(length == 2 && !strncasecmp((char_t *) message, "on", 2))
00290          BSP_LED_On(LED3);
00291       else
00292          BSP_LED_Off(LED3);
00293    }
00294 }
00295 
00296 
00297 /**
00298  * @brief Establish MQTT connection
00299  **/
00300 
00301 error_t mqttConnect(void)
00302 {
00303    error_t error;
00304    IpAddr ipAddr;
00305    MqttClientCallbacks mqttClientCallbacks;
00306 
00307    //Debug message
00308    TRACE_INFO("\r\n\r\nResolving server name...\r\n");
00309 
00310    //Resolve MQTT server name
00311    error = getHostByName(NULL, APP_SERVER_NAME, &ipAddr, 0);
00312    //Any error to report?
00313    if(error)
00314       return error;
00315 
00316 #if (APP_SERVER_PORT == 80 || APP_SERVER_PORT == 443)
00317    //Register RNG callback
00318    webSocketRegisterRandCallback(webSocketRngCallback);
00319 #endif
00320 
00321    //Initialize MQTT client context
00322    mqttClientInit(&mqttClientContext);
00323    //Initialize MQTT client callbacks
00324    mqttClientInitCallbacks(&mqttClientCallbacks);
00325 
00326    //Attach application-specific callback functions
00327    mqttClientCallbacks.publishCallback = mqttPublishCallback;
00328 #if (APP_SERVER_PORT == 8883 || APP_SERVER_PORT == 443)
00329    mqttClientCallbacks.tlsInitCallback = mqttTlsInitCallback;
00330 #endif
00331 
00332    //Register MQTT client callbacks
00333    mqttClientRegisterCallbacks(&mqttClientContext, &mqttClientCallbacks);
00334 
00335    //Set the MQTT version to be used
00336    mqttClientSetProtocolLevel(&mqttClientContext,
00337       MQTT_PROTOCOL_LEVEL_3_1_1);
00338 
00339 #if (APP_SERVER_PORT == 1883)
00340    //MQTT over TCP
00341    mqttClientSetTransportProtocol(&mqttClientContext, MQTT_TRANSPORT_PROTOCOL_TCP);
00342 #elif (APP_SERVER_PORT == 8883)
00343    //MQTT over SSL/TLS
00344    mqttClientSetTransportProtocol(&mqttClientContext, MQTT_TRANSPORT_PROTOCOL_TLS);
00345 #elif (APP_SERVER_PORT == 80)
00346    //MQTT over WebSocket
00347    mqttClientSetTransportProtocol(&mqttClientContext, MQTT_TRANSPORT_PROTOCOL_WS);
00348 #elif (APP_SERVER_PORT == 443)
00349    //MQTT over secure WebSocket
00350    mqttClientSetTransportProtocol(&mqttClientContext, MQTT_TRANSPORT_PROTOCOL_WSS);
00351 #endif
00352 
00353    //Set keep-alive value
00354    mqttClientSetKeepAlive(&mqttClientContext, 3600);
00355 
00356 #if (APP_SERVER_PORT == 80 || APP_SERVER_PORT == 443)
00357    //Set the hostname of the resource being requested
00358    mqttClientSetHost(&mqttClientContext, APP_SERVER_NAME);
00359    //Set the name of the resource being requested
00360    mqttClientSetUri(&mqttClientContext, APP_SERVER_URI);
00361 #endif
00362 
00363    //Set client identifier
00364    //mqttClientSetIdentifier(&mqttClientContext, "client12345678");
00365 
00366    //Set user name and password
00367    //mqttClientSetAuthInfo(&mqttClientContext, "username", "password");
00368 
00369    //Set Will message
00370    mqttClientSetWillMessage(&mqttClientContext, "board/status",
00371       "offline", 7, MQTT_QOS_LEVEL_0, FALSE);
00372 
00373    //Debug message
00374    TRACE_INFO("Connecting to MQTT server %s...\r\n", ipAddrToString(&ipAddr, NULL));
00375 
00376    //Start of exception handling block
00377    do
00378    {
00379       //Establish connection with the MQTT server
00380       error = mqttClientConnect(&mqttClientContext,
00381          &ipAddr, APP_SERVER_PORT, TRUE);
00382       //Any error to report
00383       if(error)
00384          break;
00385 
00386       //Subscribe to the desired topics
00387       error = mqttClientSubscribe(&mqttClientContext,
00388          "board/leds/+", MQTT_QOS_LEVEL_1, NULL);
00389       //Any error to report
00390       if(error)
00391          break;
00392 
00393       //Send PUBLISH packet
00394       error = mqttClientPublish(&mqttClientContext, "board/status",
00395          "online", 6, MQTT_QOS_LEVEL_1, TRUE, NULL);
00396       //Any error to report
00397       if(error)
00398          break;
00399 
00400       //End of exception handling block
00401    } while(0);
00402 
00403    //Check status code
00404    if(error)
00405    {
00406       //Close connection
00407       mqttClientClose(&mqttClientContext);
00408    }
00409 
00410    //Return status code
00411    return error;
00412 }
00413 
00414 
00415 /**
00416  * @brief MQTT test task
00417  **/
00418 
00419 void mqttTestTask(void *param)
00420 {
00421    error_t error;
00422    uint_t buttonState;
00423    uint_t prevButtonState;
00424    char_t buffer[16];
00425 
00426    //Initialize variables
00427    prevButtonState = 0;
00428 
00429    //Endless loop
00430    while(1)
00431    {
00432       //Check connection state
00433       if(connectionState == APP_STATE_NOT_CONNECTED)
00434       {
00435          //Update connection state
00436          connectionState = APP_STATE_CONNECTING;
00437 
00438          //Try to connect to the MQTT server
00439          error = mqttConnect();
00440 
00441          //Failed to connect to the MQTT server?
00442          if(error)
00443          {
00444             //Update connection state
00445             connectionState = APP_STATE_NOT_CONNECTED;
00446             //Recovery delay
00447             osDelayTask(2000);
00448          }
00449          else
00450          {
00451             //Update connection state
00452             connectionState = APP_STATE_CONNECTED;
00453          }
00454       }
00455       else
00456       {
00457          //Process incoming events
00458          error = mqttClientProcessEvents(&mqttClientContext, 100);
00459 
00460          //Connection to MQTT server lost?
00461          if(error != NO_ERROR && error != ERROR_TIMEOUT)
00462          {
00463             //Close connection
00464             mqttClientClose(&mqttClientContext);
00465             //Update connection state
00466             connectionState = APP_STATE_NOT_CONNECTED;
00467             //Recovery delay
00468             osDelayTask(2000);
00469          }
00470          else
00471          {
00472             //Initialize status code
00473             error = NO_ERROR;
00474 
00475             //Get user button state
00476             buttonState = BSP_PB_GetState(BUTTON_KEY);
00477 
00478             //Any change detected?
00479             if(buttonState != prevButtonState)
00480             {
00481                if(buttonState)
00482                   strcpy(buffer, "pressed");
00483                else
00484                   strcpy(buffer, "released");
00485 
00486                //Send PUBLISH packet
00487                error = mqttClientPublish(&mqttClientContext, "board/buttons/1",
00488                   buffer, strlen(buffer), MQTT_QOS_LEVEL_1, TRUE, NULL);
00489 
00490                //Save current state
00491                prevButtonState = buttonState;
00492             }
00493 
00494             //Failed to publish data?
00495             if(error)
00496             {
00497                //Close connection
00498                mqttClientClose(&mqttClientContext);
00499                //Update connection state
00500                connectionState = APP_STATE_NOT_CONNECTED;
00501                //Recovery delay
00502                osDelayTask(2000);
00503             }
00504          }
00505       }
00506    }
00507 }
00508 
00509 
00510 /**
00511  * @brief LED blinking task
00512  **/
00513 
00514 void blinkTask(void *param)
00515 {
00516    //Endless loop
00517    while(1)
00518    {
00519       BSP_LED_On(LED1);
00520       osDelayTask(100);
00521       BSP_LED_Off(LED1);
00522       osDelayTask(900);
00523    }
00524 }
00525 
00526 
00527 /**
00528  * @brief Main entry point
00529  * @return Unused value
00530  **/
00531 
00532 int_t main(void)
00533 {
00534    error_t error;
00535    uint_t i;
00536    uint32_t value;
00537    NetInterface *interface;
00538    OsTask *task;
00539    MacAddr macAddr;
00540 #if (APP_USE_DHCP == DISABLED)
00541    Ipv4Addr ipv4Addr;
00542 #endif
00543 #if (APP_USE_SLAAC == DISABLED)
00544    Ipv6Addr ipv6Addr;
00545 #endif
00546 
00547    //MPU configuration
00548    MPU_Config();
00549    //HAL library initialization
00550    HAL_Init();
00551    //Configure the system clock
00552    SystemClock_Config();
00553 
00554    //Enable I-cache and D-cache
00555    SCB_EnableICache();
00556    SCB_EnableDCache();
00557 
00558    //Initialize kernel
00559    osInitKernel();
00560    //Configure debug UART
00561    debugInit(115200);
00562 
00563    //Start-up message
00564    TRACE_INFO("\r\n");
00565    TRACE_INFO("***********************************\r\n");
00566    TRACE_INFO("*** CycloneTCP MQTT Client Demo ***\r\n");
00567    TRACE_INFO("***********************************\r\n");
00568    TRACE_INFO("Copyright: 2010-2017 Oryx Embedded SARL\r\n");
00569    TRACE_INFO("Compiled: %s %s\r\n", __DATE__, __TIME__);
00570    TRACE_INFO("Target: STM32F746\r\n");
00571    TRACE_INFO("\r\n");
00572 
00573    //LED configuration
00574    BSP_LED_Init(LED1);
00575    BSP_LED_Init(LED2);
00576    BSP_LED_Init(LED3);
00577 
00578    //Clear LEDs
00579    BSP_LED_Off(LED1);
00580    BSP_LED_Off(LED2);
00581    BSP_LED_Off(LED3);
00582 
00583    //Initialize user button
00584    BSP_PB_Init(BUTTON_KEY, BUTTON_MODE_GPIO);
00585 
00586    //Enable RNG peripheral clock
00587    __HAL_RCC_RNG_CLK_ENABLE();
00588    //Initialize RNG
00589    RNG_Handle.Instance = RNG;
00590    HAL_RNG_Init(&RNG_Handle);
00591 
00592    //Generate a random seed
00593    for(i = 0; i < 32; i += 4)
00594    {
00595       //Get 32-bit random value
00596       HAL_RNG_GenerateRandomNumber(&RNG_Handle, &value);
00597 
00598       //Copy random value
00599       seed[i] = value & 0xFF;
00600       seed[i + 1] = (value >> 8) & 0xFF;
00601       seed[i + 2] = (value >> 16) & 0xFF;
00602       seed[i + 3] = (value >> 24) & 0xFF;
00603    }
00604 
00605    //PRNG initialization
00606    error = yarrowInit(&yarrowContext);
00607    //Any error to report?
00608    if(error)
00609    {
00610       //Debug message
00611       TRACE_ERROR("Failed to initialize PRNG!\r\n");
00612    }
00613 
00614    //Properly seed the PRNG
00615    error = yarrowSeed(&yarrowContext, seed, sizeof(seed));
00616    //Any error to report?
00617    if(error)
00618    {
00619       //Debug message
00620       TRACE_ERROR("Failed to seed PRNG!\r\n");
00621    }
00622 
00623    //TCP/IP stack initialization
00624    error = netInit();
00625    //Any error to report?
00626    if(error)
00627    {
00628       //Debug message
00629       TRACE_ERROR("Failed to initialize TCP/IP stack!\r\n");
00630    }
00631 
00632    //Configure the first Ethernet interface
00633    interface = &netInterface[0];
00634 
00635    //Set interface name
00636    netSetInterfaceName(interface, "eth0");
00637    //Set host name
00638    netSetHostname(interface, "MQTTClientDemo");
00639    //Select the relevant network adapter
00640    netSetDriver(interface, &stm32f7xxEthDriver);
00641    netSetPhyDriver(interface, &lan8742PhyDriver);
00642    //Set host MAC address
00643    macStringToAddr(APP_MAC_ADDR, &macAddr);
00644    netSetMacAddr(interface, &macAddr);
00645 
00646    //Initialize network interface
00647    error = netConfigInterface(interface);
00648    //Any error to report?
00649    if(error)
00650    {
00651       //Debug message
00652       TRACE_ERROR("Failed to configure interface %s!\r\n", interface->name);
00653    }
00654 
00655 #if (IPV4_SUPPORT == ENABLED)
00656 #if (APP_USE_DHCP == ENABLED)
00657    //Get default settings
00658    dhcpClientGetDefaultSettings(&dhcpClientSettings);
00659    //Set the network interface to be configured by DHCP
00660    dhcpClientSettings.interface = interface;
00661    //Disable rapid commit option
00662    dhcpClientSettings.rapidCommit = FALSE;
00663 
00664    //DHCP client initialization
00665    error = dhcpClientInit(&dhcpClientContext, &dhcpClientSettings);
00666    //Failed to initialize DHCP client?
00667    if(error)
00668    {
00669       //Debug message
00670       TRACE_ERROR("Failed to initialize DHCP client!\r\n");
00671    }
00672 
00673    //Start DHCP client
00674    error = dhcpClientStart(&dhcpClientContext);
00675    //Failed to start DHCP client?
00676    if(error)
00677    {
00678       //Debug message
00679       TRACE_ERROR("Failed to start DHCP client!\r\n");
00680    }
00681 #else
00682    //Set IPv4 host address
00683    ipv4StringToAddr(APP_IPV4_HOST_ADDR, &ipv4Addr);
00684    ipv4SetHostAddr(interface, ipv4Addr);
00685 
00686    //Set subnet mask
00687    ipv4StringToAddr(APP_IPV4_SUBNET_MASK, &ipv4Addr);
00688    ipv4SetSubnetMask(interface, ipv4Addr);
00689 
00690    //Set default gateway
00691    ipv4StringToAddr(APP_IPV4_DEFAULT_GATEWAY, &ipv4Addr);
00692    ipv4SetDefaultGateway(interface, ipv4Addr);
00693 
00694    //Set primary and secondary DNS servers
00695    ipv4StringToAddr(APP_IPV4_PRIMARY_DNS, &ipv4Addr);
00696    ipv4SetDnsServer(interface, 0, ipv4Addr);
00697    ipv4StringToAddr(APP_IPV4_SECONDARY_DNS, &ipv4Addr);
00698    ipv4SetDnsServer(interface, 1, ipv4Addr);
00699 #endif
00700 #endif
00701 
00702 #if (IPV6_SUPPORT == ENABLED)
00703 #if (APP_USE_SLAAC == ENABLED)
00704    //Get default settings
00705    slaacGetDefaultSettings(&slaacSettings);
00706    //Set the network interface to be configured
00707    slaacSettings.interface = interface;
00708 
00709    //SLAAC initialization
00710    error = slaacInit(&slaacContext, &slaacSettings);
00711    //Failed to initialize SLAAC?
00712    if(error)
00713    {
00714       //Debug message
00715       TRACE_ERROR("Failed to initialize SLAAC!\r\n");
00716    }
00717 
00718    //Start IPv6 address autoconfiguration process
00719    error = slaacStart(&slaacContext);
00720    //Failed to start SLAAC process?
00721    if(error)
00722    {
00723       //Debug message
00724       TRACE_ERROR("Failed to start SLAAC!\r\n");
00725    }
00726 #else
00727    //Set link-local address
00728    ipv6StringToAddr(APP_IPV6_LINK_LOCAL_ADDR, &ipv6Addr);
00729    ipv6SetLinkLocalAddr(interface, &ipv6Addr);
00730 
00731    //Set IPv6 prefix
00732    ipv6StringToAddr(APP_IPV6_PREFIX, &ipv6Addr);
00733    ipv6SetPrefix(interface, 0, &ipv6Addr, APP_IPV6_PREFIX_LENGTH);
00734 
00735    //Set global address
00736    ipv6StringToAddr(APP_IPV6_GLOBAL_ADDR, &ipv6Addr);
00737    ipv6SetGlobalAddr(interface, 0, &ipv6Addr);
00738 
00739    //Set default router
00740    ipv6StringToAddr(APP_IPV6_ROUTER, &ipv6Addr);
00741    ipv6SetDefaultRouter(interface, 0, &ipv6Addr);
00742 
00743    //Set primary and secondary DNS servers
00744    ipv6StringToAddr(APP_IPV6_PRIMARY_DNS, &ipv6Addr);
00745    ipv6SetDnsServer(interface, 0, &ipv6Addr);
00746    ipv6StringToAddr(APP_IPV6_SECONDARY_DNS, &ipv6Addr);
00747    ipv6SetDnsServer(interface, 1, &ipv6Addr);
00748 #endif
00749 #endif
00750 
00751    //Create MQTT test task
00752    task = osCreateTask("MQTT", mqttTestTask, NULL, 750, OS_TASK_PRIORITY_NORMAL);
00753    //Failed to create the task?
00754    if(task == OS_INVALID_HANDLE)
00755    {
00756       //Debug message
00757       TRACE_ERROR("Failed to create task!\r\n");
00758    }
00759 
00760    //Create a task to blink the LED
00761    task = osCreateTask("Blink", blinkTask, NULL, 500, OS_TASK_PRIORITY_NORMAL);
00762    //Failed to create the task?
00763    if(task == OS_INVALID_HANDLE)
00764    {
00765       //Debug message
00766       TRACE_ERROR("Failed to create task!\r\n");
00767    }
00768 
00769    //Start the execution of tasks
00770    osStartKernel();
00771 
00772    //This function should never return
00773    return 0;
00774 }
00775