samples: net: mqtt: Add a sample to connect to Azure

This samples demonstrates how to connect to Azure Cloud
IoT hub which is based on MQTT protocol. User has to
create an account in Azure Cloud and provide those details
using Kconfig options. This sample first acquires DHCPv4
address and opens a secure connection with Azure cloud.
Then opens a MQTT connection and publish messages randomly.

Signed-off-by: Ravi kumar Veeramally <ravikumar.veeramally@linux.intel.com>
This commit is contained in:
Ravi kumar Veeramally 2019-11-08 14:01:08 +02:00 committed by Jukka Rissanen
commit f1a1e5382e
10 changed files with 800 additions and 0 deletions

View file

@ -0,0 +1,9 @@
# SPDX-License-Identifier: Apache-2.0
cmake_minimum_required(VERSION 3.13.1)
include($ENV{ZEPHYR_BASE}/cmake/app/boilerplate.cmake NO_POLICY_SCOPE)
project(mqtt-azure)
FILE(GLOB app_sources src/*.c)
target_sources(app PRIVATE ${app_sources})

View file

@ -0,0 +1,56 @@
# Kconfig - Private config options for mqtt-azure sample app
#
# Copyright (c) 2019 Intel Corporation
#
# SPDX-License-Identifier: Apache-2.0
#
mainmenu "Networking mqtt-azure sample application"
config SAMPLE_CLOUD_AZURE_USERNAME
string "Azure cloud username"
help
Username of your Azure account.
config SAMPLE_CLOUD_AZURE_PASSWORD
string "Azure cloud password"
help
Password of your Azure account.
config SAMPLE_CLOUD_AZURE_CLIENT_ID
string "Azure cloud IoT hub MQTT client ID"
help
Device ID which you have setup in IoT hub account.
config SAMPLE_CLOUD_AZURE_HOSTNAME
string "Azure cloud IoT hub hostname"
help
Hostname of your Azure cloud IoT hub.
config SAMPLE_CLOUD_AZURE_SERVER_ADDR
string "Azure cloud server address"
help
Azure cloud server address.
config SAMPLE_CLOUD_AZURE_SERVER_PORT
int "Azure cloud server port number"
default 8883
help
Azure cloud server port number.
config SAMPLE_SOCKS_ADDR
string "Proxy address"
depends on SOCKS
help
Provide proxy address if you are running this application
behind proxy.
config SAMPLE_SOCKS_PORT
int "Proxy port"
depends on SOCKS
help
Provide proxy port if you are running this application
behind proxy.
source "Kconfig.zephyr"

View file

@ -0,0 +1,115 @@
.. _mqtt-azure-sample:
MQTT Azure Sample
#################
Overview
********
This sample application demonstrates how an MQTT client
can publish messages to an Azure Cloud IoT hub based on MQTT protocol.
- Acquire a DHCPv4 lease
- Establish a TLS connection with Azure Cloud IoT hub
- Publish data to the Azure cloud
- SOCKS5 supported
- DNS supported
The source code of this sample application can be found at:
:zephyr_file:`samples/net/mqtt_azure`.
Requirements
************
- Azure Cloud account
- Azure IOT Cloud credentials and required information
- Freedom Board (FRDM-K64F)
- Network connectivity
Building and Running
********************
This application has been built and tested on the NXP FRDMK64F.
Certs are required to authenticate to the Azure Cloud IoT hub.
Current certs in :zephyr_file:`samples/net/mqtt_azure/src/digicert.cer` are
copied from `<https://github.com/Azure/azure-iot-sdk-c/blob/master/certs/certs.c>`_
Configure the following Kconfig options based on your Azure Cloud IoT Hub
in your own overlay config file:
- SAMPLE_CLOUD_AZURE_USERNAME - Username field use::
{iothubhostname}/{device_id}/?api-version=2018-06-30,
where ``{iothubhostname}`` is the full CName of the IoT hub.
- SAMPLE_CLOUD_AZURE_PASSWORD - Password field, use an SAS token.
- SAMPLE_CLOUD_AZURE_CLIENT_ID - ClientId field, use the deviceId.
- SAMPLE_CLOUD_AZURE_HOSTNAME - IoT hub hostname
- SAMPLE_CLOUD_AZURE_SERVER_ADDR - IP address of the Azure MQTT broker
- SAMPLE_CLOUD_AZURE_SERVER_PORT - Port number of the Azure MQTT broker
You'll also need to set these Kconfig options if you're running
the sample behind a proxy:
- SAMPLE_SOCKS_ADDR - IP address of SOCKS5 Proxy server
- SAMPLE_SOCKS_PORT - Port number of SOCKS5 Proxy server
On your Linux host computer, open a terminal window, locate the source code
of this sample application (i.e., :zephyr_file:`samples/net/mqtt_azure`) and type:
.. zephyr-app-commands::
:zephyr-app: samples/net/mqtt_azure
:board: frdm_k64f
:conf: "prj.conf <overlay.conf>"
:goals: build flash
:compact:
Also this application can be tested with QEMU. This is described in
:ref:`networking_with_qemu`. Set up Zephyr and NAT/masquerading on host
to access Internet and use :file:`overlay-qemu_x86.conf`.
DHCP support is not enabled with QEMU. It uses static IP addresses.
Sample overlay file
===================
This is the overlay template for Azure IoT hub and other details:
.. code-block:: console
CONFIG_SAMPLE_CLOUD_AZURE_USERNAME="<username>"
CONFIG_SAMPLE_CLOUD_AZURE_PASSWORD="<SAS token>"
CONFIG_SAMPLE_CLOUD_AZURE_CLIENT_ID="<device id>"
CONFIG_SAMPLE_CLOUD_AZURE_HOSTNAME="<IoT hub hostname>"
CONFIG_SAMPLE_SOCKS_ADDR="<proxy addr>"
CONFIG_SAMPLE_SOCKS_PORT=<proxy port>
CONFIG_SAMPLE_CLOUD_AZURE_SERVER_ADDR="<server ip addr, if DNS disabled set this>"
CONFIG_SAMPLE_CLOUD_AZURE_SERVER_PORT=<server port, if DNS disabled set this>
Sample output
=============
This is the output from the FRDM UART console, with:
.. code-block:: console
[00:00:03.001,000] <inf> eth_mcux: Enabled 100M full-duplex mode.
[00:00:03.010,000] <dbg> mqtt_azure.main: Waiting for network to setup...
[00:00:03.115,000] <inf> net_dhcpv4: Received: 10.0.0.2
[00:00:03.124,000] <inf> net_config: IPv4 address: 10.0.0.2
[00:00:03.132,000] <inf> net_config: Lease time: 43200 seconds
[00:00:03.140,000] <inf> net_config: Subnet: 255.255.255.0
[00:00:03.149,000] <inf> net_config: Router: 10.0.0.10
[00:00:06.157,000] <dbg> mqtt_azure.try_to_connect: attempting to connect...
[00:00:06.167,000] <dbg> net_sock_tls.tls_alloc: (0x200024f8): Allocated TLS context, 0x20001110
[00:00:19.412,000] <dbg> mqtt_azure.mqtt_event_handler: MQTT client connected!
[00:00:19.424,000] <dbg> mqtt_azure.publish_message: mqtt_publish OK
[00:00:19.830,000] <dbg> mqtt_azure.mqtt_event_handler: PUBACK packet id: 63387
[00:00:31.842,000] <dbg> mqtt_azure.publish_message: mqtt_publish OK
[00:00:51.852,000] <dbg> mqtt_azure.publish_message: mqtt_publish OK
[00:00:51.861,000] <dbg> mqtt_azure.mqtt_event_handler: PUBACK packet id: 38106
You can also check events or messages information on Azure Portal.
See `Azure Cloud MQTT Documentation
<https://docs.microsoft.com/en-us/azure/iot-hub/iot-hub-mqtt-support>`_.

View file

@ -0,0 +1,10 @@
# Disable DHCPv4 and use static address
CONFIG_NET_DHCPV4=n
# Use local DNS server on host
CONFIG_DNS_SERVER1="192.0.2.2"
# Configure static addresses
CONFIG_NET_CONFIG_MY_IPV4_ADDR="192.0.2.1"
CONFIG_NET_CONFIG_MY_IPV4_GW="192.0.2.2"

View file

@ -0,0 +1,71 @@
CONFIG_NETWORKING=y
# Disable IPv6 support
CONFIG_NET_IPV6=n
# Enable IPv4 support
CONFIG_NET_IPV4=y
CONFIG_NET_IF_MAX_IPV4_COUNT=2
CONFIG_NET_IF_UNICAST_IPV4_ADDR_COUNT=3
# Enable TCP support
CONFIG_NET_TCP=y
# Enable Sockets support
CONFIG_NET_SOCKETS=y
CONFIG_NET_SOCKETS_SOCKOPT_TLS=y
# Enable DHCPv4 support
CONFIG_NET_DHCPV4=y
# Enable SOCKS5 proxy support
CONFIG_SOCKS=n
# Enable MQTT Lib support
CONFIG_MQTT_LIB=y
CONFIG_MQTT_LIB_TLS=y
# Enable Mbed TLS configuration
CONFIG_MBEDTLS=y
CONFIG_MBEDTLS_BUILTIN=y
CONFIG_MBEDTLS_ENABLE_HEAP=y
CONFIG_MBEDTLS_HEAP_SIZE=100000
CONFIG_MBEDTLS_SSL_MAX_CONTENT_LEN=10240
CONFIG_MBEDTLS_PEM_CERTIFICATE_FORMAT=y
# Network configuration
CONFIG_NET_CONFIG_SETTINGS=y
# Network connection manager
CONFIG_NET_CONNECTION_MANAGER=y
CONFIG_NET_MGMT_EVENT_STACK_SIZE=1024
CONFIG_NET_MGMT_EVENT_QUEUE_SIZE=5
CONFIG_NET_MGMT_EVENT_LOG_LEVEL_DBG=n
CONFIG_DNS_RESOLVER=y
CONFIG_DNS_SERVER_IP_ADDRESSES=y
CONFIG_DNS_SERVER1="8.8.8.8"
CONFIG_DNS_RESOLVER_ADDITIONAL_BUF_CTR=2
CONFIG_NEWLIB_LIBC=y
CONFIG_INIT_STACKS=y
CONFIG_NET_SHELL=y
CONFIG_MAIN_STACK_SIZE=4096
# Enable Logging support
CONFIG_LOG_IMMEDIATE=y
CONFIG_NET_LOG=y
CONFIG_NET_TCP_LOG_LEVEL_DBG=n
CONFIG_NET_SOCKETS_LOG_LEVEL_DBG=n
CONFIG_MQTT_LOG_LEVEL_DBG=n
CONFIG_NET_DHCPV4_LOG_LEVEL_INF=n
CONFIG_NET_IF_LOG_LEVEL_DBG=n
CONFIG_MBEDTLS_DEBUG=n
#CONFIG_MBEDTLS_DEBUG_LEVEL=4
CONFIG_SOCKS_LOG_LEVEL_DBG=n
CONFIG_NET_CONFIG_LOG_LEVEL_DBG=y
CONFIG_NET_CONNECTION_MANAGER_LOG_LEVEL_DBG=n
CONFIG_DNS_RESOLVER_LOG_LEVEL_DBG=n
CONFIG_NET_CONTEXT_LOG_LEVEL_DBG=n

View file

@ -0,0 +1,8 @@
sample:
description: MQTT sample app to Azure cloud
name: mqtt-azure
tests:
sample.net.mqtt_azure:
harness: net
platform_whitelist: sam_e70_xplained frdm_k64f qemu_x86
tags: net mqtt cloud

View file

@ -0,0 +1,24 @@
/*
* Copyright (c) 2019 Intel Corporation
*
* SPDX-License-Identifier: Apache-2.0
*/
#ifndef __CONFIG_H__
#define __CONFIG_H__
#define SERVER_ADDR CONFIG_SAMPLE_CLOUD_AZURE_SERVER_ADDR
#define SERVER_PORT CONFIG_SAMPLE_CLOUD_AZURE_SERVER_PORT
#if defined(CONFIG_SOCKS)
#define SOCKS5_PROXY_ADDR CONFIG_SAMPLE_SOCKS_ADDR
#define SOCKS5_PROXY_PORT CONFIG_SAMPLE_SOCKS_PORT
#endif
#define MQTT_CLIENTID CONFIG_SAMPLE_CLOUD_AZURE_CLIENT_ID
#define APP_SLEEP_MSECS 8000
#define APP_MQTT_BUFFER_SIZE 1024
#endif /* __CONFIG_H__ */

View file

@ -0,0 +1,21 @@
"-----BEGIN CERTIFICATE-----\r\n"
"MIIDdzCCAl+gAwIBAgIEAgAAuTANBgkqhkiG9w0BAQUFADBaMQswCQYDVQQGEwJJ\r\n"
"RTESMBAGA1UEChMJQmFsdGltb3JlMRMwEQYDVQQLEwpDeWJlclRydXN0MSIwIAYD\r\n"
"VQQDExlCYWx0aW1vcmUgQ3liZXJUcnVzdCBSb290MB4XDTAwMDUxMjE4NDYwMFoX\r\n"
"DTI1MDUxMjIzNTkwMFowWjELMAkGA1UEBhMCSUUxEjAQBgNVBAoTCUJhbHRpbW9y\r\n"
"ZTETMBEGA1UECxMKQ3liZXJUcnVzdDEiMCAGA1UEAxMZQmFsdGltb3JlIEN5YmVy\r\n"
"VHJ1c3QgUm9vdDCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAKMEuyKr\r\n"
"mD1X6CZymrV51Cni4eiVgLGw41uOKymaZN+hXe2wCQVt2yguzmKiYv60iNoS6zjr\r\n"
"IZ3AQSsBUnuId9Mcj8e6uYi1agnnc+gRQKfRzMpijS3ljwumUNKoUMMo6vWrJYeK\r\n"
"mpYcqWe4PwzV9/lSEy/CG9VwcPCPwBLKBsua4dnKM3p31vjsufFoREJIE9LAwqSu\r\n"
"XmD+tqYF/LTdB1kC1FkYmGP1pWPgkAx9XbIGevOF6uvUA65ehD5f/xXtabz5OTZy\r\n"
"dc93Uk3zyZAsuT3lySNTPx8kmCFcB5kpvcY67Oduhjprl3RjM71oGDHweI12v/ye\r\n"
"jl0qhqdNkNwnGjkCAwEAAaNFMEMwHQYDVR0OBBYEFOWdWTCCR1jMrPoIVDaGezq1\r\n"
"BE3wMBIGA1UdEwEB/wQIMAYBAf8CAQMwDgYDVR0PAQH/BAQDAgEGMA0GCSqGSIb3\r\n"
"DQEBBQUAA4IBAQCFDF2O5G9RaEIFoN27TyclhAO992T9Ldcw46QQF+vaKSm2eT92\r\n"
"9hkTI7gQCvlYpNRhcL0EYWoSihfVCr3FvDB81ukMJY2GQE/szKN+OMY3EU/t3Wgx\r\n"
"jkzSswF07r51XgdIGn9w/xZchMB5hbgF/X++ZRGjD8ACtPhSNzkE1akxehi/oCr0\r\n"
"Epn3o0WC4zxe9Z2etciefC7IpJ5OCBRLbf1wbWsaY71k5h+3zvDyny67G7fyUIhz\r\n"
"ksLi4xaNmjICq44Y3ekQEe5+NauQrz4wlHrQMz2nZQ/1/I6eYs9HRCwBXbsdtTLS\r\n"
"R9I4LtD+gdwyah617jzV/OeBHRnDJELqYzmp\r\n"
"-----END CERTIFICATE-----\r\n"

View file

@ -0,0 +1,472 @@
/*
* Copyright (c) 2019 Intel Corporation
*
* SPDX-License-Identifier: Apache-2.0
*/
#include <logging/log.h>
LOG_MODULE_REGISTER(mqtt_azure, LOG_LEVEL_DBG);
#include <zephyr.h>
#include <net/socket.h>
#include <net/mqtt.h>
#include <sys/printk.h>
#include <string.h>
#include <errno.h>
#include "config.h"
#include "test_certs.h"
/* Buffers for MQTT client. */
static u8_t rx_buffer[APP_MQTT_BUFFER_SIZE];
static u8_t tx_buffer[APP_MQTT_BUFFER_SIZE];
/* The mqtt client struct */
static struct mqtt_client client_ctx;
/* MQTT Broker details. */
static struct sockaddr_storage broker;
#if defined(CONFIG_SOCKS)
static struct sockaddr socks5_proxy;
#endif
/* Socket Poll */
static struct pollfd fds[1];
static int nfds;
static bool mqtt_connected;
static struct k_delayed_work pub_message;
#if defined(CONFIG_NET_DHCPV4)
static struct k_delayed_work check_network_conn;
/* Network Management events */
#define L4_EVENT_MASK (NET_EVENT_L4_CONNECTED | NET_EVENT_L4_DISCONNECTED)
static struct net_mgmt_event_callback l4_mgmt_cb;
#endif
#if defined(CONFIG_DNS_RESOLVER)
static struct addrinfo hints;
static struct addrinfo *haddr;
#endif
static K_SEM_DEFINE(mqtt_start, 0, 1);
static K_SEM_DEFINE(publish_msg, 0, 1);
/* Application TLS configuration details */
#define TLS_SNI_HOSTNAME CONFIG_SAMPLE_CLOUD_AZURE_HOSTNAME
#define APP_CA_CERT_TAG 1
static sec_tag_t m_sec_tags[] = {
APP_CA_CERT_TAG,
};
static void mqtt_event_handler(struct mqtt_client *const client,
const struct mqtt_evt *evt);
static int tls_init(void)
{
int err;
err = tls_credential_add(APP_CA_CERT_TAG, TLS_CREDENTIAL_CA_CERTIFICATE,
ca_certificate, sizeof(ca_certificate));
if (err < 0) {
LOG_ERR("Failed to register public certificate: %d", err);
return err;
}
return err;
}
static void prepare_fds(struct mqtt_client *client)
{
if (client->transport.type == MQTT_TRANSPORT_SECURE) {
fds[0].fd = client->transport.tls.sock;
}
fds[0].events = ZSOCK_POLLIN;
nfds = 1;
}
static void clear_fds(void)
{
nfds = 0;
}
static int wait(int timeout)
{
int rc = -EINVAL;
if (nfds <= 0) {
return rc;
}
rc = poll(fds, nfds, timeout);
if (rc < 0) {
LOG_ERR("poll error: %d", errno);
return -errno;
}
return rc;
}
static void broker_init(void)
{
struct sockaddr_in *broker4 = (struct sockaddr_in *)&broker;
broker4->sin_family = AF_INET;
broker4->sin_port = htons(SERVER_PORT);
#if defined(CONFIG_DNS_RESOLVER)
net_ipaddr_copy(&broker4->sin_addr,
&net_sin(haddr->ai_addr)->sin_addr);
#else
inet_pton(AF_INET, SERVER_ADDR, &broker4->sin_addr);
#endif
#if defined(CONFIG_SOCKS)
struct sockaddr_in *proxy4 = (struct sockaddr_in *)&socks5_proxy;
proxy4->sin_family = AF_INET;
proxy4->sin_port = htons(SOCKS5_PROXY_PORT);
inet_pton(AF_INET, SOCKS5_PROXY_ADDR, &proxy4->sin_addr);
#endif
}
static void client_init(struct mqtt_client *client)
{
static struct mqtt_utf8 password;
static struct mqtt_utf8 username;
struct mqtt_sec_config *tls_config;
mqtt_client_init(client);
broker_init();
/* MQTT client configuration */
client->broker = &broker;
client->evt_cb = mqtt_event_handler;
client->client_id.utf8 = (u8_t *)MQTT_CLIENTID;
client->client_id.size = strlen(MQTT_CLIENTID);
password.utf8 = (u8_t *)CONFIG_SAMPLE_CLOUD_AZURE_PASSWORD;
password.size = strlen(CONFIG_SAMPLE_CLOUD_AZURE_PASSWORD);
client->password = &password;
username.utf8 = (u8_t *)CONFIG_SAMPLE_CLOUD_AZURE_USERNAME;
username.size = strlen(CONFIG_SAMPLE_CLOUD_AZURE_USERNAME);
client->user_name = &username;
client->protocol_version = MQTT_VERSION_3_1_1;
/* MQTT buffers configuration */
client->rx_buf = rx_buffer;
client->rx_buf_size = sizeof(rx_buffer);
client->tx_buf = tx_buffer;
client->tx_buf_size = sizeof(tx_buffer);
/* MQTT transport configuration */
client->transport.type = MQTT_TRANSPORT_SECURE;
tls_config = &client->transport.tls.config;
tls_config->peer_verify = 2;
tls_config->cipher_list = NULL;
tls_config->sec_tag_list = m_sec_tags;
tls_config->sec_tag_count = ARRAY_SIZE(m_sec_tags);
tls_config->hostname = TLS_SNI_HOSTNAME;
#if defined(CONFIG_SOCKS)
mqtt_client_set_proxy(client, &socks5_proxy,
socks5_proxy.sa_family == AF_INET ?
sizeof(struct sockaddr_in) :
sizeof(struct sockaddr_in6));
#endif
}
static void mqtt_event_handler(struct mqtt_client *const client,
const struct mqtt_evt *evt)
{
switch (evt->type) {
case MQTT_EVT_CONNACK:
if (evt->result) {
LOG_ERR("MQTT connect failed %d", evt->result);
break;
}
mqtt_connected = true;
LOG_DBG("MQTT client connected!");
break;
case MQTT_EVT_DISCONNECT:
LOG_DBG("MQTT client disconnected %d", evt->result);
mqtt_connected = false;
clear_fds();
break;
case MQTT_EVT_PUBACK:
if (evt->result) {
LOG_ERR("MQTT PUBACK error %d", evt->result);
break;
}
LOG_DBG("PUBACK packet id: %u\n", evt->param.puback.message_id);
break;
default:
LOG_DBG("Unhandled MQTT event %d", evt->type);
break;
}
}
static int publish(struct mqtt_client *client, enum mqtt_qos qos)
{
char payload[] = "{id=123}";
char topic[] = "devices/" MQTT_CLIENTID "/messages/events/";
u8_t len = strlen(topic);
struct mqtt_publish_param param;
param.message.topic.qos = qos;
param.message.topic.topic.utf8 = (u8_t *)topic;
param.message.topic.topic.size = len;
param.message.payload.data = payload;
param.message.payload.len = strlen(payload);
param.message_id = sys_rand32_get();
param.dup_flag = 0U;
param.retain_flag = 0U;
return mqtt_publish(client, &param);
}
/* Random time between 10 - 15 seconds
* If you prefer to have this value more than CONFIG_MQTT_KEEPALIVE,
* then keep the application connection live by calling mqtt_live()
* in regular intervals.
*/
static u8_t timeout_for_publish(void)
{
return (10 + sys_rand32_get() % 5);
}
static void publish_timeout(struct k_work *work)
{
k_sem_give(&publish_msg);
}
static void publish_message(void)
{
while (mqtt_connected) {
int rc;
rc = publish(&client_ctx, MQTT_QOS_1_AT_LEAST_ONCE);
if (rc) {
LOG_ERR("mqtt_publish ERROR");
goto end;
}
LOG_DBG("mqtt_publish OK");
rc = wait(APP_SLEEP_MSECS);
if (rc <= 0) {
goto end;
}
mqtt_input(&client_ctx);
end:
k_delayed_work_submit(&pub_message,
MSEC_PER_SEC * timeout_for_publish());
k_sem_take(&publish_msg, K_FOREVER);
}
}
static int try_to_connect(struct mqtt_client *client)
{
u8_t retries = 3U;
int rc;
LOG_DBG("attempting to connect...");
while (retries--) {
client_init(client);
rc = mqtt_connect(client);
if (rc) {
LOG_ERR("mqtt_connect failed %d", rc);
continue;
}
prepare_fds(client);
rc = wait(APP_SLEEP_MSECS);
if (rc < 0) {
mqtt_abort(client);
return rc;
}
mqtt_input(client);
if (mqtt_connected) {
return 0;
}
mqtt_abort(client);
wait(10 * MSEC_PER_SEC);
}
return -EINVAL;
}
#if defined(CONFIG_DNS_RESOLVER)
static int get_mqtt_broker_addrinfo(void)
{
int retries = 3;
int rc = -EINVAL;
while (retries--) {
hints.ai_family = AF_INET;
hints.ai_socktype = SOCK_STREAM;
hints.ai_protocol = 0;
rc = getaddrinfo(CONFIG_SAMPLE_CLOUD_AZURE_HOSTNAME, "8883",
&hints, &haddr);
if (rc == 0) {
LOG_INF("DNS resolved for %s:%d",
CONFIG_SAMPLE_CLOUD_AZURE_HOSTNAME,
CONFIG_SAMPLE_CLOUD_AZURE_SERVER_PORT);
return 0;
}
LOG_ERR("DNS not resolved for %s:%d, retrying",
CONFIG_SAMPLE_CLOUD_AZURE_HOSTNAME,
CONFIG_SAMPLE_CLOUD_AZURE_SERVER_PORT);
}
return rc;
}
#endif
static void connect_to_cloud_and_publish(void)
{
int rc = -EINVAL;
#if defined(CONFIG_NET_DHCPV4)
while (true) {
k_sem_take(&mqtt_start, K_FOREVER);
#endif
#if defined(CONFIG_DNS_RESOLVER)
rc = get_mqtt_broker_addrinfo();
if (rc) {
return;
}
#endif
rc = try_to_connect(&client_ctx);
if (rc) {
return;
}
publish_message();
#if defined(CONFIG_NET_DHCPV4)
}
#endif
}
/* DHCP tries to renew the address after interface is down and up.
* If DHCPv4 address renewal is success, then it doesn't generate
* any event. We have to monitor this way.
* If DHCPv4 attempts exceeds maximum number, it will delete iface
* address and attempts for new request. In this case we can rely
* on IPV4_ADDR_ADD event.
*/
#if defined(CONFIG_NET_DHCPV4)
static void check_network_connection(struct k_work *work)
{
struct net_if *iface;
if (mqtt_connected) {
return;
}
iface = net_if_get_default();
if (!iface) {
goto end;
}
if (iface->config.dhcpv4.state == NET_DHCPV4_BOUND) {
k_sem_give(&mqtt_start);
return;
}
LOG_INF("waiting for DHCP to acquire addr");
end:
k_delayed_work_submit(&check_network_conn, 3 * MSEC_PER_SEC);
}
#endif
#if defined(CONFIG_NET_DHCPV4)
static void abort_mqtt_connection(void)
{
if (mqtt_connected) {
mqtt_connected = false;
mqtt_abort(&client_ctx);
k_delayed_work_cancel(&pub_message);
}
}
static void l4_event_handler(struct net_mgmt_event_callback *cb,
u32_t mgmt_event, struct net_if *iface)
{
if ((mgmt_event & L4_EVENT_MASK) != mgmt_event) {
return;
}
if (mgmt_event == NET_EVENT_L4_CONNECTED) {
/* Wait for DHCP to be back in BOUND state */
k_delayed_work_submit(&check_network_conn, 3 * MSEC_PER_SEC);
return;
}
if (mgmt_event == NET_EVENT_L4_DISCONNECTED) {
k_sem_give(&publish_msg);
abort_mqtt_connection();
k_delayed_work_cancel(&check_network_conn);
return;
}
}
#endif
void main(void)
{
int rc;
LOG_DBG("Waiting for network to setup...");
rc = tls_init();
if (rc) {
return;
}
k_delayed_work_init(&pub_message, publish_timeout);
#if defined(CONFIG_NET_DHCPV4)
k_delayed_work_init(&check_network_conn, check_network_connection);
net_mgmt_init_event_callback(&l4_mgmt_cb, l4_event_handler,
L4_EVENT_MASK);
net_mgmt_add_event_callback(&l4_mgmt_cb);
#endif
connect_to_cloud_and_publish();
}

View file

@ -0,0 +1,14 @@
/*
* Copyright (c) 2019 Intel Corporation
*
* SPDX-License-Identifier: Apache-2.0
*/
#ifndef __TEST_CERTS_H__
#define __TEST_CERTS_H__
static const unsigned char ca_certificate[] = {
#include "digicert.cer"
};
#endif /* __TEST_CERTS_H__ */