Skip to content
GitLab
Explore
Sign in
Primary navigation
Search or go to…
Project
C
contiki-ng
Manage
Activity
Members
Labels
Plan
Issues
Issue boards
Milestones
Wiki
Code
Merge requests
Repository
Branches
Commits
Tags
Repository graph
Compare revisions
Snippets
Build
Pipelines
Jobs
Pipeline schedules
Artifacts
Deploy
Releases
Package registry
Model registry
Operate
Environments
Terraform modules
Monitor
Incidents
Analyze
Value stream analytics
Contributor analytics
CI/CD analytics
Repository analytics
Model experiments
Help
Help
Support
GitLab documentation
Compare GitLab plans
Community forum
Contribute to GitLab
Provide feedback
Keyboard shortcuts
?
Snippets
Groups
Projects
Show more breadcrumbs
NATAF Emmanuel
contiki-ng
Commits
1e922116
Commit
1e922116
authored
10 years ago
by
Jonas Olsson
Browse files
Options
Downloads
Patches
Plain Diff
Add MQTT 3.1 engine
parent
e58aae1d
No related branches found
No related tags found
No related merge requests found
Changes
3
Expand all
Hide whitespace changes
Inline
Side-by-side
Showing
3 changed files
apps/mqtt/Makefile.mqtt
+1
-0
1 addition, 0 deletions
apps/mqtt/Makefile.mqtt
apps/mqtt/mqtt.c
+1484
-0
1484 additions, 0 deletions
apps/mqtt/mqtt.c
apps/mqtt/mqtt.h
+509
-0
509 additions, 0 deletions
apps/mqtt/mqtt.h
with
1994 additions
and
0 deletions
apps/mqtt/Makefile.mqtt
0 → 100644
+
1
−
0
View file @
1e922116
mqtt_src
=
mqtt.c
This diff is collapsed.
Click to expand it.
apps/mqtt/mqtt.c
0 → 100644
+
1484
−
0
View file @
1e922116
This diff is collapsed.
Click to expand it.
apps/mqtt/mqtt.h
0 → 100644
+
509
−
0
View file @
1e922116
/*
* Copyright (c) 2015, Texas Instruments Incorporated - http://www.ti.com/
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the copyright holder nor the names of its
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
* OF THE POSSIBILITY OF SUCH DAMAGE.
*/
/*---------------------------------------------------------------------------*/
/**
* \addtogroup apps
* @{
*
* \defgroup mqtt-engine An implementation of MQTT v3.1
* @{
*
* This application is an engine for MQTT v3.1. It supports QoS Levels 0 and 1.
*
* MQTT is a Client Server publish/subscribe messaging transport protocol.
* It is light weight, open, simple, and designed so as to be easy to implement.
* These characteristics make it ideal for use in many situations, including
* constrained environments such as for communication in Machine to Machine
* (M2M) and Internet of Things (IoT) contexts where a small code footprint is
* required and/or network bandwidth is at a premium.
*
* The protocol runs over TCP/IP, more specifically tcp_socket.
* Its features include:
*
* - Use of the publish/subscribe message pattern which provides
* one-to-many message distribution and decoupling of applications.
* - A messaging transport that is agnostic to the content of the payload.
* Three qualities of service for message delivery:
* -- "At most once" (0), where messages are delivered according to the best
* efforts of the operating environment. Message loss can occur.
* This level could be used, for example, with ambient sensor data where it
* does not matter if an individual reading is lost as the next one will be
* published soon after.
* --"At least once" (1), where messages are assured to arrive but duplicates
* can occur.
* -- "Exactly once" (2), where message are assured to arrive exactly once.
* This level could be used, for example, with billing systems where duplicate
* or lost messages could lead to incorrect charges being applied. This QoS
* level is currently not supported in this implementation.
*
* - A small transport overhead and protocol exchanges minimized to reduce
* network traffic.
* - A mechanism, Last Will, to notify interested parties when an abnormal
* disconnection occurs.
*
* The protocol specification and other useful information can be found
* here: http://mqtt.org
*
*/
/**
* \file
* Header file for the Contiki MQTT engine
*
* \author
* Texas Instruments
*/
/*---------------------------------------------------------------------------*/
#ifndef MQTT_H_
#define MQTT_H_
/*---------------------------------------------------------------------------*/
#include
"contiki.h"
#include
"contiki-net.h"
#include
"contiki-lib.h"
#include
"lib/random.h"
#include
"sys/ctimer.h"
#include
"sys/etimer.h"
#include
"net/rpl/rpl.h"
#include
"net/ip/uip.h"
#include
"net/ipv6/uip-ds6.h"
#include
"dev/leds.h"
#include
"tcp-socket.h"
#include
"udp-socket.h"
#include
<stdlib.h>
#include
<stdio.h>
#include
<string.h>
/*---------------------------------------------------------------------------*/
/* Protocol constants */
#define MQTT_CLIENT_ID_MAX_LEN 23
/* Size of the underlying TCP buffers */
#define MQTT_TCP_INPUT_BUFF_SIZE 512
#define MQTT_TCP_OUTPUT_BUFF_SIZE 512
#define MQTT_INPUT_BUFF_SIZE 512
#define MQTT_MAX_TOPIC_LENGTH 64
#define MQTT_MAX_TOPICS_PER_SUBSCRIBE 1
#define MQTT_FHDR_SIZE 1
#define MQTT_MAX_REMAINING_LENGTH_BYTES 4
#define MQTT_PROTOCOL_VERSION 3
#define MQTT_PROTOCOL_NAME "MQIsdp"
#define MQTT_TOPIC_MAX_LENGTH 128
/*---------------------------------------------------------------------------*/
/*
* Debug configuration, this is similar but not exactly like the Debugging
* System discussion at https://github.com/contiki-os/contiki/wiki.
*/
#define DEBUG_MQTT 0
#if DEBUG_MQTT == 1
#define DBG(...) printf(__VA_ARGS__)
#else
#define DBG(...)
#endif
/* DEBUG */
/*---------------------------------------------------------------------------*/
extern
process_event_t
mqtt_update_event
;
/* Forward declaration */
struct
mqtt_connection
;
typedef
enum
{
MQTT_RETAIN_OFF
,
MQTT_RETAIN_ON
,
}
mqtt_retain_t
;
/**
* \brief MQTT engine events
*/
typedef
enum
{
MQTT_EVENT_CONNECTED
,
MQTT_EVENT_DISCONNECTED
,
MQTT_EVENT_SUBACK
,
MQTT_EVENT_UNSUBACK
,
MQTT_EVENT_PUBLISH
,
MQTT_EVENT_PUBACK
,
/* Errors */
MQTT_EVENT_ERROR
=
0x80
,
MQTT_EVENT_PROTOCOL_ERROR
,
MQTT_EVENT_CONNECTION_REFUSED_ERROR
,
MQTT_EVENT_DNS_ERROR
,
MQTT_EVENT_NOT_IMPLEMENTED_ERROR
,
/* Add more */
}
mqtt_event_t
;
typedef
enum
{
MQTT_STATUS_OK
,
MQTT_STATUS_OUT_QUEUE_FULL
,
/* Errors */
MQTT_STATUS_ERROR
=
0x80
,
MQTT_STATUS_NOT_CONNECTED_ERROR
,
MQTT_STATUS_INVALID_ARGS_ERROR
,
MQTT_STATUS_DNS_ERROR
,
}
mqtt_status_t
;
typedef
enum
{
MQTT_QOS_LEVEL_0
,
MQTT_QOS_LEVEL_1
,
MQTT_QOS_LEVEL_2
,
}
mqtt_qos_level_t
;
typedef
enum
{
MQTT_QOS_STATE_NO_ACK
,
MQTT_QOS_STATE_GOT_ACK
,
/* Expand for QoS 2 */
}
mqtt_qos_state_t
;
/*---------------------------------------------------------------------------*/
/*
* This is the state of the connection itself.
*
* N.B. The order is important because of runtime checks on how far the
* connection has proceeded.
*/
typedef
enum
{
MQTT_CONN_STATE_ERROR
,
MQTT_CONN_STATE_DNS_ERROR
,
MQTT_CONN_STATE_DISCONNECTING
,
MQTT_CONN_STATE_NOT_CONNECTED
,
MQTT_CONN_STATE_DNS_LOOKUP
,
MQTT_CONN_STATE_TCP_CONNECTING
,
MQTT_CONN_STATE_TCP_CONNECTED
,
MQTT_CONN_STATE_CONNECTING_TO_BROKER
,
MQTT_CONN_STATE_CONNECTED_TO_BROKER
,
MQTT_CONN_STATE_SENDING_MQTT_DISCONNECT
,
MQTT_CONN_STATE_ABORT_IMMEDIATE
,
}
mqtt_conn_state_t
;
/*---------------------------------------------------------------------------*/
struct
mqtt_string
{
char
*
string
;
uint16_t
length
;
};
/*
* Note that the pairing mid <-> QoS level only applies one-to-one if we only
* allow the subscription of one topic at a time. Otherwise we will have an
* ordered list of QoS levels corresponding to the order of topics.
*
* This could be part of a union of event data structures.
*/
struct
mqtt_suback_event
{
uint16_t
mid
;
mqtt_qos_level_t
qos_level
;
};
/* This is the MQTT message that is exposed to the end user. */
struct
mqtt_message
{
uint32_t
mid
;
char
topic
[
MQTT_MAX_TOPIC_LENGTH
+
1
];
/* +1 for string termination */
uint8_t
*
payload_chunk
;
uint16_t
payload_chunk_length
;
uint8_t
first_chunk
;
uint16_t
payload_length
;
uint16_t
payload_left
;
};
/* This struct represents a packet received from the MQTT server. */
struct
mqtt_in_packet
{
/* Used by the list interface, must be first in the struct. */
struct
mqtt_connection
*
next
;
/* Total bytes read so far. Compared to the remaining length to to decide when
* we've read the payload. */
uint32_t
byte_counter
;
uint8_t
packet_received
;
uint8_t
fhdr
;
uint16_t
remaining_length
;
uint16_t
mid
;
/* Helper variables needed to decode the remaining_length */
uint8_t
remaining_multiplier
;
uint8_t
has_remaining_length
;
uint8_t
remaining_length_bytes
;
/* Not the same as payload in the MQTT sense, it also contains the variable
* header.
*/
uint8_t
payload_pos
;
uint8_t
payload
[
MQTT_INPUT_BUFF_SIZE
];
/* Message specific data */
uint16_t
topic_len
;
uint16_t
topic_pos
;
uint8_t
topic_len_received
;
uint8_t
topic_received
;
};
/* This struct represents a packet sent to the MQTT server. */
struct
mqtt_out_packet
{
uint8_t
fhdr
;
uint32_t
remaining_length
;
uint8_t
remaining_length_enc
[
MQTT_MAX_REMAINING_LENGTH_BYTES
];
uint8_t
remaining_length_enc_bytes
;
uint16_t
mid
;
char
*
topic
;
uint16_t
topic_length
;
uint8_t
*
payload
;
uint32_t
payload_size
;
mqtt_qos_level_t
qos
;
mqtt_qos_state_t
qos_state
;
mqtt_retain_t
retain
;
};
/*---------------------------------------------------------------------------*/
/**
* \brief MQTT event callback function
* \param m A pointer to a MQTT connection
* \param event The event number
* \param data A user-defined pointer
*
* The MQTT socket event callback function gets called whenever there is an
* event on a MQTT connection, such as the connection getting connected
* or closed.
*/
typedef
void
(
*
mqtt_event_callback_t
)(
struct
mqtt_connection
*
m
,
mqtt_event_t
event
,
void
*
data
);
typedef
void
(
*
mqtt_topic_callback_t
)(
struct
mqtt_connection
*
m
,
struct
mqtt_message
*
msg
);
/*---------------------------------------------------------------------------*/
struct
mqtt_will
{
struct
mqtt_string
topic
;
struct
mqtt_string
message
;
mqtt_qos_level_t
qos
;
};
struct
mqtt_credentials
{
struct
mqtt_string
username
;
struct
mqtt_string
password
;
};
struct
mqtt_connection
{
/* Used by the list interface, must be first in the struct */
struct
mqtt_connection
*
next
;
struct
timer
t
;
struct
mqtt_string
client_id
;
uint8_t
connect_vhdr_flags
;
uint8_t
auto_reconnect
;
uint16_t
keep_alive
;
struct
ctimer
keep_alive_timer
;
uint8_t
waiting_for_pingresp
;
struct
mqtt_will
will
;
struct
mqtt_credentials
credentials
;
mqtt_conn_state_t
state
;
mqtt_event_callback_t
event_callback
;
/* Internal data */
uint16_t
mid_counter
;
/* Used for communication between MQTT API and APP */
uint8_t
out_queue_full
;
struct
process
*
app_process
;
/* Outgoing data related */
uint8_t
*
out_buffer_ptr
;
uint8_t
out_buffer
[
MQTT_TCP_OUTPUT_BUFF_SIZE
];
uint8_t
out_buffer_sent
;
struct
mqtt_out_packet
out_packet
;
struct
pt
out_proto_thread
;
uint32_t
out_write_pos
;
uint16_t
max_segment_size
;
/* Incoming data related */
uint8_t
in_buffer
[
MQTT_TCP_INPUT_BUFF_SIZE
];
struct
mqtt_in_packet
in_packet
;
struct
mqtt_message
in_publish_msg
;
/* TCP related information */
char
*
server_host
;
uip_ipaddr_t
server_ip
;
uint16_t
server_port
;
struct
tcp_socket
socket
;
};
/* This is the API exposed to the user. */
/*---------------------------------------------------------------------------*/
/**
* \brief Initializes the MQTT engine.
* \param conn A pointer to the MQTT connection.
* \param app_process A pointer to the application process handling the MQTT
* connection.
* \param client_id A pointer to the MQTT client ID.
* \param event_callback Callback function responsible for handling the
* callback from MQTT engine.
* \param max_segment_size The TCP segment size to use for this MQTT/TCP
* connection.
* \return MQTT_STATUS_OK or MQTT_STATUS_INVALID_ARGS_ERROR
*
* This function initializes the MQTT engine and shall be called before any
* other MQTT function.
*/
mqtt_status_t
mqtt_register
(
struct
mqtt_connection
*
conn
,
struct
process
*
app_process
,
char
*
client_id
,
mqtt_event_callback_t
event_callback
,
uint16_t
max_segment_size
);
/*---------------------------------------------------------------------------*/
/**
* \brief Connects to a MQTT broker.
* \param conn A pointer to the MQTT connection.
* \param host IP address of the broker to connect to.
* \param port Port of the broker to connect to, default is MQTT port is 1883.
* \param keep_alive Keep alive timer in seconds. Used by broker to handle
* client disc. Defines the maximum time interval between two messages
* from the client. Shall be min 1.5 x report interval.
* \return MQTT_STATUS_OK or an error status
*
* This function connects to a MQTT broker.
*/
mqtt_status_t
mqtt_connect
(
struct
mqtt_connection
*
conn
,
char
*
host
,
uint16_t
port
,
uint16_t
keep_alive
);
/*---------------------------------------------------------------------------*/
/**
* \brief Disconnects from a MQTT broker.
* \param conn A pointer to the MQTT connection.
*
* This function disconnects from a MQTT broker.
*/
void
mqtt_disconnect
(
struct
mqtt_connection
*
conn
);
/*---------------------------------------------------------------------------*/
/**
* \brief Subscribes to a MQTT topic.
* \param conn A pointer to the MQTT connection.
* \param mid A pointer to message ID.
* \param topic A pointer to the topic to subscribe to.
* \param qos_level Quality Of Service level to use. Currently supports 0, 1.
* \return MQTT_STATUS_OK or some error status
*
* This function subscribes to a topic on a MQTT broker.
*/
mqtt_status_t
mqtt_subscribe
(
struct
mqtt_connection
*
conn
,
uint16_t
*
mid
,
char
*
topic
,
mqtt_qos_level_t
qos_level
);
/*---------------------------------------------------------------------------*/
/**
* \brief Unsubscribes from a MQTT topic.
* \param conn A pointer to the MQTT connection.
* \param mid A pointer to message ID.
* \param topic A pointer to the topic to unsubscribe from.
* \return MQTT_STATUS_OK or some error status
*
* This function unsubscribes from a topic on a MQTT broker.
*/
mqtt_status_t
mqtt_unsubscribe
(
struct
mqtt_connection
*
conn
,
uint16_t
*
mid
,
char
*
topic
);
/*---------------------------------------------------------------------------*/
/**
* \brief Publish to a MQTT topic.
* \param conn A pointer to the MQTT connection.
* \param mid A pointer to message ID.
* \param topic A pointer to the topic to subscribe to.
* \param payload A pointer to the topic payload.
* \param payload_size Payload size.
* \param qos_level Quality Of Service level to use. Currently supports 0, 1.
* \param retain If the RETAIN flag is set to 1, in a PUBLISH Packet sent by a
* Client to a Server, the Server MUST store the Application Message
* and its QoS, so that it can be delivered to future subscribers whose
* subscriptions match its topic name
* \return MQTT_STATUS_OK or some error status
*
* This function publishes to a topic on a MQTT broker.
*/
mqtt_status_t
mqtt_publish
(
struct
mqtt_connection
*
conn
,
uint16_t
*
mid
,
char
*
topic
,
uint8_t
*
payload
,
uint32_t
payload_size
,
mqtt_qos_level_t
qos_level
,
mqtt_retain_t
retain
);
/*---------------------------------------------------------------------------*/
/**
* \brief Set the user name and password for a MQTT client.
* \param conn A pointer to the MQTT connection.
* \param username A pointer to the user name.
* \param password A pointer to the password.
*
* This function sets clients user name and password to use when connecting to
* a MQTT broker.
*/
void
mqtt_set_username_password
(
struct
mqtt_connection
*
conn
,
char
*
username
,
char
*
password
);
/*---------------------------------------------------------------------------*/
/**
* \brief Set the last will topic and message for a MQTT client.
* \param conn A pointer to the MQTT connection.
* \param topic A pointer to the Last Will topic.
* \param message A pointer to the Last Will message (payload).
* \param qos The desired QoS level.
*
* This function sets clients Last Will topic and message (payload).
* If the Will Flag is set to 1 (using the function) this indicates that,
* if the Connect request is accepted, a Will Message MUST be stored on the
* Server and associated with the Network Connection. The Will Message MUST
* be published when the Network Connection is subsequently closed.
*
* This functionality can be used to get notified that a device has
* disconnected from the broker.
*
*/
void
mqtt_set_last_will
(
struct
mqtt_connection
*
conn
,
char
*
topic
,
char
*
message
,
mqtt_qos_level_t
qos
);
#define mqtt_connected(conn) \
((conn)->state == MQTT_CONN_STATE_CONNECTED_TO_BROKER ? 1 : 0)
#define mqtt_ready(conn) \
(!(conn)->out_queue_full && mqtt_connected((conn)))
/*---------------------------------------------------------------------------*/
#endif
/* MQTT_H_ */
/*---------------------------------------------------------------------------*/
/**
* @}
* @}
*/
This diff is collapsed.
Click to expand it.
Preview
0%
Loading
Try again
or
attach a new file
.
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Save comment
Cancel
Please
register
or
sign in
to comment