Lesson 35 - Get Compute Auth Token Working

This commit is contained in:
Norman Lansing
2026-02-28 12:32:28 -05:00
parent 1d477ee42a
commit 4fde462bce
7743 changed files with 1397833 additions and 18 deletions

View File

@@ -0,0 +1,814 @@
#ifndef AWS_MQTT_MQTT5_CLIENT_H
#define AWS_MQTT_MQTT5_CLIENT_H
/**
* Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
* SPDX-License-Identifier: Apache-2.0.
*/
#include <aws/mqtt/mqtt.h>
#include <aws/io/retry_strategy.h>
#include <aws/mqtt/v5/mqtt5_types.h>
AWS_PUSH_SANE_WARNING_LEVEL
struct aws_allocator;
struct aws_client_bootstrap;
struct aws_host_resolution_config;
struct aws_http_message;
struct aws_mqtt5_client;
struct aws_mqtt5_client_lifecycle_event;
struct aws_tls_connection_options;
struct aws_socket_options;
/* public client-related enums */
/**
* Controls how the mqtt client should behave with respect to mqtt sessions.
*/
enum aws_mqtt5_client_session_behavior_type {
/**
* Maps to AWS_MQTT5_CSBT_CLEAN
*/
AWS_MQTT5_CSBT_DEFAULT,
/**
* Always join a new, clean session
*/
AWS_MQTT5_CSBT_CLEAN,
/**
* Always attempt to rejoin an existing session after an initial connection success.
*/
AWS_MQTT5_CSBT_REJOIN_POST_SUCCESS,
/**
* Always attempt to rejoin an existing session. Since the client does not support durable session persistence,
* this option is not guaranteed to be spec compliant because any unacknowledged qos1 publishes (which are
* part of the client session state) will not be present on the initial connection. Until we support
* durable session resumption, this option is technically spec-breaking, but useful.
*/
AWS_MQTT5_CSBT_REJOIN_ALWAYS,
};
/**
* Outbound topic aliasing behavior is controlled by this type.
*
* Topic alias behavior is described in https://docs.oasis-open.org/mqtt/mqtt/v5.0/os/mqtt-v5.0-os.html#_Toc3901113
*
* If the server allows topic aliasing, this setting controls how topic aliases are used on PUBLISH packets sent
* from the client to the server.
*
* If topic aliasing is not supported by the server, this setting has no effect and any attempts to directly
* manipulate the topic alias id in outbound publishes will be ignored.
*/
enum aws_mqtt5_client_outbound_topic_alias_behavior_type {
/**
* Maps to AWS_MQTT5_COTABT_DISABLED This keeps the client from being broken (by default) if the broker
* topic aliasing implementation has a problem.
*/
AWS_MQTT5_COTABT_DEFAULT,
/**
* Outbound aliasing is the user's responsibility. Client will cache and use
* previously-established aliases if they fall within the negotiated limits of the connection.
*
* The user must still always submit a full topic in their publishes because disconnections disrupt
* topic alias mappings unpredictably. The client will properly use the alias when the current connection
* has seen the alias binding already.
*/
AWS_MQTT5_COTABT_MANUAL,
/**
* Client ignores any user-specified topic aliasing and acts on the outbound alias set as an LRU cache.
*/
AWS_MQTT5_COTABT_LRU,
/**
* Completely disable outbound topic aliasing.
*/
AWS_MQTT5_COTABT_DISABLED
};
/**
* Inbound topic aliasing behavior is controlled by this type.
*
* Topic alias behavior is described in https://docs.oasis-open.org/mqtt/mqtt/v5.0/os/mqtt-v5.0-os.html#_Toc3901113
*
* This setting controls whether or not the client will send a positive topic alias maximum to the server
* in its CONNECT packets.
*
* If topic aliasing is not supported by the server, this setting has no net effect.
*/
enum aws_mqtt5_client_inbound_topic_alias_behavior_type {
/**
* Maps to AWS_MQTT5_CITABT_DISABLED
*/
AWS_MQTT5_CITABT_DEFAULT,
/**
* Allow the server to send PUBLISH packets to the client that use topic aliasing
*/
AWS_MQTT5_CITABT_ENABLED,
/**
* Forbid the server from sending PUBLISH packets to the client that use topic aliasing
*/
AWS_MQTT5_CITABT_DISABLED
};
/**
* Configuration struct for all client topic aliasing behavior. If this is left null, then all default options
* (as it zeroed) will be used.
*/
struct aws_mqtt5_client_topic_alias_options {
/**
* Controls what kind of outbound topic aliasing behavior the client should attempt to use.
*/
enum aws_mqtt5_client_outbound_topic_alias_behavior_type outbound_topic_alias_behavior;
/**
* If outbound topic aliasing is set to LRU, this controls the maximum size of the cache. If outbound topic
* aliasing is set to LRU and this is zero, a sensible default is used (25). If outbound topic aliasing is not
* set to LRU, then this setting has no effect.
*
* The final size of the cache is determined by the minimum of this setting and the value of the
* topic_alias_maximum property of the received CONNACK. If the received CONNACK does not have an explicit
* positive value for that field, outbound topic aliasing is disabled for the duration of that connection.
*/
uint16_t outbound_alias_cache_max_size;
/**
* Controls what kind of inbound topic aliasing behavior the client should use.
*
* Even if inbound topic aliasing is enabled, it is up to the server to choose whether or not to use it.
*/
enum aws_mqtt5_client_inbound_topic_alias_behavior_type inbound_topic_alias_behavior;
/**
* If inbound topic aliasing is enabled, this will control the size of the inbound alias cache. If inbound
* aliases are enabled and this is zero, then a sensible default will be used (25). If inbound aliases are
* disabled, this setting has no effect.
*
* Behaviorally, this value overrides anything present in the topic_alias_maximum field of
* the CONNECT packet options.
*/
uint16_t inbound_alias_cache_size;
};
/**
* Extended validation and flow control options
*
* Potentially a point of expansion in the future. We could add custom controls letting people override
* the Aws IOT Core limits based on their account properties. We could, with IoT Core support, add dynamic
* limit recognition via user properties as well.
*/
enum aws_mqtt5_extended_validation_and_flow_control_options {
/**
* Do not do any additional validation or flow control outside of the MQTT5 spec
*/
AWS_MQTT5_EVAFCO_NONE,
/**
* Apply additional client-side operational flow control that respects the
* default AWS IoT Core limits.
*
* Applies the following flow control:
* (1) Outbound throughput throttled to 512KB/s
* (2) Outbound publish TPS throttled to 100
*/
AWS_MQTT5_EVAFCO_AWS_IOT_CORE_DEFAULTS,
};
/**
* Controls how disconnects affect the queued and in-progress operations submitted to the client. Also controls
* how operations are handled while the client is not connected. In particular, if the client is not connected,
* then any operation that would be failed on disconnect (according to these rules) will be rejected.
*/
enum aws_mqtt5_client_operation_queue_behavior_type {
/*
* Maps to AWS_MQTT5_COQBT_FAIL_QOS0_PUBLISH_ON_DISCONNECT
*/
AWS_MQTT5_COQBT_DEFAULT,
/*
* Requeues QoS 1+ publishes on disconnect; unacked publishes go to the front, unprocessed publishes stay
* in place. All other operations (QoS 0 publishes, subscribe, unsubscribe) are failed.
*/
AWS_MQTT5_COQBT_FAIL_NON_QOS1_PUBLISH_ON_DISCONNECT,
/*
* Qos 0 publishes that are not complete at the time of disconnection are failed. Unacked QoS 1+ publishes are
* requeued at the head of the line for immediate retransmission on a session resumption. All other operations
* are requeued in original order behind any retransmissions.
*/
AWS_MQTT5_COQBT_FAIL_QOS0_PUBLISH_ON_DISCONNECT,
/*
* All operations that are not complete at the time of disconnection are failed, except those operations that
* the mqtt 5 spec requires to be retransmitted (unacked qos1+ publishes).
*/
AWS_MQTT5_COQBT_FAIL_ALL_ON_DISCONNECT,
};
/**
* Type of a client lifecycle event
*/
enum aws_mqtt5_client_lifecycle_event_type {
/**
* Emitted when the client begins an attempt to connect to the remote endpoint.
*
* Mandatory event fields: client, user_data
*/
AWS_MQTT5_CLET_ATTEMPTING_CONNECT,
/**
* Emitted after the client connects to the remote endpoint and receives a successful CONNACK.
* Every ATTEMPTING_CONNECT will be followed by exactly one CONNECTION_SUCCESS or one CONNECTION_FAILURE.
*
* Mandatory event fields: client, user_data, connack_data, settings
*/
AWS_MQTT5_CLET_CONNECTION_SUCCESS,
/**
* Emitted at any point during the connection process when it has conclusively failed.
* Every ATTEMPTING_CONNECT will be followed by exactly one CONNECTION_SUCCESS or one CONNECTION_FAILURE.
*
* Mandatory event fields: client, user_data, error_code
* Conditional event fields: connack_data
*/
AWS_MQTT5_CLET_CONNECTION_FAILURE,
/**
* Lifecycle event containing information about a disconnect. Every CONNECTION_SUCCESS will eventually be
* followed by one and only one DISCONNECTION.
*
* Mandatory event fields: client, user_data, error_code
* Conditional event fields: disconnect_data
*/
AWS_MQTT5_CLET_DISCONNECTION,
/**
* Lifecycle event notifying the user that the client has entered the STOPPED state. Entering this state will
* cause the client to wipe all MQTT session state.
*
* Mandatory event fields: client, user_data
*/
AWS_MQTT5_CLET_STOPPED,
};
/* client-related callback function signatures */
/**
* Signature of the continuation function to be called after user-code transforms a websocket handshake request
*/
typedef void(aws_mqtt5_transform_websocket_handshake_complete_fn)(
struct aws_http_message *request,
int error_code,
void *complete_ctx);
/**
* Signature of the websocket handshake request transformation function. After transformation, the completion
* function must be invoked to send the request.
*/
typedef void(aws_mqtt5_transform_websocket_handshake_fn)(
struct aws_http_message *request,
void *user_data,
aws_mqtt5_transform_websocket_handshake_complete_fn *complete_fn,
void *complete_ctx);
/**
* Callback signature for mqtt5 client lifecycle events.
*/
typedef void(aws_mqtt5_client_connection_event_callback_fn)(const struct aws_mqtt5_client_lifecycle_event *event);
/**
* Signature of callback to invoke on Publish success/failure.
*/
typedef void(aws_mqtt5_publish_completion_fn)(
enum aws_mqtt5_packet_type packet_type,
const void *packet,
int error_code,
void *complete_ctx);
/**
* Signature of callback to invoke on Subscribe success/failure.
*/
typedef void(aws_mqtt5_subscribe_completion_fn)(
const struct aws_mqtt5_packet_suback_view *suback,
int error_code,
void *complete_ctx);
/**
* Signature of callback to invoke on Unsubscribe success/failure.
*/
typedef void(aws_mqtt5_unsubscribe_completion_fn)(
const struct aws_mqtt5_packet_unsuback_view *unsuback,
int error_code,
void *complete_ctx);
/**
* Signature of callback to invoke on Publish received
*/
typedef void(aws_mqtt5_publish_received_fn)(const struct aws_mqtt5_packet_publish_view *publish, void *user_data);
/**
* Signature of a listener publish received callback that returns an indicator whether or not the publish
* was handled by the listener.
*/
typedef bool(
aws_mqtt5_listener_publish_received_fn)(const struct aws_mqtt5_packet_publish_view *publish, void *user_data);
/**
* Signature of callback to invoke when a DISCONNECT is fully written to the socket (or fails to be)
*/
typedef void(aws_mqtt5_disconnect_completion_fn)(int error_code, void *complete_ctx);
/**
* Signature of callback invoked when a client has completely destroyed itself
*/
typedef void(aws_mqtt5_client_termination_completion_fn)(void *complete_ctx);
/* operation completion options structures */
/**
* Completion options for the Publish operation
*/
struct aws_mqtt5_publish_completion_options {
aws_mqtt5_publish_completion_fn *completion_callback;
void *completion_user_data;
/** Overrides the client's ack timeout with this value, for this operation only */
uint32_t ack_timeout_seconds_override;
};
/**
* Completion options for the Subscribe operation
*/
struct aws_mqtt5_subscribe_completion_options {
aws_mqtt5_subscribe_completion_fn *completion_callback;
void *completion_user_data;
/** Overrides the client's ack timeout with this value, for this operation only */
uint32_t ack_timeout_seconds_override;
};
/**
* Completion options for the Unsubscribe operation
*/
struct aws_mqtt5_unsubscribe_completion_options {
aws_mqtt5_unsubscribe_completion_fn *completion_callback;
void *completion_user_data;
/** Overrides the client's ack timeout with this value, for this operation only */
uint32_t ack_timeout_seconds_override;
};
/**
* Completion options for the a DISCONNECT operation
*/
struct aws_mqtt5_disconnect_completion_options {
aws_mqtt5_disconnect_completion_fn *completion_callback;
void *completion_user_data;
};
/**
* Mqtt behavior settings that are dynamically negotiated as part of the CONNECT/CONNACK exchange.
*/
struct aws_mqtt5_negotiated_settings {
/**
* The maximum QoS used between the server and client.
*/
enum aws_mqtt5_qos maximum_qos;
/**
* the amount of time in seconds the server will retain the session after a disconnect.
*/
uint32_t session_expiry_interval;
/**
* the number of QoS 1 and QoS2 publications the server is willing to process concurrently.
*/
uint16_t receive_maximum_from_server;
/**
* the maximum packet size the server is willing to accept.
*/
uint32_t maximum_packet_size_to_server;
/**
* the highest value that the server will accept as a Topic Alias sent by the client.
*/
uint16_t topic_alias_maximum_to_server;
/**
* the highest value that the client will accept as a Topic Alias sent by the server.
*/
uint16_t topic_alias_maximum_to_client;
/**
* the amount of time in seconds before the server will disconnect the client for inactivity.
*/
uint16_t server_keep_alive;
/**
* whether the server supports retained messages.
*/
bool retain_available;
/**
* whether the server supports wildcard subscriptions.
*/
bool wildcard_subscriptions_available;
/**
* whether the server supports subscription identifiers
*/
bool subscription_identifiers_available;
/**
* whether the server supports shared subscriptions
*/
bool shared_subscriptions_available;
/**
* whether the client has rejoined an existing session.
*/
bool rejoined_session;
struct aws_byte_buf client_id_storage;
};
/**
* Contains some simple statistics about the current state of the client's queue of operations
*/
struct aws_mqtt5_client_operation_statistics {
/*
* total number of operations submitted to the client that have not yet been completed. Unacked operations
* are a subset of this.
*/
uint64_t incomplete_operation_count;
/*
* total packet size of operations submitted to the client that have not yet been completed. Unacked operations
* are a subset of this.
*/
uint64_t incomplete_operation_size;
/*
* total number of operations that have been sent to the server and are waiting for a corresponding ACK before
* they can be completed.
*/
uint64_t unacked_operation_count;
/*
* total packet size of operations that have been sent to the server and are waiting for a corresponding ACK before
* they can be completed.
*/
uint64_t unacked_operation_size;
};
/**
* Details about a client lifecycle event.
*/
struct aws_mqtt5_client_lifecycle_event {
/**
* Type of event this is.
*/
enum aws_mqtt5_client_lifecycle_event_type event_type;
/**
* Client this event corresponds to. Necessary (can't be replaced with user data) because the client
* doesn't exist at the time the event callback user data is configured.
*/
struct aws_mqtt5_client *client;
/**
* Aws-c-* error code associated with the event
*/
int error_code;
/**
* User data associated with the client's lifecycle event handler. Set with client configuration.
*/
void *user_data;
/**
* If this event was caused by receiving a CONNACK, this will be a view of that packet.
*/
const struct aws_mqtt5_packet_connack_view *connack_data;
/**
* If this is a successful connection establishment, this will contain the negotiated mqtt5 behavioral settings
*/
const struct aws_mqtt5_negotiated_settings *settings;
/**
* If this event was caused by receiving a DISCONNECT, this will be a view of that packet.
*/
const struct aws_mqtt5_packet_disconnect_view *disconnect_data;
};
/**
* Basic mqtt5 client configuration struct.
*
* Contains desired connection properties
* Configuration that represents properties of the mqtt5 CONNECT packet go in the connect view (connect_options)
*/
struct aws_mqtt5_client_options {
/**
* Host to establish mqtt connections to
*/
struct aws_byte_cursor host_name;
/**
* Port to establish mqtt connections to
*/
uint32_t port;
/**
* Client bootstrap to use whenever this client establishes a connection
*/
struct aws_client_bootstrap *bootstrap;
/**
* Socket options to use whenever this client establishes a connection
*/
const struct aws_socket_options *socket_options;
/**
* (Optional) Tls options to use whenever this client establishes a connection
*/
const struct aws_tls_connection_options *tls_options;
/**
* (Optional) Http proxy options to use whenever this client establishes a connection
*/
const struct aws_http_proxy_options *http_proxy_options;
/**
* (Optional) Websocket handshake transformation function and user data. Websockets are used if the
* transformation function is non-null.
*/
aws_mqtt5_transform_websocket_handshake_fn *websocket_handshake_transform;
void *websocket_handshake_transform_user_data;
/**
* All CONNECT-related options, includes the will configuration, if desired
*/
const struct aws_mqtt5_packet_connect_view *connect_options;
/**
* Controls session rejoin behavior
*/
enum aws_mqtt5_client_session_behavior_type session_behavior;
/**
* Controls if any additional AWS-specific validation or flow control should be performed by the client.
*/
enum aws_mqtt5_extended_validation_and_flow_control_options extended_validation_and_flow_control_options;
/**
* Controls how the client treats queued/in-progress operations when the connection drops for any reason.
*/
enum aws_mqtt5_client_operation_queue_behavior_type offline_queue_behavior;
/**
* Controls the exponential backoff behavior when the client is waiting to reconnect.
*
* See: https://aws.amazon.com/blogs/architecture/exponential-backoff-and-jitter/
*/
enum aws_exponential_backoff_jitter_mode retry_jitter_mode;
/**
* Minimum amount of time in ms to wait before attempting to reconnect. If this is zero, a default of 1000 ms will
* be used.
*/
uint64_t min_reconnect_delay_ms;
/**
* Maximum amount of time in ms to wait before attempting to reconnect. If this is zero, a default of 120000 ms
* will be used.
*/
uint64_t max_reconnect_delay_ms;
/**
* Amount of time that must elapse with a good connection before the reconnect delay is reset to the minimum. If
* this zero, a default of 30000 ms will be used.
*/
uint64_t min_connected_time_to_reset_reconnect_delay_ms;
/**
* Time interval to wait after sending a PINGREQ for a PINGRESP to arrive. If one does not arrive, the connection
* will be shut down. If this is zero, a default of 30000 ms will be used.
*/
uint32_t ping_timeout_ms;
/**
* Time interval to wait after sending a CONNECT request for a CONNACK to arrive. If one does not arrive, the
* connection will be shut down. If this zero, a default of 20000 ms will be used.
*/
uint32_t connack_timeout_ms;
/**
* Time interval to wait for an ack after sending a SUBSCRIBE, UNSUBSCRIBE, or PUBLISH with QoS 1+ before
* failing the packet, notifying the client of failure, and removing it. If this is zero, a default of 60 seconds
* will be used.
*/
uint32_t ack_timeout_seconds;
/**
* Controls how the client uses mqtt5 topic aliasing. If NULL, zero-based defaults will be used.
*/
const struct aws_mqtt5_client_topic_alias_options *topic_aliasing_options;
/**
* Callback for received publish packets
*/
aws_mqtt5_publish_received_fn *publish_received_handler;
void *publish_received_handler_user_data;
/**
* Callback and user data for all client lifecycle events.
* Life cycle events include:
* ConnectionSuccess
* ConnectionFailure,
* Disconnect
* (client) Stopped
*
* Disconnect lifecycle events are 1-1 with -- strictly after -- ConnectionSuccess events.
*/
aws_mqtt5_client_connection_event_callback_fn *lifecycle_event_handler;
void *lifecycle_event_handler_user_data;
/**
* Callback for when the client has completely destroyed itself
*/
aws_mqtt5_client_termination_completion_fn *client_termination_handler;
void *client_termination_handler_user_data;
/**
* Options to override aspects of DNS resolution. If unspecified, use a default that matches the regular
* configuration but changes the refresh frequency to a value that prevents DNS pinging.
*/
struct aws_host_resolution_config *host_resolution_override;
};
AWS_EXTERN_C_BEGIN
/**
* Creates a new mqtt5 client using the supplied configuration
*
* @param allocator allocator to use with all memory operations related to this client's creation and operation
* @param options mqtt5 client configuration
* @return a new mqtt5 client or NULL
*/
AWS_MQTT_API
struct aws_mqtt5_client *aws_mqtt5_client_new(
struct aws_allocator *allocator,
const struct aws_mqtt5_client_options *options);
/**
* Acquires a reference to an mqtt5 client
*
* @param client client to acquire a reference to. May be NULL.
* @return what was passed in as the client (a client or NULL)
*/
AWS_MQTT_API
struct aws_mqtt5_client *aws_mqtt5_client_acquire(struct aws_mqtt5_client *client);
/**
* Release a reference to an mqtt5 client. When the client ref count drops to zero, the client will automatically
* trigger a stop and once the stop completes, the client will delete itself.
*
* @param client client to release a reference to. May be NULL.
* @return NULL
*/
AWS_MQTT_API
struct aws_mqtt5_client *aws_mqtt5_client_release(struct aws_mqtt5_client *client);
/**
* Asynchronous notify to the mqtt5 client that you want it to attempt to connect to the configured endpoint.
* The client will attempt to stay connected using the properties of the reconnect-related parameters
* in the mqtt5 client configuration.
*
* @param client mqtt5 client to start
* @return success/failure in the synchronous logic that kicks off the start process
*/
AWS_MQTT_API
int aws_mqtt5_client_start(struct aws_mqtt5_client *client);
/**
* Asynchronous notify to the mqtt5 client that you want it to transition to the stopped state. When the client
* reaches the stopped state, all session state is erased.
*
* @param client mqtt5 client to stop
* @param disconnect_options (optional) properties of a DISCONNECT packet to send as part of the shutdown process
* @return success/failure in the synchronous logic that kicks off the stop process
*/
AWS_MQTT_API
int aws_mqtt5_client_stop(
struct aws_mqtt5_client *client,
const struct aws_mqtt5_packet_disconnect_view *disconnect_options,
const struct aws_mqtt5_disconnect_completion_options *completion_options);
/**
* Queues a Publish operation in an mqtt5 client
*
* @param client mqtt5 client to queue a Publish for
* @param publish_options configuration options for the Publish operation
* @param completion_options completion callback configuration. Successful QoS 0 publishes invoke the callback when
* the data has been written to the socket. Successful QoS1+ publishes invoke the callback when the corresponding ack
* is received. Unsuccessful publishes invoke the callback at the point in time a failure condition is reached.
* @return success/failure in the synchronous logic that kicks off the publish operation
*/
AWS_MQTT_API
int aws_mqtt5_client_publish(
struct aws_mqtt5_client *client,
const struct aws_mqtt5_packet_publish_view *publish_options,
const struct aws_mqtt5_publish_completion_options *completion_options);
/**
* Queues a Subscribe operation in an mqtt5 client
*
* @param client mqtt5 client to queue a Subscribe for
* @param subscribe_options configuration options for the Subscribe operation
* @param completion_options Completion callback configuration. Invoked when the corresponding SUBACK is received or
* a failure condition is reached. An error code implies complete failure of the subscribe, while a success code
* implies the user must still check all of the SUBACK's reason codes for per-subscription feedback.
* @return success/failure in the synchronous logic that kicks off the Subscribe operation
*/
AWS_MQTT_API
int aws_mqtt5_client_subscribe(
struct aws_mqtt5_client *client,
const struct aws_mqtt5_packet_subscribe_view *subscribe_options,
const struct aws_mqtt5_subscribe_completion_options *completion_options);
/**
* Queues an Unsubscribe operation in an mqtt5 client
*
* @param client mqtt5 client to queue an Unsubscribe for
* @param unsubscribe_options configuration options for the Unsubscribe operation
* @param completion_options Completion callback configuration. Invoked when the corresponding UNSUBACK is received or
* a failure condition is reached. An error code implies complete failure of the unsubscribe, while a success code
* implies the user must still check all of the UNSUBACK's reason codes for per-topic-filter feedback.
* @return success/failure in the synchronous logic that kicks off the Unsubscribe operation
*/
AWS_MQTT_API
int aws_mqtt5_client_unsubscribe(
struct aws_mqtt5_client *client,
const struct aws_mqtt5_packet_unsubscribe_view *unsubscribe_options,
const struct aws_mqtt5_unsubscribe_completion_options *completion_options);
/**
* Queries the client's internal statistics for incomplete operations.
* @param client client to get statistics for
* @param stats set of incomplete operation statistics
*/
AWS_MQTT_API
void aws_mqtt5_client_get_stats(struct aws_mqtt5_client *client, struct aws_mqtt5_client_operation_statistics *stats);
/* Misc related type APIs */
/**
* Initializes the Client ID byte buf in negotiated settings
*
* @param allocator allocator to use for memory allocation
* @param negotiated_settings settings to apply client id to
* @param client_id client id to set
*/
AWS_MQTT_API int aws_mqtt5_negotiated_settings_init(
struct aws_allocator *allocator,
struct aws_mqtt5_negotiated_settings *negotiated_settings,
const struct aws_byte_cursor *client_id);
/**
* Makes an owning copy of a negotiated settings structure.
*
* @param source settings to copy from
* @param dest settings to copy into. Must be in a zeroed or initialized state because it gets clean up
* called on it as the first step of the copy process.
* @return success/failure
*
* Used in downstream.
*/
AWS_MQTT_API int aws_mqtt5_negotiated_settings_copy(
const struct aws_mqtt5_negotiated_settings *source,
struct aws_mqtt5_negotiated_settings *dest);
/**
* Clean up owned memory in negotiated_settings
*
* @param negotiated_settings settings to clean up
*/
AWS_MQTT_API void aws_mqtt5_negotiated_settings_clean_up(struct aws_mqtt5_negotiated_settings *negotiated_settings);
AWS_EXTERN_C_END
AWS_POP_SANE_WARNING_LEVEL
#endif /* AWS_MQTT_MQTT5_CLIENT_H */

View File

@@ -0,0 +1,88 @@
/**
* Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
* SPDX-License-Identifier: Apache-2.0.
*/
#ifndef AWS_MQTT_MQTT5_LISTENER_H
#define AWS_MQTT_MQTT5_LISTENER_H
#include <aws/mqtt/mqtt.h>
#include <aws/mqtt/v5/mqtt5_client.h>
AWS_PUSH_SANE_WARNING_LEVEL
/*
* Callback signature for when an mqtt5 listener has completely destroyed itself.
*/
typedef void(aws_mqtt5_listener_termination_completion_fn)(void *complete_ctx);
/**
* A record that tracks MQTT5 client callbacks which can be dynamically injected via a listener.
*/
struct aws_mqtt5_callback_set {
aws_mqtt5_listener_publish_received_fn *listener_publish_received_handler;
void *listener_publish_received_handler_user_data;
aws_mqtt5_client_connection_event_callback_fn *lifecycle_event_handler;
void *lifecycle_event_handler_user_data;
};
/**
* Configuration options for MQTT5 listener objects.
*/
struct aws_mqtt5_listener_config {
/**
* MQTT5 client to listen to events on
*/
struct aws_mqtt5_client *client;
/**
* Callbacks to invoke when events occur on the MQTT5 client
*/
struct aws_mqtt5_callback_set listener_callbacks;
/**
* Listener destruction is asynchronous and thus requires a termination callback and associated user data
* to notify the user that the listener has been fully destroyed and no further events will be received.
*/
aws_mqtt5_listener_termination_completion_fn *termination_callback;
void *termination_callback_user_data;
};
AWS_EXTERN_C_BEGIN
/**
* Creates a new MQTT5 listener object. For as long as the listener lives, incoming publishes and lifecycle events
* will be forwarded to the callbacks configured on the listener.
*
* @param allocator allocator to use
* @param config listener configuration
* @return a new aws_mqtt5_listener object
*/
AWS_MQTT_API struct aws_mqtt5_listener *aws_mqtt5_listener_new(
struct aws_allocator *allocator,
struct aws_mqtt5_listener_config *config);
/**
* Adds a reference to an mqtt5 listener.
*
* @param listener listener to add a reference to
* @return the listener object
*/
AWS_MQTT_API struct aws_mqtt5_listener *aws_mqtt5_listener_acquire(struct aws_mqtt5_listener *listener);
/**
* Removes a reference to an mqtt5 listener. When the reference count drops to zero, the listener's asynchronous
* destruction will be started.
*
* @param listener listener to remove a reference from
* @return NULL
*/
AWS_MQTT_API struct aws_mqtt5_listener *aws_mqtt5_listener_release(struct aws_mqtt5_listener *listener);
AWS_EXTERN_C_END
AWS_POP_SANE_WARNING_LEVEL
#endif /* AWS_MQTT_MQTT5_LISTENER_H */

View File

@@ -0,0 +1,331 @@
#ifndef AWS_MQTT_MQTT5_PACKET_STORAGE_H
#define AWS_MQTT_MQTT5_PACKET_STORAGE_H
/**
* Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
* SPDX-License-Identifier: Apache-2.0.
*/
#include <aws/mqtt/mqtt.h>
#include <aws/mqtt/v5/mqtt5_types.h>
AWS_PUSH_SANE_WARNING_LEVEL
struct aws_mqtt5_user_property_set {
struct aws_array_list properties;
};
struct aws_mqtt5_packet_connect_storage {
struct aws_allocator *allocator;
struct aws_mqtt5_packet_connect_view storage_view;
struct aws_byte_cursor username;
struct aws_byte_cursor password;
uint32_t session_expiry_interval_seconds;
uint8_t request_response_information;
uint8_t request_problem_information;
uint16_t receive_maximum;
uint16_t topic_alias_maximum;
uint32_t maximum_packet_size_bytes;
struct aws_mqtt5_packet_publish_storage *will;
uint32_t will_delay_interval_seconds;
struct aws_mqtt5_user_property_set user_properties;
struct aws_byte_cursor authentication_method;
struct aws_byte_cursor authentication_data;
struct aws_byte_buf storage;
};
struct aws_mqtt5_packet_connack_storage {
struct aws_allocator *allocator;
struct aws_mqtt5_packet_connack_view storage_view;
uint32_t session_expiry_interval;
uint16_t receive_maximum;
enum aws_mqtt5_qos maximum_qos;
bool retain_available;
uint32_t maximum_packet_size;
struct aws_byte_cursor assigned_client_identifier;
uint16_t topic_alias_maximum;
struct aws_byte_cursor reason_string;
bool wildcard_subscriptions_available;
bool subscription_identifiers_available;
bool shared_subscriptions_available;
uint16_t server_keep_alive;
struct aws_byte_cursor response_information;
struct aws_byte_cursor server_reference;
struct aws_byte_cursor authentication_method;
struct aws_byte_cursor authentication_data;
struct aws_mqtt5_user_property_set user_properties;
struct aws_byte_buf storage;
};
struct aws_mqtt5_packet_suback_storage {
struct aws_allocator *allocator;
struct aws_mqtt5_packet_suback_view storage_view;
struct aws_byte_cursor reason_string;
struct aws_mqtt5_user_property_set user_properties;
struct aws_array_list reason_codes;
struct aws_byte_buf storage;
};
struct aws_mqtt5_packet_unsuback_storage {
struct aws_allocator *allocator;
struct aws_mqtt5_packet_unsuback_view storage_view;
struct aws_byte_cursor reason_string;
struct aws_mqtt5_user_property_set user_properties;
struct aws_array_list reason_codes;
struct aws_byte_buf storage;
};
struct aws_mqtt5_packet_publish_storage {
struct aws_mqtt5_packet_publish_view storage_view;
enum aws_mqtt5_payload_format_indicator payload_format;
uint32_t message_expiry_interval_seconds;
uint16_t topic_alias;
struct aws_byte_cursor response_topic;
struct aws_byte_cursor correlation_data;
struct aws_byte_cursor content_type;
struct aws_mqtt5_user_property_set user_properties;
struct aws_array_list subscription_identifiers;
struct aws_byte_buf storage;
};
struct aws_mqtt5_packet_puback_storage {
struct aws_mqtt5_packet_puback_view storage_view;
struct aws_byte_cursor reason_string;
struct aws_mqtt5_user_property_set user_properties;
struct aws_byte_buf storage;
};
struct aws_mqtt5_packet_disconnect_storage {
struct aws_mqtt5_packet_disconnect_view storage_view;
uint32_t session_expiry_interval_seconds;
struct aws_byte_cursor reason_string;
struct aws_mqtt5_user_property_set user_properties;
struct aws_byte_cursor server_reference;
struct aws_byte_buf storage;
};
struct aws_mqtt5_packet_subscribe_storage {
struct aws_mqtt5_packet_subscribe_view storage_view;
uint32_t subscription_identifier;
struct aws_array_list subscriptions;
struct aws_mqtt5_user_property_set user_properties;
struct aws_byte_buf storage;
};
struct aws_mqtt5_packet_unsubscribe_storage {
struct aws_mqtt5_packet_unsubscribe_view storage_view;
struct aws_array_list topic_filters;
struct aws_mqtt5_user_property_set user_properties;
struct aws_byte_buf storage;
};
AWS_EXTERN_C_BEGIN
/* User properties */
AWS_MQTT_API int aws_mqtt5_user_property_set_init_with_storage(
struct aws_mqtt5_user_property_set *property_set,
struct aws_allocator *allocator,
struct aws_byte_buf *storage_buffer,
size_t property_count,
const struct aws_mqtt5_user_property *properties);
AWS_MQTT_API void aws_mqtt5_user_property_set_clean_up(struct aws_mqtt5_user_property_set *property_set);
AWS_MQTT_API size_t aws_mqtt5_user_property_set_size(const struct aws_mqtt5_user_property_set *property_set);
/* Connect */
AWS_MQTT_API int aws_mqtt5_packet_connect_storage_init(
struct aws_mqtt5_packet_connect_storage *connect_storage,
struct aws_allocator *allocator,
const struct aws_mqtt5_packet_connect_view *connect_options);
AWS_MQTT_API int aws_mqtt5_packet_connect_storage_init_from_external_storage(
struct aws_mqtt5_packet_connect_storage *connect_storage,
struct aws_allocator *allocator);
AWS_MQTT_API void aws_mqtt5_packet_connect_storage_clean_up(struct aws_mqtt5_packet_connect_storage *connect_storage);
/* Connack */
AWS_MQTT_API int aws_mqtt5_packet_connack_storage_init(
struct aws_mqtt5_packet_connack_storage *connack_storage,
struct aws_allocator *allocator,
const struct aws_mqtt5_packet_connack_view *connack_options);
AWS_MQTT_API int aws_mqtt5_packet_connack_storage_init_from_external_storage(
struct aws_mqtt5_packet_connack_storage *connack_storage,
struct aws_allocator *allocator);
AWS_MQTT_API void aws_mqtt5_packet_connack_storage_clean_up(struct aws_mqtt5_packet_connack_storage *connack_storage);
/* Disconnect */
AWS_MQTT_API int aws_mqtt5_packet_disconnect_storage_init(
struct aws_mqtt5_packet_disconnect_storage *disconnect_storage,
struct aws_allocator *allocator,
const struct aws_mqtt5_packet_disconnect_view *disconnect_options);
AWS_MQTT_API int aws_mqtt5_packet_disconnect_storage_init_from_external_storage(
struct aws_mqtt5_packet_disconnect_storage *disconnect_storage,
struct aws_allocator *allocator);
AWS_MQTT_API void aws_mqtt5_packet_disconnect_storage_clean_up(
struct aws_mqtt5_packet_disconnect_storage *disconnect_storage);
/* Publish */
AWS_MQTT_API int aws_mqtt5_packet_publish_storage_init(
struct aws_mqtt5_packet_publish_storage *publish_storage,
struct aws_allocator *allocator,
const struct aws_mqtt5_packet_publish_view *publish_options);
AWS_MQTT_API int aws_mqtt5_packet_publish_storage_init_from_external_storage(
struct aws_mqtt5_packet_publish_storage *publish_storage,
struct aws_allocator *allocator);
AWS_MQTT_API void aws_mqtt5_packet_publish_storage_clean_up(struct aws_mqtt5_packet_publish_storage *publish_storage);
/* Puback */
AWS_MQTT_API int aws_mqtt5_packet_puback_storage_init(
struct aws_mqtt5_packet_puback_storage *puback_storage,
struct aws_allocator *allocator,
const struct aws_mqtt5_packet_puback_view *puback_view);
AWS_MQTT_API int aws_mqtt5_packet_puback_storage_init_from_external_storage(
struct aws_mqtt5_packet_puback_storage *puback_storage,
struct aws_allocator *allocator);
AWS_MQTT_API void aws_mqtt5_packet_puback_storage_clean_up(struct aws_mqtt5_packet_puback_storage *puback_storage);
/* Subscribe */
AWS_MQTT_API int aws_mqtt5_packet_subscribe_storage_init(
struct aws_mqtt5_packet_subscribe_storage *subscribe_storage,
struct aws_allocator *allocator,
const struct aws_mqtt5_packet_subscribe_view *subscribe_options);
AWS_MQTT_API int aws_mqtt5_packet_subscribe_storage_init_from_external_storage(
struct aws_mqtt5_packet_subscribe_storage *subscribe_storage,
struct aws_allocator *allocator);
AWS_MQTT_API void aws_mqtt5_packet_subscribe_storage_clean_up(
struct aws_mqtt5_packet_subscribe_storage *subscribe_storage);
/* Suback */
AWS_MQTT_API int aws_mqtt5_packet_suback_storage_init(
struct aws_mqtt5_packet_suback_storage *suback_storage,
struct aws_allocator *allocator,
const struct aws_mqtt5_packet_suback_view *suback_view);
AWS_MQTT_API int aws_mqtt5_packet_suback_storage_init_from_external_storage(
struct aws_mqtt5_packet_suback_storage *suback_storage,
struct aws_allocator *allocator);
AWS_MQTT_API void aws_mqtt5_packet_suback_storage_clean_up(struct aws_mqtt5_packet_suback_storage *suback_storage);
/* Unsubscribe */
AWS_MQTT_API int aws_mqtt5_packet_unsubscribe_storage_init(
struct aws_mqtt5_packet_unsubscribe_storage *unsubscribe_storage,
struct aws_allocator *allocator,
const struct aws_mqtt5_packet_unsubscribe_view *unsubscribe_options);
AWS_MQTT_API int aws_mqtt5_packet_unsubscribe_storage_init_from_external_storage(
struct aws_mqtt5_packet_unsubscribe_storage *unsubscribe_storage,
struct aws_allocator *allocator);
AWS_MQTT_API void aws_mqtt5_packet_unsubscribe_storage_clean_up(
struct aws_mqtt5_packet_unsubscribe_storage *unsubscribe_storage);
/* Unsuback */
AWS_MQTT_API int aws_mqtt5_packet_unsuback_storage_init(
struct aws_mqtt5_packet_unsuback_storage *unsuback_storage,
struct aws_allocator *allocator,
const struct aws_mqtt5_packet_unsuback_view *unsuback_view);
AWS_MQTT_API int aws_mqtt5_packet_unsuback_storage_init_from_external_storage(
struct aws_mqtt5_packet_unsuback_storage *unsuback_storage,
struct aws_allocator *allocator);
AWS_MQTT_API void aws_mqtt5_packet_unsuback_storage_clean_up(
struct aws_mqtt5_packet_unsuback_storage *unsuback_storage);
AWS_EXTERN_C_END
AWS_POP_SANE_WARNING_LEVEL
#endif /* AWS_MQTT_MQTT5_PACKET_STORAGE_H */

View File

@@ -0,0 +1,481 @@
#ifndef AWS_MQTT_MQTT5_TYPES_H
#define AWS_MQTT_MQTT5_TYPES_H
/**
* Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
* SPDX-License-Identifier: Apache-2.0.
*/
#include <aws/mqtt/mqtt.h>
#include <aws/common/array_list.h>
#include <aws/common/byte_buf.h>
AWS_PUSH_SANE_WARNING_LEVEL
/**
* Some artificial (non-MQTT spec specified) limits that we place on input packets (publish, subscribe, unsubscibe)
* which lets us safely do the various packet size calculations with a bare minimum of checked arithmetic.
*
* I don't see any conceivable use cases why you'd want more than this, but they are relaxable to some degree.
*
* TODO: Add some static assert calculations that verify that we can't possibly overflow against the maximum value
* of a variable length integer for relevant packet size encodings that are absolute worst-case against these limits.
*/
#define AWS_MQTT5_CLIENT_MAXIMUM_USER_PROPERTIES 1024
#define AWS_MQTT5_CLIENT_MAXIMUM_SUBSCRIPTIONS_PER_SUBSCRIBE 1024
#define AWS_MQTT5_CLIENT_MAXIMUM_TOPIC_FILTERS_PER_UNSUBSCRIBE 1024
/**
* Over-the-wire packet id as defined in the mqtt spec. Allocated at the point in time when the packet is
* is next to go down the channel and about to be encoded into an io message buffer.
*
* https://docs.oasis-open.org/mqtt/mqtt/v5.0/os/mqtt-v5.0-os.html#_Toc3901026
*/
typedef uint16_t aws_mqtt5_packet_id_t;
/**
* MQTT Message delivery quality of service.
* Enum values match mqtt spec encoding values.
*
* https://docs.oasis-open.org/mqtt/mqtt/v5.0/os/mqtt-v5.0-os.html#_Toc3901234
*/
enum aws_mqtt5_qos {
/** https://docs.oasis-open.org/mqtt/mqtt/v5.0/os/mqtt-v5.0-os.html#_Toc3901235 */
AWS_MQTT5_QOS_AT_MOST_ONCE = 0x0,
/** https://docs.oasis-open.org/mqtt/mqtt/v5.0/os/mqtt-v5.0-os.html#_Toc3901236 */
AWS_MQTT5_QOS_AT_LEAST_ONCE = 0x1,
/** https://docs.oasis-open.org/mqtt/mqtt/v5.0/os/mqtt-v5.0-os.html#_Toc3901237 */
AWS_MQTT5_QOS_EXACTLY_ONCE = 0x2,
};
/**
* Server return code for CONNECT attempts.
* Enum values match mqtt spec encoding values.
*
* https://docs.oasis-open.org/mqtt/mqtt/v5.0/os/mqtt-v5.0-os.html#_Toc3901079
*/
enum aws_mqtt5_connect_reason_code {
AWS_MQTT5_CRC_SUCCESS = 0,
AWS_MQTT5_CRC_UNSPECIFIED_ERROR = 128,
AWS_MQTT5_CRC_MALFORMED_PACKET = 129,
AWS_MQTT5_CRC_PROTOCOL_ERROR = 130,
AWS_MQTT5_CRC_IMPLEMENTATION_SPECIFIC_ERROR = 131,
AWS_MQTT5_CRC_UNSUPPORTED_PROTOCOL_VERSION = 132,
AWS_MQTT5_CRC_CLIENT_IDENTIFIER_NOT_VALID = 133,
AWS_MQTT5_CRC_BAD_USERNAME_OR_PASSWORD = 134,
AWS_MQTT5_CRC_NOT_AUTHORIZED = 135,
AWS_MQTT5_CRC_SERVER_UNAVAILABLE = 136,
AWS_MQTT5_CRC_SERVER_BUSY = 137,
AWS_MQTT5_CRC_BANNED = 138,
AWS_MQTT5_CRC_BAD_AUTHENTICATION_METHOD = 140,
AWS_MQTT5_CRC_TOPIC_NAME_INVALID = 144,
AWS_MQTT5_CRC_PACKET_TOO_LARGE = 149,
AWS_MQTT5_CRC_QUOTA_EXCEEDED = 151,
AWS_MQTT5_CRC_PAYLOAD_FORMAT_INVALID = 153,
AWS_MQTT5_CRC_RETAIN_NOT_SUPPORTED = 154,
AWS_MQTT5_CRC_QOS_NOT_SUPPORTED = 155,
AWS_MQTT5_CRC_USE_ANOTHER_SERVER = 156,
AWS_MQTT5_CRC_SERVER_MOVED = 157,
AWS_MQTT5_CRC_CONNECTION_RATE_EXCEEDED = 159,
};
/**
* Reason code inside DISCONNECT packets.
* Enum values match mqtt spec encoding values.
*
* https://docs.oasis-open.org/mqtt/mqtt/v5.0/os/mqtt-v5.0-os.html#_Toc3901208
*/
enum aws_mqtt5_disconnect_reason_code {
AWS_MQTT5_DRC_NORMAL_DISCONNECTION = 0,
AWS_MQTT5_DRC_DISCONNECT_WITH_WILL_MESSAGE = 4,
AWS_MQTT5_DRC_UNSPECIFIED_ERROR = 128,
AWS_MQTT5_DRC_MALFORMED_PACKET = 129,
AWS_MQTT5_DRC_PROTOCOL_ERROR = 130,
AWS_MQTT5_DRC_IMPLEMENTATION_SPECIFIC_ERROR = 131,
AWS_MQTT5_DRC_NOT_AUTHORIZED = 135,
AWS_MQTT5_DRC_SERVER_BUSY = 137,
AWS_MQTT5_DRC_SERVER_SHUTTING_DOWN = 139,
AWS_MQTT5_DRC_KEEP_ALIVE_TIMEOUT = 141,
AWS_MQTT5_DRC_SESSION_TAKEN_OVER = 142,
AWS_MQTT5_DRC_TOPIC_FILTER_INVALID = 143,
AWS_MQTT5_DRC_TOPIC_NAME_INVALID = 144,
AWS_MQTT5_DRC_RECEIVE_MAXIMUM_EXCEEDED = 147,
AWS_MQTT5_DRC_TOPIC_ALIAS_INVALID = 148,
AWS_MQTT5_DRC_PACKET_TOO_LARGE = 149,
AWS_MQTT5_DRC_MESSAGE_RATE_TOO_HIGH = 150,
AWS_MQTT5_DRC_QUOTA_EXCEEDED = 151,
AWS_MQTT5_DRC_ADMINISTRATIVE_ACTION = 152,
AWS_MQTT5_DRC_PAYLOAD_FORMAT_INVALID = 153,
AWS_MQTT5_DRC_RETAIN_NOT_SUPPORTED = 154,
AWS_MQTT5_DRC_QOS_NOT_SUPPORTED = 155,
AWS_MQTT5_DRC_USE_ANOTHER_SERVER = 156,
AWS_MQTT5_DRC_SERVER_MOVED = 157,
AWS_MQTT5_DRC_SHARED_SUBSCRIPTIONS_NOT_SUPPORTED = 158,
AWS_MQTT5_DRC_CONNECTION_RATE_EXCEEDED = 159,
AWS_MQTT5_DRC_MAXIMUM_CONNECT_TIME = 160,
AWS_MQTT5_DRC_SUBSCRIPTION_IDENTIFIERS_NOT_SUPPORTED = 161,
AWS_MQTT5_DRC_WILDCARD_SUBSCRIPTIONS_NOT_SUPPORTED = 162,
};
/**
* Reason code inside PUBACK packets.
* Enum values match mqtt spec encoding values.
*
* https://docs.oasis-open.org/mqtt/mqtt/v5.0/os/mqtt-v5.0-os.html#_Toc3901124
*/
enum aws_mqtt5_puback_reason_code {
AWS_MQTT5_PARC_SUCCESS = 0,
AWS_MQTT5_PARC_NO_MATCHING_SUBSCRIBERS = 16,
AWS_MQTT5_PARC_UNSPECIFIED_ERROR = 128,
AWS_MQTT5_PARC_IMPLEMENTATION_SPECIFIC_ERROR = 131,
AWS_MQTT5_PARC_NOT_AUTHORIZED = 135,
AWS_MQTT5_PARC_TOPIC_NAME_INVALID = 144,
AWS_MQTT5_PARC_PACKET_IDENTIFIER_IN_USE = 145,
AWS_MQTT5_PARC_QUOTA_EXCEEDED = 151,
AWS_MQTT5_PARC_PAYLOAD_FORMAT_INVALID = 153,
};
/**
* Reason code inside SUBACK packet payloads.
* Enum values match mqtt spec encoding values.
*
* https://docs.oasis-open.org/mqtt/mqtt/v5.0/os/mqtt-v5.0-os.html#_Toc3901178
*/
enum aws_mqtt5_suback_reason_code {
AWS_MQTT5_SARC_GRANTED_QOS_0 = 0,
AWS_MQTT5_SARC_GRANTED_QOS_1 = 1,
AWS_MQTT5_SARC_GRANTED_QOS_2 = 2,
AWS_MQTT5_SARC_UNSPECIFIED_ERROR = 128,
AWS_MQTT5_SARC_IMPLEMENTATION_SPECIFIC_ERROR = 131,
AWS_MQTT5_SARC_NOT_AUTHORIZED = 135,
AWS_MQTT5_SARC_TOPIC_FILTER_INVALID = 143,
AWS_MQTT5_SARC_PACKET_IDENTIFIER_IN_USE = 145,
AWS_MQTT5_SARC_QUOTA_EXCEEDED = 151,
AWS_MQTT5_SARC_SHARED_SUBSCRIPTIONS_NOT_SUPPORTED = 158,
AWS_MQTT5_SARC_SUBSCRIPTION_IDENTIFIERS_NOT_SUPPORTED = 161,
AWS_MQTT5_SARC_WILDCARD_SUBSCRIPTIONS_NOT_SUPPORTED = 162,
};
/**
* Reason code inside UNSUBACK packet payloads.
* Enum values match mqtt spec encoding values.
*
* https://docs.oasis-open.org/mqtt/mqtt/v5.0/os/mqtt-v5.0-os.html#_Toc3901194
*/
enum aws_mqtt5_unsuback_reason_code {
AWS_MQTT5_UARC_SUCCESS = 0,
AWS_MQTT5_UARC_NO_SUBSCRIPTION_EXISTED = 17,
AWS_MQTT5_UARC_UNSPECIFIED_ERROR = 128,
AWS_MQTT5_UARC_IMPLEMENTATION_SPECIFIC_ERROR = 131,
AWS_MQTT5_UARC_NOT_AUTHORIZED = 135,
AWS_MQTT5_UARC_TOPIC_FILTER_INVALID = 143,
AWS_MQTT5_UARC_PACKET_IDENTIFIER_IN_USE = 145,
};
/**
* Type of mqtt packet.
* Enum values match mqtt spec encoding values.
*
* https://docs.oasis-open.org/mqtt/mqtt/v5.0/os/mqtt-v5.0-os.html#_Toc3901022
*/
enum aws_mqtt5_packet_type {
/* internal indicator that the associated packet is null */
AWS_MQTT5_PT_NONE = -1,
AWS_MQTT5_PT_RESERVED = 0,
AWS_MQTT5_PT_CONNECT = 1,
AWS_MQTT5_PT_CONNACK = 2,
AWS_MQTT5_PT_PUBLISH = 3,
AWS_MQTT5_PT_PUBACK = 4,
AWS_MQTT5_PT_PUBREC = 5,
AWS_MQTT5_PT_PUBREL = 6,
AWS_MQTT5_PT_PUBCOMP = 7,
AWS_MQTT5_PT_SUBSCRIBE = 8,
AWS_MQTT5_PT_SUBACK = 9,
AWS_MQTT5_PT_UNSUBSCRIBE = 10,
AWS_MQTT5_PT_UNSUBACK = 11,
AWS_MQTT5_PT_PINGREQ = 12,
AWS_MQTT5_PT_PINGRESP = 13,
AWS_MQTT5_PT_DISCONNECT = 14,
AWS_MQTT5_PT_AUTH = 15,
};
/**
* Non-persistent representation of an mqtt5 user property.
*/
struct aws_mqtt5_user_property {
struct aws_byte_cursor name;
struct aws_byte_cursor value;
};
/**
* Optional property describing a message's payload format.
* Enum values match mqtt spec encoding values.
*
* https://docs.oasis-open.org/mqtt/mqtt/v5.0/os/mqtt-v5.0-os.html#_Toc3901063
*/
enum aws_mqtt5_payload_format_indicator {
AWS_MQTT5_PFI_BYTES = 0,
AWS_MQTT5_PFI_UTF8 = 1,
};
/**
* Configures how retained messages should be handled when subscribing with a topic filter that matches topics with
* associated retained messages.
*
* https://docs.oasis-open.org/mqtt/mqtt/v5.0/os/mqtt-v5.0-os.html#_Toc3901169
*/
enum aws_mqtt5_retain_handling_type {
/**
* Server should send all retained messages on topics that match the subscription's filter.
*/
AWS_MQTT5_RHT_SEND_ON_SUBSCRIBE = 0x00,
/**
* Server should send all retained messages on topics that match the subscription's filter, where this is the
* first (relative to connection) subscription filter that matches the topic with a retained message.
*/
AWS_MQTT5_RHT_SEND_ON_SUBSCRIBE_IF_NEW = 0x01,
/**
* Subscribe must not trigger any retained message publishes from the server.
*/
AWS_MQTT5_RHT_DONT_SEND = 0x02,
};
/**
* Configures a single subscription within a Subscribe operation
*/
struct aws_mqtt5_subscription_view {
/**
* Topic filter to subscribe to
*/
struct aws_byte_cursor topic_filter;
/**
* Maximum QOS that the subscriber will accept messages for. Negotiated QoS may be different.
*/
enum aws_mqtt5_qos qos;
/**
* Should the server not send publishes to a client when that client was the one who sent the publish?
*/
bool no_local;
/**
* Should messages sent due to this subscription keep the retain flag preserved on the message?
*/
bool retain_as_published;
/**
* Should retained messages on matching topics be sent in reaction to this subscription?
*/
enum aws_mqtt5_retain_handling_type retain_handling_type;
};
/**
* Read-only snapshot of a DISCONNECT packet
*
* https://docs.oasis-open.org/mqtt/mqtt/v5.0/os/mqtt-v5.0-os.html#_Toc3901205
*/
struct aws_mqtt5_packet_disconnect_view {
enum aws_mqtt5_disconnect_reason_code reason_code;
const uint32_t *session_expiry_interval_seconds;
const struct aws_byte_cursor *reason_string;
size_t user_property_count;
const struct aws_mqtt5_user_property *user_properties;
const struct aws_byte_cursor *server_reference;
};
/**
* Read-only snapshot of a SUBSCRIBE packet
*
* https://docs.oasis-open.org/mqtt/mqtt/v5.0/os/mqtt-v5.0-os.html#_Toc3901161
*/
struct aws_mqtt5_packet_subscribe_view {
aws_mqtt5_packet_id_t packet_id;
size_t subscription_count;
const struct aws_mqtt5_subscription_view *subscriptions;
const uint32_t *subscription_identifier;
size_t user_property_count;
const struct aws_mqtt5_user_property *user_properties;
};
/**
* Read-only snapshot of an UNSUBSCRIBE packet
*
* https://docs.oasis-open.org/mqtt/mqtt/v5.0/os/mqtt-v5.0-os.html#_Toc3901179
*/
struct aws_mqtt5_packet_unsubscribe_view {
aws_mqtt5_packet_id_t packet_id;
size_t topic_filter_count;
const struct aws_byte_cursor *topic_filters;
size_t user_property_count;
const struct aws_mqtt5_user_property *user_properties;
};
/**
* Read-only snapshot of a PUBLISH packet. Used both in configuration of a publish operation and callback
* data in message receipt.
*
* https://docs.oasis-open.org/mqtt/mqtt/v5.0/os/mqtt-v5.0-os.html#_Toc3901100
*/
struct aws_mqtt5_packet_publish_view {
struct aws_byte_cursor payload;
/* packet_id is only set for QoS 1 and QoS 2 */
aws_mqtt5_packet_id_t packet_id;
enum aws_mqtt5_qos qos;
/*
* Used to set the duplicate flag on QoS 1+ re-delivery attempts.
* Set to false on all first attempts or QoS 0. Set to true on any re-delivery.
*/
bool duplicate;
bool retain;
struct aws_byte_cursor topic;
const enum aws_mqtt5_payload_format_indicator *payload_format;
const uint32_t *message_expiry_interval_seconds;
const uint16_t *topic_alias;
const struct aws_byte_cursor *response_topic;
const struct aws_byte_cursor *correlation_data;
/* These are ignored when building publish operations */
size_t subscription_identifier_count;
const uint32_t *subscription_identifiers;
const struct aws_byte_cursor *content_type;
size_t user_property_count;
const struct aws_mqtt5_user_property *user_properties;
};
/**
* Read-only snapshot of a CONNECT packet
*
* https://docs.oasis-open.org/mqtt/mqtt/v5.0/os/mqtt-v5.0-os.html#_Toc3901033
*/
struct aws_mqtt5_packet_connect_view {
uint16_t keep_alive_interval_seconds;
struct aws_byte_cursor client_id;
const struct aws_byte_cursor *username;
const struct aws_byte_cursor *password;
bool clean_start;
const uint32_t *session_expiry_interval_seconds;
const uint8_t *request_response_information;
const uint8_t *request_problem_information;
const uint16_t *receive_maximum;
const uint16_t *topic_alias_maximum;
const uint32_t *maximum_packet_size_bytes;
const uint32_t *will_delay_interval_seconds;
const struct aws_mqtt5_packet_publish_view *will;
size_t user_property_count;
const struct aws_mqtt5_user_property *user_properties;
/* Do not bind these. We don't support AUTH packets yet. For decode/encade testing purposes only. */
const struct aws_byte_cursor *authentication_method;
const struct aws_byte_cursor *authentication_data;
};
/**
* Read-only snapshot of a CONNACK packet.
*
* https://docs.oasis-open.org/mqtt/mqtt/v5.0/os/mqtt-v5.0-os.html#_Toc3901074
*/
struct aws_mqtt5_packet_connack_view {
bool session_present;
enum aws_mqtt5_connect_reason_code reason_code;
const uint32_t *session_expiry_interval;
const uint16_t *receive_maximum;
const enum aws_mqtt5_qos *maximum_qos;
const bool *retain_available;
const uint32_t *maximum_packet_size;
const struct aws_byte_cursor *assigned_client_identifier;
const uint16_t *topic_alias_maximum;
const struct aws_byte_cursor *reason_string;
size_t user_property_count;
const struct aws_mqtt5_user_property *user_properties;
const bool *wildcard_subscriptions_available;
const bool *subscription_identifiers_available;
const bool *shared_subscriptions_available;
const uint16_t *server_keep_alive;
const struct aws_byte_cursor *response_information;
const struct aws_byte_cursor *server_reference;
const struct aws_byte_cursor *authentication_method;
const struct aws_byte_cursor *authentication_data;
};
/**
* Read-only snapshot of a PUBACK packet
*
* https://docs.oasis-open.org/mqtt/mqtt/v5.0/os/mqtt-v5.0-os.html#_Toc3901121
*/
struct aws_mqtt5_packet_puback_view {
aws_mqtt5_packet_id_t packet_id;
enum aws_mqtt5_puback_reason_code reason_code;
const struct aws_byte_cursor *reason_string;
size_t user_property_count;
const struct aws_mqtt5_user_property *user_properties;
};
/**
* Read-only snapshot of a SUBACK packet
*
* https://docs.oasis-open.org/mqtt/mqtt/v5.0/os/mqtt-v5.0-os.html#_Toc3901171
*/
struct aws_mqtt5_packet_suback_view {
aws_mqtt5_packet_id_t packet_id;
const struct aws_byte_cursor *reason_string;
size_t user_property_count;
const struct aws_mqtt5_user_property *user_properties;
size_t reason_code_count;
const enum aws_mqtt5_suback_reason_code *reason_codes;
};
/**
* Read-only snapshot of an UNSUBACK packet
*
* https://docs.oasis-open.org/mqtt/mqtt/v5.0/os/mqtt-v5.0-os.html#_Toc3901187
*/
struct aws_mqtt5_packet_unsuback_view {
aws_mqtt5_packet_id_t packet_id;
const struct aws_byte_cursor *reason_string;
size_t user_property_count;
const struct aws_mqtt5_user_property *user_properties;
size_t reason_code_count;
const enum aws_mqtt5_unsuback_reason_code *reason_codes;
};
AWS_POP_SANE_WARNING_LEVEL
#endif /* AWS_MQTT_MQTT5_TYPES_H */