Mosquito MQTT header

Headers, Bindings, Libraries for use with FreeBASIC, Please include example of use to help ensure they are tested and usable.
Post Reply
birosys
Posts: 17
Joined: Aug 28, 2007 20:39

Mosquito MQTT header

Post by birosys »

Regards to all .
For my IOT project I needed the MQTT library, so with the help of FBFROG I converted the header for the Mosquitto library.

In the continuation of the message is the header, as well as the test programs.
There are probably type conversion errors, so feel free to correct them if you spot them.

Tested on Linux.

Cheers!

mosquitto.bi

Code: Select all

#pragma once

''#include once "stdbool.bi"
#include once "crt/stddef.bi"
#include once "crt/stdint.bi"

extern "C"

#define MOSQUITTO_H

#ifdef __FB_WIN32__
	#define libmosq_EXPORT __declspec(dllimport)
#else
	#define libmosq_EXPORT
#endif

const LIBMOSQUITTO_MAJOR = 2
const LIBMOSQUITTO_MINOR = 0
const LIBMOSQUITTO_REVISION = 15
const LIBMOSQUITTO_VERSION_NUMBER = ((LIBMOSQUITTO_MAJOR * 1000000) + (LIBMOSQUITTO_MINOR * 1000)) + LIBMOSQUITTO_REVISION
const MOSQ_LOG_NONE = 0
const MOSQ_LOG_INFO = 1 shl 0
const MOSQ_LOG_NOTICE = 1 shl 1
const MOSQ_LOG_WARNING = 1 shl 2
const MOSQ_LOG_ERR = 1 shl 3
const MOSQ_LOG_DEBUG = 1 shl 4
const MOSQ_LOG_SUBSCRIBE = 1 shl 5
const MOSQ_LOG_UNSUBSCRIBE = 1 shl 6
const MOSQ_LOG_WEBSOCKETS = 1 shl 7
const MOSQ_LOG_INTERNAL = &h80000000u
const MOSQ_LOG_ALL = &hFFFFFFFFu

type mosq_err_t as long
enum
	MOSQ_ERR_AUTH_CONTINUE = -4
	MOSQ_ERR_NO_SUBSCRIBERS = -3
	MOSQ_ERR_SUB_EXISTS = -2
	MOSQ_ERR_CONN_PENDING = -1
	MOSQ_ERR_SUCCESS = 0
	MOSQ_ERR_NOMEM = 1
	MOSQ_ERR_PROTOCOL = 2
	MOSQ_ERR_INVAL = 3
	MOSQ_ERR_NO_CONN = 4
	MOSQ_ERR_CONN_REFUSED = 5
	MOSQ_ERR_NOT_FOUND = 6
	MOSQ_ERR_CONN_LOST = 7
	MOSQ_ERR_TLS = 8
	MOSQ_ERR_PAYLOAD_SIZE = 9
	MOSQ_ERR_NOT_SUPPORTED = 10
	MOSQ_ERR_AUTH = 11
	MOSQ_ERR_ACL_DENIED = 12
	MOSQ_ERR_UNKNOWN = 13
	MOSQ_ERR_ERRNO = 14
	MOSQ_ERR_EAI = 15
	MOSQ_ERR_PROXY = 16
	MOSQ_ERR_PLUGIN_DEFER = 17
	MOSQ_ERR_MALFORMED_UTF8 = 18
	MOSQ_ERR_KEEPALIVE = 19
	MOSQ_ERR_LOOKUP = 20
	MOSQ_ERR_MALFORMED_PACKET = 21
	MOSQ_ERR_DUPLICATE_PROPERTY = 22
	MOSQ_ERR_TLS_HANDSHAKE = 23
	MOSQ_ERR_QOS_NOT_SUPPORTED = 24
	MOSQ_ERR_OVERSIZE_PACKET = 25
	MOSQ_ERR_OCSP = 26
	MOSQ_ERR_TIMEOUT = 27
	MOSQ_ERR_RETAIN_NOT_SUPPORTED = 28
	MOSQ_ERR_TOPIC_ALIAS_INVALID = 29
	MOSQ_ERR_ADMINISTRATIVE_ACTION = 30
	MOSQ_ERR_ALREADY_EXISTS = 31
end enum

type mosq_opt_t as long
enum
	MOSQ_OPT_PROTOCOL_VERSION = 1
	MOSQ_OPT_SSL_CTX = 2
	MOSQ_OPT_SSL_CTX_WITH_DEFAULTS = 3
	MOSQ_OPT_RECEIVE_MAXIMUM = 4
	MOSQ_OPT_SEND_MAXIMUM = 5
	MOSQ_OPT_TLS_KEYFORM = 6
	MOSQ_OPT_TLS_ENGINE = 7
	MOSQ_OPT_TLS_ENGINE_KPASS_SHA1 = 8
	MOSQ_OPT_TLS_OCSP_REQUIRED = 9
	MOSQ_OPT_TLS_ALPN = 10
	MOSQ_OPT_TCP_NODELAY = 11
	MOSQ_OPT_BIND_ADDRESS = 12
	MOSQ_OPT_TLS_USE_OS_CERTS = 13
end enum

const MOSQ_MQTT_ID_MAX_LENGTH = 23
const MQTT_PROTOCOL_V31 = 3
const MQTT_PROTOCOL_V311 = 4
const MQTT_PROTOCOL_V5 = 5

type mosquitto_message
	msg_id as long
	topic as zstring ptr
	payload as any ptr
	payloadlen as long
	qos as long
	retain as Boolean
end type

type mosquitto as any ptr

type mosquitto_property as mqtt5__property
declare function mosquitto_lib_version(byval major as long ptr, byval minor as long ptr, byval revision as long ptr) as long
declare function mosquitto_lib_init() as long
declare function mosquitto_lib_cleanup() as long
declare function mosquitto_new(byval id as const zstring ptr, byval clean_session as Boolean, byval obj as any ptr) as mosquitto ptr
declare sub mosquitto_destroy(byval mosq as mosquitto ptr)
declare function mosquitto_reinitialise(byval mosq as mosquitto ptr, byval id as const zstring ptr, byval clean_session as Boolean, byval obj as any ptr) as long
declare function mosquitto_will_set(byval mosq as mosquitto ptr, byval topic as const zstring ptr, byval payloadlen as long, byval payload as const any ptr, byval qos as long, byval retain as Boolean) as long
declare function mosquitto_will_set_v5(byval mosq as mosquitto ptr, byval topic as const zstring ptr, byval payloadlen as long, byval payload as const any ptr, byval qos as long, byval retain as Boolean, byval properties as mosquitto_property ptr) as long
declare function mosquitto_will_clear(byval mosq as mosquitto ptr) as long
declare function mosquitto_username_pw_set(byval mosq as mosquitto ptr, byval username as const zstring ptr, byval password as const zstring ptr) as long
declare function mosquitto_connect(byval mosq as mosquitto ptr, byval host as const zstring ptr, byval port as long, byval keepalive as long) as long
declare function mosquitto_connect_bind(byval mosq as mosquitto ptr, byval host as const zstring ptr, byval port as long, byval keepalive as long, byval bind_address as const zstring ptr) as long
declare function mosquitto_connect_bind_v5(byval mosq as mosquitto ptr, byval host as const zstring ptr, byval port as long, byval keepalive as long, byval bind_address as const zstring ptr, byval properties as const mosquitto_property ptr) as long
declare function mosquitto_connect_async(byval mosq as mosquitto ptr, byval host as const zstring ptr, byval port as long, byval keepalive as long) as long
declare function mosquitto_connect_bind_async(byval mosq as mosquitto ptr, byval host as const zstring ptr, byval port as long, byval keepalive as long, byval bind_address as const zstring ptr) as long
declare function mosquitto_connect_srv(byval mosq as mosquitto ptr, byval host as const zstring ptr, byval keepalive as long, byval bind_address as const zstring ptr) as long
declare function mosquitto_reconnect(byval mosq as mosquitto ptr) as long
declare function mosquitto_reconnect_async(byval mosq as mosquitto ptr) as long
declare function mosquitto_disconnect(byval mosq as mosquitto ptr) as long
declare function mosquitto_disconnect_v5(byval mosq as mosquitto ptr, byval reason_code as long, byval properties as const mosquitto_property ptr) as long
declare function mosquitto_publish(byval mosq as mosquitto ptr, byval msg_id as long ptr, byval topic as const zstring ptr, byval payloadlen as long, byval payload as const any ptr, byval qos as long, byval retain as Boolean) as long
declare function mosquitto_publish_v5(byval mosq as mosquitto ptr, byval msg_id as long ptr, byval topic as const zstring ptr, byval payloadlen as long, byval payload as const any ptr, byval qos as long, byval retain as Boolean, byval properties as const mosquitto_property ptr) as long
declare function mosquitto_subscribe(byval mosq as mosquitto ptr, byval msg_id as long ptr, byval sub as const zstring ptr, byval qos as long) as long
declare function mosquitto_subscribe_v5(byval mosq as mosquitto ptr, byval msg_id as long ptr, byval sub as const zstring ptr, byval qos as long, byval options as long, byval properties as const mosquitto_property ptr) as long
declare function mosquitto_subscribe_multiple(byval mosq as mosquitto ptr, byval msg_id as long ptr, byval sub_count as long, byval sub as zstring const ptr const ptr, byval qos as long, byval options as long, byval properties as const mosquitto_property ptr) as long
declare function mosquitto_unsubscribe(byval mosq as mosquitto ptr, byval msg_id as long ptr, byval sub as const zstring ptr) as long
declare function mosquitto_unsubscribe_v5(byval mosq as mosquitto ptr, byval msg_id as long ptr, byval sub as const zstring ptr, byval properties as const mosquitto_property ptr) as long
declare function mosquitto_unsubscribe_multiple(byval mosq as mosquitto ptr, byval msg_id as long ptr, byval sub_count as long, byval sub as zstring const ptr const ptr, byval properties as const mosquitto_property ptr) as long
declare function mosquitto_message_copy(byval dst as mosquitto_message ptr, byval src as const mosquitto_message ptr) as long
declare sub mosquitto_message_free(byval message as mosquitto_message ptr ptr)
declare sub mosquitto_message_free_contents(byval message as mosquitto_message ptr)
declare function mosquitto_loop_forever(byval mosq as mosquitto ptr, byval timeout as long, byval max_packets as long) as long
declare function mosquitto_loop_start(byval mosq as mosquitto ptr) as long
declare function mosquitto_loop_stop(byval mosq as mosquitto ptr, byval force as Boolean) as long
declare function mosquitto_loop(byval mosq as mosquitto ptr, byval timeout as long, byval max_packets as long) as long
declare function mosquitto_loop_read(byval mosq as mosquitto ptr, byval max_packets as long) as long
declare function mosquitto_loop_write(byval mosq as mosquitto ptr, byval max_packets as long) as long
declare function mosquitto_loop_misc(byval mosq as mosquitto ptr) as long
declare function mosquitto_socket(byval mosq as mosquitto ptr) as long
declare function mosquitto_want_write(byval mosq as mosquitto ptr) as Boolean
declare function mosquitto_threaded_set(byval mosq as mosquitto ptr, byval threaded as Boolean) as long
declare function mosquitto_opts_set(byval mosq as mosquitto ptr, byval option as mosq_opt_t, byval value as any ptr) as long
declare function mosquitto_int_option(byval mosq as mosquitto ptr, byval option as mosq_opt_t, byval value as long) as long
declare function mosquitto_string_option(byval mosq as mosquitto ptr, byval option as mosq_opt_t, byval value as const zstring ptr) as long
declare function mosquitto_void_option(byval mosq as mosquitto ptr, byval option as mosq_opt_t, byval value as any ptr) as long
declare function mosquitto_reconnect_delay_set(byval mosq as mosquitto ptr, byval reconnect_delay as ulong, byval reconnect_delay_max as ulong, byval reconnect_exponential_backoff as Boolean) as long
declare function mosquitto_max_inflight_messages_set(byval mosq as mosquitto ptr, byval max_inflight_messages as ulong) as long
declare sub mosquitto_message_retry_set(byval mosq as mosquitto ptr, byval message_retry as ulong)
declare sub mosquitto_user_data_set(byval mosq as mosquitto ptr, byval obj as any ptr)
declare function mosquitto_userdata(byval mosq as mosquitto ptr) as any ptr
declare function mosquitto_tls_set(byval mosq as mosquitto ptr, byval cafile as const zstring ptr, byval capath as const zstring ptr, byval certfile as const zstring ptr, byval keyfile as const zstring ptr, byval pw_callback as function(byval buf as zstring ptr, byval size as long, byval rwflag as long, byval userdata as any ptr) as long) as long
declare function mosquitto_tls_insecure_set(byval mosq as mosquitto ptr, byval value as Boolean) as long
declare function mosquitto_tls_opts_set(byval mosq as mosquitto ptr, byval cert_reqs as long, byval tls_version as const zstring ptr, byval ciphers as const zstring ptr) as long
declare function mosquitto_tls_psk_set(byval mosq as mosquitto ptr, byval psk as const zstring ptr, byval identity as const zstring ptr, byval ciphers as const zstring ptr) as long
declare function mosquitto_ssl_get(byval mosq as mosquitto ptr) as any ptr
declare sub mosquitto_connect_callback_set(byval mosq as mosquitto ptr, byval on_connect as sub(byval as mosquitto ptr, byval as any ptr, byval as long))
declare sub mosquitto_connect_with_flags_callback_set(byval mosq as mosquitto ptr, byval on_connect as sub(byval as mosquitto ptr, byval as any ptr, byval as long, byval as long))
declare sub mosquitto_connect_v5_callback_set(byval mosq as mosquitto ptr, byval on_connect as sub(byval as mosquitto ptr, byval as any ptr, byval as long, byval as long, byval props as const mosquitto_property ptr))
declare sub mosquitto_disconnect_callback_set(byval mosq as mosquitto ptr, byval on_disconnect as sub(byval as mosquitto ptr, byval as any ptr, byval as long))
declare sub mosquitto_disconnect_v5_callback_set(byval mosq as mosquitto ptr, byval on_disconnect as sub(byval as mosquitto ptr, byval as any ptr, byval as long, byval props as const mosquitto_property ptr))
declare sub mosquitto_publish_callback_set(byval mosq as mosquitto ptr, byval on_publish as sub(byval as mosquitto ptr, byval as any ptr, byval as long))
declare sub mosquitto_publish_v5_callback_set(byval mosq as mosquitto ptr, byval on_publish as sub(byval as mosquitto ptr, byval as any ptr, byval as long, byval as long, byval props as const mosquitto_property ptr))
declare sub mosquitto_message_callback_set(byval mosq as mosquitto ptr, byval on_message as sub(byval as mosquitto ptr, byval as any ptr, byval as const mosquitto_message ptr))
declare sub mosquitto_message_v5_callback_set(byval mosq as mosquitto ptr, byval on_message as sub(byval as mosquitto ptr, byval as any ptr, byval as const mosquitto_message ptr, byval props as const mosquitto_property ptr))
declare sub mosquitto_subscribe_callback_set(byval mosq as mosquitto ptr, byval on_subscribe as sub(byval as mosquitto ptr, byval as any ptr, byval as long, byval as long, byval as const long ptr))
declare sub mosquitto_subscribe_v5_callback_set(byval mosq as mosquitto ptr, byval on_subscribe as sub(byval as mosquitto ptr, byval as any ptr, byval as long, byval as long, byval as const long ptr, byval props as const mosquitto_property ptr))
declare sub mosquitto_unsubscribe_callback_set(byval mosq as mosquitto ptr, byval on_unsubscribe as sub(byval as mosquitto ptr, byval as any ptr, byval as long))
declare sub mosquitto_unsubscribe_v5_callback_set(byval mosq as mosquitto ptr, byval on_unsubscribe as sub(byval as mosquitto ptr, byval as any ptr, byval as long, byval props as const mosquitto_property ptr))
declare sub mosquitto_log_callback_set(byval mosq as mosquitto ptr, byval on_log as sub(byval as mosquitto ptr, byval as any ptr, byval as long, byval as const zstring ptr))
declare function mosquitto_socks5_set(byval mosq as mosquitto ptr, byval host as const zstring ptr, byval port as long, byval username as const zstring ptr, byval password as const zstring ptr) as long
declare function mosquitto_strerror(byval mosq_errno as long) as const zstring ptr
declare function mosquitto_connack_string(byval connack_code as long) as const zstring ptr
declare function mosquitto_reason_string(byval reason_code as long) as const zstring ptr
declare function mosquitto_string_to_command(byval str as const zstring ptr, byval cmd as long ptr) as long
declare function mosquitto_sub_topic_tokenise(byval subtopic as const zstring ptr, byval topics as zstring ptr ptr ptr, byval count as long ptr) as long
declare function mosquitto_sub_topic_tokens_free(byval topics as zstring ptr ptr ptr, byval count as long) as long
declare function mosquitto_topic_matches_sub(byval sub as const zstring ptr, byval topic as const zstring ptr, byval result as Boolean ptr) as long
declare function mosquitto_topic_matches_sub2(byval sub as const zstring ptr, byval sublen as uinteger, byval topic as const zstring ptr, byval topiclen as uinteger, byval result as Boolean ptr) as long
declare function mosquitto_pub_topic_check(byval topic as const zstring ptr) as long
declare function mosquitto_pub_topic_check2(byval topic as const zstring ptr, byval topiclen as uinteger) as long
declare function mosquitto_sub_topic_check(byval topic as const zstring ptr) as long
declare function mosquitto_sub_topic_check2(byval topic as const zstring ptr, byval topiclen as uinteger) as long
declare function mosquitto_validate_utf8(byval str as const zstring ptr, byval len as long) as long

type libmosquitto_will
	topic as zstring ptr
	payload as any ptr
	payloadlen as long
	qos as long
	retain as Boolean
end type

type libmosquitto_auth
	username as zstring ptr
	password as zstring ptr
end type

type libmosquitto_tls
	cafile as zstring ptr
	capath as zstring ptr
	certfile as zstring ptr
	keyfile as zstring ptr
	ciphers as zstring ptr
	tls_version as zstring ptr
	pw_callback as function(byval buf as zstring ptr, byval size as long, byval rwflag as long, byval userdata as any ptr) as long
	cert_reqs as long
end type

declare function mosquitto_subscribe_simple(byval messages as mosquitto_message ptr ptr, byval msg_count as long, byval want_retained as Boolean, byval topic as const zstring ptr, byval qos as long, byval host as const zstring ptr, byval port as long, byval client_id as const zstring ptr, byval keepalive as long, byval clean_session as Boolean, byval username as const zstring ptr, byval password as const zstring ptr, byval will as const libmosquitto_will ptr, byval tls as const libmosquitto_tls ptr) as long
declare function mosquitto_subscribe_callback(byval callback as function(byval as mosquitto ptr, byval as any ptr, byval as const mosquitto_message ptr) as long, byval userdata as any ptr, byval topic as const zstring ptr, byval qos as long, byval host as const zstring ptr, byval port as long, byval client_id as const zstring ptr, byval keepalive as long, byval clean_session as Boolean, byval username as const zstring ptr, byval password as const zstring ptr, byval will as const libmosquitto_will ptr, byval tls as const libmosquitto_tls ptr) as long
declare function mosquitto_property_add_byte(byval proplist as mosquitto_property ptr ptr, byval identifier as long, byval value as ubyte) as long
declare function mosquitto_property_add_int16(byval proplist as mosquitto_property ptr ptr, byval identifier as long, byval value as ushort) as long
declare function mosquitto_property_add_int32(byval proplist as mosquitto_property ptr ptr, byval identifier as long, byval value as ulong) as long
declare function mosquitto_property_add_varint(byval proplist as mosquitto_property ptr ptr, byval identifier as long, byval value as ulong) as long
declare function mosquitto_property_add_binary(byval proplist as mosquitto_property ptr ptr, byval identifier as long, byval value as const any ptr, byval len as ushort) as long
declare function mosquitto_property_add_string(byval proplist as mosquitto_property ptr ptr, byval identifier as long, byval value as const zstring ptr) as long
declare function mosquitto_property_add_string_pair(byval proplist as mosquitto_property ptr ptr, byval identifier as long, byval name as const zstring ptr, byval value as const zstring ptr) as long
declare function mosquitto_property_identifier(byval property as const mosquitto_property ptr) as long
declare function mosquitto_property_next(byval proplist as const mosquitto_property ptr) as const mosquitto_property ptr
declare function mosquitto_property_read_byte(byval proplist as const mosquitto_property ptr, byval identifier as long, byval value as ubyte ptr, byval skip_first as Boolean) as const mosquitto_property ptr
declare function mosquitto_property_read_int16(byval proplist as const mosquitto_property ptr, byval identifier as long, byval value as ushort ptr, byval skip_first as Boolean) as const mosquitto_property ptr
declare function mosquitto_property_read_int32(byval proplist as const mosquitto_property ptr, byval identifier as long, byval value as ulong ptr, byval skip_first as Boolean) as const mosquitto_property ptr
declare function mosquitto_property_read_varint(byval proplist as const mosquitto_property ptr, byval identifier as long, byval value as ulong ptr, byval skip_first as Boolean) as const mosquitto_property ptr
declare function mosquitto_property_read_binary(byval proplist as const mosquitto_property ptr, byval identifier as long, byval value as any ptr ptr, byval len as ushort ptr, byval skip_first as Boolean) as const mosquitto_property ptr
declare function mosquitto_property_read_string(byval proplist as const mosquitto_property ptr, byval identifier as long, byval value as zstring ptr ptr, byval skip_first as Boolean) as const mosquitto_property ptr
declare function mosquitto_property_read_string_pair(byval proplist as const mosquitto_property ptr, byval identifier as long, byval name as zstring ptr ptr, byval value as zstring ptr ptr, byval skip_first as Boolean) as const mosquitto_property ptr
declare sub mosquitto_property_free_all(byval properties as mosquitto_property ptr ptr)
declare function mosquitto_property_copy_all(byval dest as mosquitto_property ptr ptr, byval src as const mosquitto_property ptr) as long
declare function mosquitto_property_check_command(byval command as long, byval identifier as long) as long
declare function mosquitto_property_check_all(byval command as long, byval properties as const mosquitto_property ptr) as long
declare function mosquitto_property_identifier_to_string(byval identifier as long) as const zstring ptr
declare function mosquitto_string_to_property_info(byval propname as const zstring ptr, byval identifier as long ptr, byval type as long ptr) as long

end extern
publish.bas

Code: Select all

/'
 * This example shows how to publish messages from outside of the Mosquitto network loop.
 '/

#inclib "mosquitto"
#include "mosquitto.bi"


/' Callback called when the client receives a CONNACK message from the broker. '/
sub on_connect (byval mosq as mosquitto ptr, byval obj as any ptr, byval reason_code as long)
/' Print out the connection result. mosquitto_connack_string() produces an
	 * appropriate string for MQTT v3.x clients, the equivalent for MQTT v5.0
	 * clients is mosquitto_reason_string().
	 '/
	 
	print "on_connect: " & *mosquitto_connack_string(reason_code)

	if (reason_code <> 0) then
		/' If the connection fails for any reason, we don't want to keep on
		 * retrying in this example, so disconnect. Without this, the client
		 * will attempt to reconnect. '/
		mosquitto_disconnect(mosq)
	end if
	
	/' You may wish to set a flag here to indicate to your application that the
	 * client is now connected. '/
end sub


/' Callback called when the client knows to the best of its abilities that a
 * PUBLISH has been successfully sent. For QoS 0 this means the message has
 * been completely written to the operating system. For QoS 1 this means we
 * have received a PUBACK from the broker. For QoS 2 this means we have
 * received a PUBCOMP from the broker. '/
sub on_publish (byval mosq as mosquitto ptr, byval obj as any ptr, byval msg_id as long)
	print("Message with msg_id " & msg_id & " has been published")
end sub

function get_temperature () as long
	sleep(1000) /' Prevent a storm of messages - this pretend sensor works at 1Hz '/
	return rnd*100
end function

/' This function pretends to read some data from a sensor and publish it.'/
sub publish_sensor_data(byval mosq as any ptr)
	dim payload as string
	dim temp as long
	dim rc as long

	/' Get our pretend data '/
	temp = get_temperature()
	/' Print it to a string for easy human reading - payload format is highly
	 * application dependent. '/
	
	payload=str(temp)


	/' Publish the message
	 * mosq - our client instance
	 * *mid = NULL - we don't want to know what the message id for this message is
	 * topic = "test" - the topic on which this message will be published
	 * payloadlen = strlen(payload) - the length of our payload in bytes
	 * payload - the actual payload
	 * qos = 2 - publish with QoS 2 for this example
	 * retain = false - do not use the retained message feature for this message
	 '/
	rc = mosquitto_publish(mosq, NULL, "test", len(payload)+1, strptr(payload), 2, false)
	if(rc <> MOSQ_ERR_SUCCESS) then
		print("Error publishing: " & *mosquitto_strerror(rc))
	end if
end sub
/' main program goes here '/

dim mosq as mosquitto ptr
dim rc as long
	
	randomize ,1

	/' Required before calling other mosquitto functions '/
	mosquitto_lib_init()

	/' Create a new client instance.
	 * id = NULL -> ask the broker to generate a client id for us
	 * clean session = true -> the broker should remove old sessions when we connect
	 * obj = NULL -> we aren't passing any of our private data for callbacks
	 '/
	mosq = mosquitto_new(0, true, 0)
	if (mosq = 0) then
		Print("Error: Out of memory.")
		End 1
	end if

	/' Configure callbacks. This should be done before connecting ideally. '/
	mosquitto_connect_callback_set(mosq, @on_connect)
	mosquitto_publish_callback_set(mosq, @on_publish)

	/' Connect to MQTT server on port 1883, with a keepalive of 60 seconds.
	 * This call makes the socket connection only, it does not complete the MQTT
	 * CONNECT/CONNACK flow, you should use mosquitto_loop_start() or
	 * mosquitto_loop_forever() for processing net traffic. '/
	rc = mosquitto_connect(mosq, "localhost", 1883, 60)
	if(rc <> MOSQ_ERR_SUCCESS) then
		mosquitto_destroy(mosq)
		Print("Error: " & *mosquitto_strerror(rc))
		End 1
	end if

	/' Run the network loop in a background thread, this call returns quickly. '/
	rc = mosquitto_loop_start(mosq)
	if(rc <> MOSQ_ERR_SUCCESS) then
		mosquitto_destroy(mosq)
		Print("Error: " & *mosquitto_strerror(rc))
		End 1
	end if

	/' At this point the client is connected to the network socket, but may not
	 * have completed CONNECT/CONNACK.
	 * It is fairly safe to start queuing messages at this point, but if you
	 * want to be really sure you should wait until after a successful call to
	 * the connect callback.
	 * In this case we know it is 1 second before we start publishing.
	 '/
	while(1)
		publish_sensor_data(mosq)
	wend

	mosquitto_lib_cleanup()
	End 0
subscribe.bas

Code: Select all

/'
 * This example shows how to write a client that subscribes to a topic and does
 * not do anything other than handle the messages that are received.
 '/
 
#inclib "mosquitto"
#include "mosquitto.bi"


/' Callback called when the client receives a CONNACK message from the broker. '/
sub on_connect (byval mosq as mosquitto ptr, byval obj as any ptr, byval reason_code as long)
	dim rc as long
	
	/' Print out the connection result. mosquitto_connack_string() produces an
	 * appropriate string for MQTT v3.x clients, the equivalent for MQTT v5.0
	 * clients is mosquitto_reason_string().
	 '/
	 
	print "on_connect: " & *mosquitto_connack_string(reason_code)

	if (reason_code <> 0) then
		/' If the connection fails for any reason, we don't want to keep on
		 * retrying in this example, so disconnect. Without this, the client
		 * will attempt to reconnect. '/
		mosquitto_disconnect(mosq)
	end if
	
	/' Making subscriptions in the on_connect() callback means that if the
	 * connection drops and is automatically resumed by the client, then the
	 * subscriptions will be recreated when the client reconnects. '/
	 
	rc=mosquitto_subscribe(mosq,0,"test",1)
	if (rc <> MOSQ_ERR_SUCCESS) then
		print "Error subscribing: " & *mosquitto_strerror(rc)
		/' We might as well disconnect if we were unable to subscribe '/
		mosquitto_disconnect(mosq)
	end if
end sub

/' Callback called when the broker sends a SUBACK in response to a SUBSCRIBE. '/
sub on_subscribe (byval moq as mosquitto ptr, byval obj as any ptr, byval msg_id as long, byval qos_count as long, byval granted_qos as const long ptr)
	dim i as long
	dim have_subscription as Boolean
	
	/' In this example we only subscribe to a single topic at once, but a
	 * SUBSCRIBE can contain many topics at once, so this is one way to check
	 * them all. '/
	
	for i=0 to i<qos_count
		
		print("on_subscribe:" & i &  "granted qos = " & granted_qos+i)
		if (granted_qos+i <=2) then
			have_subscription=true
		end if

		if (have_subscription=false) then
			/' The broker rejected all of our subscriptions, we know we only sent
		 * the one SUBSCRIBE, so there is no point remaining connected. '/
			Print "Error: All subscriptions rejected!"
			mosquitto_disconnect(moq)
		end if
		i=i+1
	next i
end sub

/' Callback called when the client receives a message. '/
sub on_message (byval mosq as mosquitto ptr, byval obj as any ptr, byval msg as const mosquitto_message ptr)
	/' This blindly prints the payload, but the payload can be anything so take care. '/
	print(*msg->topic & " " & msg->qos & " " & *Cptr(zstring ptr,msg->payload))
end sub



dim mosq as mosquitto ptr
dim rc as long

/' Required before calling other mosquitto functions '/
mosquitto_lib_init()

	/' Create a new client instance.
	 * id = NULL -> ask the broker to generate a client id for us
	 * clean session = true -> the broker should remove old sessions when we connect
	 * obj = NULL -> we aren't passing any of our private data for callbacks
	 '/
mosq = mosquitto_new(NULL, true, NULL)
	if(mosq =0) then
		Print "Error: Out of memory."
		End 1
	end if

	/' Configure callbacks. This should be done before connecting ideally. '/
	mosquitto_connect_callback_set(mosq, @on_connect)
	mosquitto_subscribe_callback_set(mosq, @on_subscribe)
	mosquitto_message_callback_set(mosq, @on_message)

	/' Connect to MQTT server on port 1883, with a keepalive of 60 seconds.
	 * This call makes the socket connection only, it does not complete the MQTT
	 * CONNECT/CONNACK flow, you should use mosquitto_loop_start() or
	 * mosquitto_loop_forever() for processing net traffic. '/
	rc = mosquitto_connect(mosq, "localhost", 1883, 60)
	if(rc <> MOSQ_ERR_SUCCESS) then
		mosquitto_destroy(mosq)
		print("Error: " & mosquitto_strerror(rc))
		end 1
	end if

	/' Run the network loop in a blocking call. The only thing we do in this
	 * example is to print incoming messages, so a blocking call here is fine.
	 *
	 * This call will continue forever, carrying automatic reconnections if
	 * necessary, until the user calls mosquitto_disconnect().
	 '/
	
	mosquitto_loop_forever(mosq, -1, 1)

	mosquitto_lib_cleanup()
	end 0


Dinosaur
Posts: 1481
Joined: Jul 24, 2005 1:13
Location: Hervey Bay (.au)

Re: Mosquito MQTT header

Post by Dinosaur »

Hi All

birosys, it looks like you have done a lot of work on this.

Did you manage to use an interrupt to prevent the subscriber from polling for new messages ?
I can't seem to find any options in Mosquitto to do this.

Currently I am using Mosquitto on a Rpi-Zero as the broker and a Pico as the only client.
With using MMBasic in the Pico, I can specify the interrupt routine with an inbuilt MMBasic command.

Using FreeBasic in the Rpi-Zero at the moment is done as follows
To Initialize:

Code: Select all

    Dim as String RxStr
    If Fileexists("/var/lib/mosquitto/mosquitto.db") Then
        RxStr = "sudo systemctl stop mosquitto.service"
        Shell RxStr
        
        RxStr = "sudo rm /var/lib/mosquitto/mosquitto.db"
        Shell RxStr
        
        RxStr = "sudo systemctl start mosquitto.service"
        Shell RxStr
    EndIf
To Publish

Code: Select all

                    Dim as Long pf = FreeFile
                    Open Pipe "mosquitto_pub -d -q 1 -t AmpHr -m 'Time ?' "  for Input as #pf    'ask pico to send RTC Time
                        Input #pf, MQTT.Cmnd
                    Close #pf
To Poll for messages

Code: Select all

        Dim as Long pf = FreeFile
        'Open without printing (--quiet), No CR added (-N),topic AmpHr, wait for 4 Sec's only
        Open Pipe "mosquitto_sub --keepalive 100 --quiet -N --retained-only --qos 1 -t AmpHr -W 4"  for Input as #pf
            Input #pf, .RxStr
        Close #pf
When I found your work, wanted to convert to using it, but without some sort of Interrupt routine it's probably not worth it.

Regards
birosys
Posts: 17
Joined: Aug 28, 2007 20:39

Re: Mosquito MQTT header

Post by birosys »

Hi Dinosaur.

In the mosquitto library, all events are executed via callback functions.
Events are checked in a network loop.

To check network communication in loop, four functions are used:
mosquitto_loop_forever This function calls loop() for you in an infinite blocking loop.
mosquitto_loop_start This is part of the threaded client interface.
mosquitto_loop_stop This is part of the threaded client interface.
mosquitto_loop The main network loop for the client.

You can find documentation on their use at the following link https://mosquitto.org/api/files/mosquitto-h.html

There is no need for interrupt.

You can frequently call mosquitto_loop in your app loop, or you can use mosquitto_loop_start and mosquitto_loop_stop for threaded network loop.

Hope you help.

Cheers.
Dinosaur
Posts: 1481
Joined: Jul 24, 2005 1:13
Location: Hervey Bay (.au)

Re: Mosquito MQTT header

Post by Dinosaur »

Thank you birosys

I did see the mosquitto_loop option , but it is still polling.
It is probably better/faster than my polling using pipe..

Your code worked perfectly.

Regards
coderx
Posts: 3
Joined: Nov 12, 2023 3:11

Re: Mosquito MQTT header

Post by coderx »

For those on Windows note that threaded functions do not work in the 2.0.x versions of the library. That means mosquitto_loop_start, etc. will fail with a return code of "not supported".

My easy fix was to download the win32 library version 1.3.5:
https://mosquitto.org/files/binary/win32/
coderx
Posts: 3
Joined: Nov 12, 2023 3:11

Re: Mosquito MQTT header

Post by coderx »

One additional bit of info, to get the callback functions to work I had to change declaration like this (added cdecl):
/' Callback called when the client receives a CONNACK message from the broker. '/
sub on_connect cdecl (byval mosq as mosquitto ptr, byval obj as any ptr, byval reason_code as long)
Post Reply