samples/net: Add network-related functions to MQTT Publisher
Add TCP/IPv4 routines to this sample. This MQTT sample code demonstrates how to implement an MQTT publisher application. For network application development, see: * samples/net/echo_server * samples/net/echo_client Change-Id: I13ac5ca1da2cd4d984fb595b599c3eab4edc5bf0 Signed-off-by: Flavio Santes <flavio.santes@intel.com>
This commit is contained in:
parent
38723bc177
commit
8ba4f26e5f
7 changed files with 417 additions and 5 deletions
|
@ -12,8 +12,6 @@ CONFIG_NETWORKING_IPV6_NO_ND=y
|
|||
CONFIG_IP_BUF_RX_SIZE=4
|
||||
CONFIG_IP_BUF_TX_SIZE=4
|
||||
|
||||
CONFIG_NETZ=y
|
||||
|
||||
# Uncomment the following variables for debugging
|
||||
|
||||
#CONFIG_NETWORKING_WITH_LOGGING=y
|
||||
|
|
|
@ -14,6 +14,12 @@
|
|||
# limitations under the License.
|
||||
#
|
||||
|
||||
obj-y += mqtt.o
|
||||
ccflags-y +=-I${ZEPHYR_BASE}/net/ip/contiki
|
||||
ccflags-y +=-I${ZEPHYR_BASE}/net/ip/contiki/os/lib
|
||||
ccflags-y +=-I${ZEPHYR_BASE}/net/ip/contiki/os
|
||||
ccflags-y +=-I${ZEPHYR_BASE}/net/ip
|
||||
|
||||
obj-y += mqtt_pack.o
|
||||
obj-y += netz.o
|
||||
obj-y += mqtt.o
|
||||
obj-y += main.o
|
||||
|
|
19
samples/net/paho_mqtt_clients/publisher/src/app_buf.h
Normal file
19
samples/net/paho_mqtt_clients/publisher/src/app_buf.h
Normal file
|
@ -0,0 +1,19 @@
|
|||
#ifndef _APP_BUF_H_
|
||||
#define _APP_BUF_H_
|
||||
|
||||
#include <zephyr.h> /* for __deprecated */
|
||||
#include <stdint.h>
|
||||
#include <stddef.h>
|
||||
|
||||
struct __deprecated app_buf_t;
|
||||
|
||||
struct app_buf_t {
|
||||
uint8_t *buf;
|
||||
size_t size;
|
||||
size_t length;
|
||||
};
|
||||
|
||||
#define APP_BUF_INIT(_buf, _size, _length) {.buf = _buf, .size = _size,\
|
||||
.length = _length}
|
||||
|
||||
#endif
|
|
@ -17,7 +17,7 @@
|
|||
#ifndef _MQTT_H_
|
||||
#define _MQTT_H_
|
||||
|
||||
#include <netz.h>
|
||||
#include "netz.h"
|
||||
#include "mqtt_pack.h"
|
||||
|
||||
/**
|
||||
|
|
|
@ -17,7 +17,10 @@
|
|||
#ifndef _MQTT_PKT_H_
|
||||
#define _MQTT_PKT_H_
|
||||
|
||||
#include <app_buf.h>
|
||||
#include <stdint.h>
|
||||
#include <stddef.h>
|
||||
|
||||
#include "app_buf.h"
|
||||
|
||||
/**
|
||||
* @brief MQTT Packet Type
|
||||
|
|
223
samples/net/paho_mqtt_clients/publisher/src/netz.c
Normal file
223
samples/net/paho_mqtt_clients/publisher/src/netz.c
Normal file
|
@ -0,0 +1,223 @@
|
|||
/*
|
||||
* Copyright (c) 2016 Intel Corporation
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#include <netz.h>
|
||||
|
||||
#include <net/net_core.h>
|
||||
#include <net/net_socket.h>
|
||||
|
||||
#include <string.h>
|
||||
#include <errno.h>
|
||||
|
||||
void netz_host(struct netz_ctx_t *ctx, struct net_addr *host)
|
||||
{
|
||||
return netz_host_ipv4(ctx, host->in_addr.in4_u.u4_addr8[0],
|
||||
host->in_addr.in4_u.u4_addr8[1],
|
||||
host->in_addr.in4_u.u4_addr8[2],
|
||||
host->in_addr.in4_u.u4_addr8[3]);
|
||||
}
|
||||
|
||||
void netz_host_ipv4(struct netz_ctx_t *ctx, uint8_t a1, uint8_t a2,
|
||||
uint8_t a3, uint8_t a4)
|
||||
{
|
||||
uip_ipaddr_t host_addr;
|
||||
|
||||
uip_ipaddr(&host_addr, a1, a2, a3, a4);
|
||||
uip_sethostaddr(&host_addr);
|
||||
|
||||
ctx->host.in_addr.in4_u.u4_addr8[0] = a1;
|
||||
ctx->host.in_addr.in4_u.u4_addr8[1] = a2;
|
||||
ctx->host.in_addr.in4_u.u4_addr8[2] = a3;
|
||||
ctx->host.in_addr.in4_u.u4_addr8[3] = a4;
|
||||
ctx->host.family = AF_INET;
|
||||
}
|
||||
|
||||
void netz_netmask(struct netz_ctx_t *ctx, struct net_addr *netmask)
|
||||
{
|
||||
return netz_netmask_ipv4(ctx, netmask->in_addr.in4_u.u4_addr8[0],
|
||||
netmask->in_addr.in4_u.u4_addr8[1],
|
||||
netmask->in_addr.in4_u.u4_addr8[2],
|
||||
netmask->in_addr.in4_u.u4_addr8[3]);
|
||||
}
|
||||
|
||||
void netz_netmask_ipv4(struct netz_ctx_t *ctx, uint8_t n1, uint8_t n2,
|
||||
uint8_t n3, uint8_t n4)
|
||||
{
|
||||
ARG_UNUSED(ctx);
|
||||
|
||||
uip_ipaddr_t netmask;
|
||||
|
||||
uip_ipaddr(&netmask, n1, n2, n3, n4);
|
||||
uip_setnetmask(&netmask);
|
||||
}
|
||||
|
||||
void netz_remote(struct netz_ctx_t *ctx, struct net_addr *remote, int port)
|
||||
{
|
||||
return netz_remote_ipv4(ctx, remote->in_addr.in4_u.u4_addr8[0],
|
||||
remote->in_addr.in4_u.u4_addr8[1],
|
||||
remote->in_addr.in4_u.u4_addr8[2],
|
||||
remote->in_addr.in4_u.u4_addr8[3], port);
|
||||
}
|
||||
|
||||
void netz_remote_ipv4(struct netz_ctx_t *ctx, uint8_t a1, uint8_t a2,
|
||||
uint8_t a3, uint8_t a4, int port)
|
||||
{
|
||||
ctx->remote.in_addr.in4_u.u4_addr8[0] = a1;
|
||||
ctx->remote.in_addr.in4_u.u4_addr8[1] = a2;
|
||||
ctx->remote.in_addr.in4_u.u4_addr8[2] = a3;
|
||||
ctx->remote.in_addr.in4_u.u4_addr8[3] = a4;
|
||||
ctx->remote.family = AF_INET;
|
||||
|
||||
ctx->remote_port = port;
|
||||
}
|
||||
|
||||
static int netz_prepare(struct netz_ctx_t *ctx, enum ip_protocol proto)
|
||||
{
|
||||
#ifdef CONFIG_NETWORKING_WITH_TCP
|
||||
struct app_buf_t buf = APP_BUF_INIT(NULL, 0, 0);
|
||||
int rc;
|
||||
#endif
|
||||
|
||||
ctx->connected = 0;
|
||||
ctx->proto = proto;
|
||||
|
||||
ctx->net_ctx = net_context_get(ctx->proto,
|
||||
&ctx->remote, ctx->remote_port,
|
||||
&ctx->host, 0);
|
||||
if (ctx->net_ctx == NULL) {
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
#ifdef CONFIG_NETWORKING_WITH_TCP
|
||||
/* workaround to activate the IP stack */
|
||||
rc = netz_tx(ctx, &buf);
|
||||
if (rc != 0) {
|
||||
return rc;
|
||||
}
|
||||
#endif
|
||||
ctx->connected = 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int netz_tcp(struct netz_ctx_t *ctx)
|
||||
{
|
||||
return netz_prepare(ctx, IPPROTO_TCP);
|
||||
}
|
||||
|
||||
int netz_udp(struct netz_ctx_t *ctx)
|
||||
{
|
||||
return netz_prepare(ctx, IPPROTO_UDP);
|
||||
}
|
||||
|
||||
static void netz_sleep(int sleep_ticks)
|
||||
{
|
||||
struct nano_timer timer;
|
||||
|
||||
nano_timer_init(&timer, NULL);
|
||||
nano_fiber_timer_start(&timer, sleep_ticks);
|
||||
nano_fiber_timer_test(&timer, TICKS_UNLIMITED);
|
||||
}
|
||||
|
||||
static int tcp_tx(struct net_context *ctx, uint8_t *buf, size_t size,
|
||||
int tx_retry_timeout)
|
||||
{
|
||||
struct net_buf *nbuf;
|
||||
uint8_t *ptr;
|
||||
int rc;
|
||||
|
||||
nbuf = ip_buf_get_tx(ctx);
|
||||
if (nbuf == NULL) {
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
ptr = net_buf_add(nbuf, size);
|
||||
memcpy(ptr, buf, size);
|
||||
ip_buf_appdatalen(nbuf) = size;
|
||||
|
||||
do {
|
||||
rc = net_send(nbuf);
|
||||
|
||||
if (rc >= 0) {
|
||||
ip_buf_unref(nbuf);
|
||||
return 0;
|
||||
}
|
||||
switch (rc) {
|
||||
case -EINPROGRESS:
|
||||
netz_sleep(tx_retry_timeout);
|
||||
break;
|
||||
case -EAGAIN:
|
||||
case -ECONNRESET:
|
||||
netz_sleep(tx_retry_timeout);
|
||||
break;
|
||||
default:
|
||||
ip_buf_unref(nbuf);
|
||||
return -EIO;
|
||||
}
|
||||
} while (1);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int tcp_rx(struct net_context *ctx, uint8_t *buf, size_t *read_bytes,
|
||||
size_t size, int rx_timeout)
|
||||
{
|
||||
struct net_buf *nbuf;
|
||||
int rc;
|
||||
|
||||
nbuf = net_receive(ctx, rx_timeout);
|
||||
if (nbuf == NULL) {
|
||||
return -EIO;
|
||||
}
|
||||
|
||||
*read_bytes = ip_buf_appdatalen(nbuf);
|
||||
if (*read_bytes > size) {
|
||||
*read_bytes = size;
|
||||
rc = -ENOMEM;
|
||||
} else {
|
||||
rc = 0;
|
||||
}
|
||||
|
||||
memcpy(buf, ip_buf_appdata(nbuf), *read_bytes);
|
||||
ip_buf_unref(nbuf);
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
int netz_tx(struct netz_ctx_t *ctx, struct app_buf_t *buf)
|
||||
{
|
||||
int rc;
|
||||
|
||||
/* We don't evaluate if we are connected. */
|
||||
|
||||
rc = tcp_tx(ctx->net_ctx, buf->buf, buf->length,
|
||||
ctx->tx_retry_timeout);
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
int netz_rx(struct netz_ctx_t *ctx, struct app_buf_t *buf)
|
||||
{
|
||||
int rc;
|
||||
|
||||
if (ctx->connected != 1) {
|
||||
return -ENOTCONN;
|
||||
}
|
||||
|
||||
rc = tcp_rx(ctx->net_ctx, buf->buf, &buf->length, buf->size,
|
||||
ctx->rx_timeout);
|
||||
|
||||
return rc;
|
||||
}
|
163
samples/net/paho_mqtt_clients/publisher/src/netz.h
Normal file
163
samples/net/paho_mqtt_clients/publisher/src/netz.h
Normal file
|
@ -0,0 +1,163 @@
|
|||
/*
|
||||
* Copyright (c) 2016 Intel Corporation
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#ifndef _NETZ_H_
|
||||
#define _NETZ_H_
|
||||
|
||||
#include <net/ip_buf.h>
|
||||
#include <net/net_core.h>
|
||||
|
||||
#include "app_buf.h"
|
||||
|
||||
struct __deprecated netz_ctx_t;
|
||||
|
||||
struct netz_ctx_t {
|
||||
struct net_context *net_ctx;
|
||||
int connected;
|
||||
|
||||
int rx_timeout;
|
||||
int tx_retry_timeout;
|
||||
|
||||
struct net_addr host;
|
||||
int host_port;
|
||||
|
||||
struct net_addr remote;
|
||||
int remote_port;
|
||||
|
||||
enum ip_protocol proto;
|
||||
};
|
||||
|
||||
#define TCP_COMMON_TIMEOUT 20
|
||||
|
||||
/**
|
||||
* @brief NETZ_CTX_INIT Initializes a netz context with default values
|
||||
*/
|
||||
#define NETZ_CTX_INIT { .rx_timeout = TCP_COMMON_TIMEOUT, \
|
||||
.tx_retry_timeout = TCP_COMMON_TIMEOUT, \
|
||||
.net_ctx = NULL, \
|
||||
.connected = 0, \
|
||||
.proto = IPPROTO_UDP, \
|
||||
.host_port = 0, \
|
||||
.remote_port = 0}
|
||||
|
||||
/**
|
||||
* @brief NET_ADDR_IPV4_INIT Initializes a net_addr structure with
|
||||
* an IPv4 address specified by a1, a2, a3 and a4
|
||||
*/
|
||||
#define NET_ADDR_IPV4_INIT(a1, a2, a3, a4) {.in_addr.in4_u.u4_addr8[0] = (a1),\
|
||||
.in_addr.in4_u.u4_addr8[1] = (a2),\
|
||||
.in_addr.in4_u.u4_addr8[2] = (a3),\
|
||||
.in_addr.in4_u.u4_addr8[3] = (a4),\
|
||||
.family = AF_INET}
|
||||
|
||||
/**
|
||||
* @brief netz_host Sets the host IPv4 address (no IPv6 support)
|
||||
* @param ctx netz context structure
|
||||
* @param host Network address
|
||||
*/
|
||||
void __deprecated netz_host(struct netz_ctx_t *ctx, struct net_addr *host);
|
||||
|
||||
/**
|
||||
* @brief netz_host_ipv4 Sets the host IPv4 address (no IPv6 support)
|
||||
* @param ctx netz context structure
|
||||
* @param a1 Byte 0 of the IPv4 address
|
||||
* @param a2 Byte 1 of the IPv4 address
|
||||
* @param a3 Byte 2 of the IPv4 address
|
||||
* @param a4 Byte 3 of the IPv4 address
|
||||
*/
|
||||
void __deprecated netz_host_ipv4(struct netz_ctx_t *ctx, uint8_t a1,
|
||||
uint8_t a2, uint8_t a3, uint8_t a4);
|
||||
|
||||
/**
|
||||
* @brief netz_netmask Sets the host's netmask address
|
||||
* @param ctx netz context structure
|
||||
* @param netmask Network address to be used as netmask
|
||||
*/
|
||||
void __deprecated netz_netmask(struct netz_ctx_t *ctx,
|
||||
struct net_addr *netmask);
|
||||
|
||||
/**
|
||||
* @brief netz_netmask_ipv4 Sets the host's netmask IPv4 address
|
||||
* @param ctx netz context structure
|
||||
* @param n1 Byte 0 of the IPv4 address
|
||||
* @param n2 Byte 1 of the IPv4 address
|
||||
* @param n3 Byte 2 of the IPv4 address
|
||||
* @param n4 Byte 3 of the IPv4 address
|
||||
*/
|
||||
void __deprecated netz_netmask_ipv4(struct netz_ctx_t *ctx, uint8_t n1,
|
||||
uint8_t n2, uint8_t n3, uint8_t n4);
|
||||
/**
|
||||
* @brief netz_remote Sets the address of the remote peer
|
||||
* @param ctx netz context structure
|
||||
* @param remote Network address of the remote peer
|
||||
* @param port Port number of the remote peer
|
||||
*/
|
||||
void __deprecated netz_remote(struct netz_ctx_t *ctx, struct net_addr *remote,
|
||||
int port);
|
||||
|
||||
/**
|
||||
* @brief netz_remote_ipv4 Sets the IPv4 address of the remote peer
|
||||
* @param ctx netz context structure
|
||||
* @param a1 Byte 0 of the IPv4 address
|
||||
* @param a2 Byte 1 of the IPv4 address
|
||||
* @param a3 Byte 2 of the IPv4 address
|
||||
* @param a4 Byte 3 of the IPv4 address
|
||||
*/
|
||||
|
||||
void __deprecated netz_remote_ipv4(struct netz_ctx_t *ctx, uint8_t a1,
|
||||
uint8_t a2, uint8_t a3, uint8_t a4,
|
||||
int port);
|
||||
|
||||
/**
|
||||
* @brief netz_tcp Initializes the netz context & connects
|
||||
* to the remote peer
|
||||
* @param ctx netz context structure
|
||||
* @return 0 on success
|
||||
* @return -EINVAL if a null context was obtained
|
||||
* @return Read netz_tx return codes
|
||||
*/
|
||||
int __deprecated netz_tcp(struct netz_ctx_t *ctx);
|
||||
|
||||
/**
|
||||
* @brief netz_udp Initializes the context for UDP transfers
|
||||
* @param ctx netz context structure
|
||||
* @return 0 on success
|
||||
* @return -EINVAL if a null context was obtained
|
||||
*/
|
||||
int __deprecated netz_udp(struct netz_ctx_t *ctx);
|
||||
|
||||
/**
|
||||
* @brief netz_tx TCP/UDP data transmission
|
||||
* @param ctx netz context structure
|
||||
* @param buf Buffer that contains the data to be sent
|
||||
* @return 0 on success
|
||||
* @return -EINVAL if no network buffer is available
|
||||
* @return -EIO if a TCP error was detected
|
||||
*/
|
||||
int __deprecated netz_tx(struct netz_ctx_t *ctx, struct app_buf_t *buf);
|
||||
|
||||
/**
|
||||
* @brief netz_rx TCP/UDP data reception
|
||||
* @param ctx netz context structure
|
||||
* @param buf Buffer that contains the received data
|
||||
* @return 0 on success
|
||||
* @return -EIO on TCP or network buffer error
|
||||
* @return -ENOMEM if the space in buf is not enough
|
||||
* to store the received data
|
||||
*/
|
||||
int __deprecated netz_rx(struct netz_ctx_t *ctx, struct app_buf_t *buf);
|
||||
|
||||
#endif
|
Loading…
Add table
Add a link
Reference in a new issue