Make user functions for reading properties easier to use.

pull/1072/head
Roger A. Light 7 years ago
parent 608b8d33e7
commit 4fe75b1af0

@ -39,15 +39,32 @@ int mosquitto_publish_v5(struct mosquitto *mosq, int *mid, const char *topic, in
uint16_t local_mid;
int queue_status;
const mosquitto_property *p;
const mosquitto_property *outgoing_properties = NULL;
mosquitto_property local_property;
bool have_topic_alias;
int rc;
if(!mosq || qos<0 || qos>2) return MOSQ_ERR_INVAL;
if(mosq->protocol != mosq_p_mqtt5 && properties) return MOSQ_ERR_NOT_SUPPORTED;
if(properties){
if(properties->client_generated){
outgoing_properties = properties;
}else{
memcpy(&local_property, properties, sizeof(mosquitto_property));
local_property.client_generated = true;
local_property.next = NULL;
outgoing_properties = &local_property;
}
rc = mosquitto_property_check_all(CMD_PUBLISH, outgoing_properties);
if(rc) return rc;
}
if(!topic || STREMPTY(topic)){
if(topic) topic = NULL;
if(mosq->protocol == mosq_p_mqtt5){
p = properties;
p = outgoing_properties;
have_topic_alias = false;
while(p){
if(p->identifier == MQTT_PROP_TOPIC_ALIAS){
@ -69,10 +86,6 @@ int mosquitto_publish_v5(struct mosquitto *mosq, int *mid, const char *topic, in
return MOSQ_ERR_INVAL;
}
}
if(properties){
rc = mosquitto_property_check_all(CMD_PUBLISH, properties);
if(rc) return rc;
}
local_mid = mosquitto__mid_generate(mosq);
if(mid){
@ -80,7 +93,7 @@ int mosquitto_publish_v5(struct mosquitto *mosq, int *mid, const char *topic, in
}
if(qos == 0){
return send__publish(mosq, local_mid, topic, payloadlen, payload, qos, retain, false, properties);
return send__publish(mosq, local_mid, topic, payloadlen, payload, qos, retain, false, outgoing_properties);
}else{
message = mosquitto__calloc(1, sizeof(struct mosquitto_message_all));
if(!message) return MOSQ_ERR_NOMEM;
@ -120,7 +133,7 @@ int mosquitto_publish_v5(struct mosquitto *mosq, int *mid, const char *topic, in
message->state = mosq_ms_wait_for_pubrec;
}
pthread_mutex_unlock(&mosq->out_message_mutex);
return send__publish(mosq, message->msg.mid, message->msg.topic, message->msg.payloadlen, message->msg.payload, message->msg.qos, message->msg.retain, message->dup, properties);
return send__publish(mosq, message->msg.mid, message->msg.topic, message->msg.payloadlen, message->msg.payload, message->msg.qos, message->msg.retain, message->dup, outgoing_properties);
}else{
message->state = mosq_ms_invalid;
pthread_mutex_unlock(&mosq->out_message_mutex);
@ -137,34 +150,57 @@ int mosquitto_subscribe(struct mosquitto *mosq, int *mid, const char *sub, int q
int mosquitto_subscribe_v5(struct mosquitto *mosq, int *mid, const char *sub, int qos, const mosquitto_property *properties)
{
const mosquitto_property *outgoing_properties = NULL;
mosquitto_property local_property;
int rc;
if(!mosq) return MOSQ_ERR_INVAL;
if(mosq->protocol != mosq_p_mqtt5 && properties) return MOSQ_ERR_NOT_SUPPORTED;
if(mosq->sock == INVALID_SOCKET) return MOSQ_ERR_NO_CONN;
if(mosquitto_sub_topic_check(sub)) return MOSQ_ERR_INVAL;
if(mosquitto_validate_utf8(sub, strlen(sub))) return MOSQ_ERR_MALFORMED_UTF8;
if(properties){
rc = mosquitto_property_check_all(CMD_SUBSCRIBE, properties);
if(properties->client_generated){
outgoing_properties = properties;
}else{
memcpy(&local_property, properties, sizeof(mosquitto_property));
local_property.client_generated = true;
local_property.next = NULL;
outgoing_properties = &local_property;
}
rc = mosquitto_property_check_all(CMD_SUBSCRIBE, outgoing_properties);
if(rc) return rc;
}
return send__subscribe(mosq, mid, 1, (char *const *const)&sub, qos, properties);
return send__subscribe(mosq, mid, 1, (char *const *const)&sub, qos, outgoing_properties);
}
int mosquitto_subscribe_multiple(struct mosquitto *mosq, int *mid, int sub_count, char *const *const sub, int qos, const mosquitto_property *properties)
{
const mosquitto_property *outgoing_properties = NULL;
mosquitto_property local_property;
int i;
int rc;
if(!mosq || !sub_count || !sub) return MOSQ_ERR_INVAL;
if(mosq->protocol != mosq_p_mqtt5 && properties) return MOSQ_ERR_NOT_SUPPORTED;
if(qos < 0 || qos > 2) return MOSQ_ERR_INVAL;
if(mosq->sock == INVALID_SOCKET) return MOSQ_ERR_NO_CONN;
if(mosq->protocol == mosq_p_mqtt5 && properties){
rc = mosquitto_property_check_all(CMD_SUBSCRIBE, properties);
if(properties){
if(properties->client_generated){
outgoing_properties = properties;
}else{
memcpy(&local_property, properties, sizeof(mosquitto_property));
local_property.client_generated = true;
local_property.next = NULL;
outgoing_properties = &local_property;
}
rc = mosquitto_property_check_all(CMD_SUBSCRIBE, outgoing_properties);
if(rc) return rc;
}
@ -184,18 +220,30 @@ int mosquitto_unsubscribe(struct mosquitto *mosq, int *mid, const char *sub)
int mosquitto_unsubscribe_v5(struct mosquitto *mosq, int *mid, const char *sub, const mosquitto_property *properties)
{
const mosquitto_property *outgoing_properties = NULL;
mosquitto_property local_property;
int rc;
if(!mosq) return MOSQ_ERR_INVAL;
if(mosq->protocol != mosq_p_mqtt5 && properties) return MOSQ_ERR_NOT_SUPPORTED;
if(mosq->sock == INVALID_SOCKET) return MOSQ_ERR_NO_CONN;
if(mosquitto_sub_topic_check(sub)) return MOSQ_ERR_INVAL;
if(mosquitto_validate_utf8(sub, strlen(sub))) return MOSQ_ERR_MALFORMED_UTF8;
if(properties){
rc = mosquitto_property_check_all(CMD_PUBLISH, properties);
if(properties->client_generated){
outgoing_properties = properties;
}else{
memcpy(&local_property, properties, sizeof(mosquitto_property));
local_property.client_generated = true;
local_property.next = NULL;
outgoing_properties = &local_property;
}
rc = mosquitto_property_check_all(CMD_UNSUBSCRIBE, outgoing_properties);
if(rc) return rc;
}
return send__unsubscribe(mosq, mid, sub, properties);
return send__unsubscribe(mosq, mid, sub, outgoing_properties);
}

@ -149,10 +149,26 @@ int mosquitto_reconnect(struct mosquitto *mosq)
static int mosquitto__reconnect(struct mosquitto *mosq, bool blocking, const mosquitto_property *properties)
{
const mosquitto_property *outgoing_properties = NULL;
mosquitto_property local_property;
int rc;
struct mosquitto__packet *packet;
if(!mosq) return MOSQ_ERR_INVAL;
if(!mosq->host || mosq->port <= 0) return MOSQ_ERR_INVAL;
if(mosq->protocol != mosq_p_mqtt5 && properties) return MOSQ_ERR_NOT_SUPPORTED;
if(properties){
if(properties->client_generated){
outgoing_properties = properties;
}else{
memcpy(&local_property, properties, sizeof(mosquitto_property));
local_property.client_generated = true;
local_property.next = NULL;
outgoing_properties = &local_property;
}
rc = mosquitto_property_check_all(CMD_DISCONNECT, outgoing_properties);
if(rc) return rc;
}
pthread_mutex_lock(&mosq->state_mutex);
#ifdef WITH_SOCKS
@ -223,7 +239,7 @@ static int mosquitto__reconnect(struct mosquitto *mosq, bool blocking, const mos
}else
#endif
{
return send__connect(mosq, mosq->keepalive, mosq->clean_start, properties);
return send__connect(mosq, mosq->keepalive, mosq->clean_start, outgoing_properties);
}
}
@ -235,11 +251,22 @@ int mosquitto_disconnect(struct mosquitto *mosq)
int mosquitto_disconnect_v5(struct mosquitto *mosq, int reason_code, const mosquitto_property *properties)
{
const mosquitto_property *outgoing_properties = NULL;
mosquitto_property local_property;
int rc;
if(!mosq) return MOSQ_ERR_INVAL;
if(mosq->protocol != mosq_p_mqtt5 && properties) return MOSQ_ERR_NOT_SUPPORTED;
if(properties){
rc = mosquitto_property_check_all(CMD_DISCONNECT, properties);
if(properties->client_generated){
outgoing_properties = properties;
}else{
memcpy(&local_property, properties, sizeof(mosquitto_property));
local_property.client_generated = true;
local_property.next = NULL;
outgoing_properties = &local_property;
}
rc = mosquitto_property_check_all(CMD_DISCONNECT, outgoing_properties);
if(rc) return rc;
}
@ -248,7 +275,7 @@ int mosquitto_disconnect_v5(struct mosquitto *mosq, int reason_code, const mosqu
pthread_mutex_unlock(&mosq->state_mutex);
if(mosq->sock == INVALID_SOCKET) return MOSQ_ERR_NO_CONN;
return send__disconnect(mosq, reason_code, properties);
return send__disconnect(mosq, reason_code, outgoing_properties);
}

@ -34,7 +34,7 @@ int handle__connack(struct mosquitto *mosq)
uint8_t reason_code;
int rc;
mosquitto_property *properties = NULL;
const mosquitto_property *prop;
char *clientid = NULL;
assert(mosq);
rc = packet__read_byte(&mosq->in_packet, &connect_flags);
@ -47,30 +47,21 @@ int handle__connack(struct mosquitto *mosq)
if(rc) return rc;
}
prop = mosquitto_property_get_property(properties, MQTT_PROP_ASSIGNED_CLIENT_IDENTIFIER, false);
if(prop){
mosquitto_property_read_string(properties, MQTT_PROP_ASSIGNED_CLIENT_IDENTIFIER, &clientid, false);
if(clientid){
if(mosq->id){
/* We've been sent a client identifier but already have one. This
* shouldn't happen. */
free(clientid);
mosquitto_property_free_all(&properties);
return MOSQ_ERR_PROTOCOL;
}else{
rc = mosquitto_property_read_string(prop, &mosq->id);
if(rc){
mosquitto_property_free_all(&properties);
return rc;
}
mosq->id = clientid;
clientid = NULL;
}
}
prop = mosquitto_property_get_property(properties, MQTT_PROP_SERVER_KEEP_ALIVE, false);
if(prop){
rc = mosquitto_property_read_int16(prop, &mosq->keepalive);
if(rc){
mosquitto_property_free_all(&properties);
return rc;
}
}
mosquitto_property_read_int16(properties, MQTT_PROP_SERVER_KEEP_ALIVE, &mosq->keepalive, false);
log__printf(mosq, MOSQ_LOG_DEBUG, "Client %s received CONNACK (%d)", mosq->id, reason_code);
pthread_mutex_lock(&mosq->callback_mutex);

@ -106,7 +106,6 @@ MOSQ_1.6 {
mosquitto_property_add_string;
mosquitto_property_add_string_pair;
mosquitto_property_add_varint;
mosquitto_property_get_property;
mosquitto_property_read_binary;
mosquitto_property_read_byte;
mosquitto_property_read_int16;

@ -2428,17 +2428,26 @@ libmosq_EXPORT int mosquitto_property_add_string(mosquitto_property **proplist,
libmosq_EXPORT int mosquitto_property_add_string_pair(mosquitto_property **proplist, int identifier, const char *name, const char *value);
/*
* Function: mosquitto_property_get_property
* Function: mosquitto_property_read_byte
*
* Attempt to read a byte property matching an identifier, from a property list
* or single property. This function can search for multiple entries of the
* same identifier by using the returned value and skip_first. Note however
* that it is forbidden for most properties to be duplicated.
*
* Retrieve a property matching an identifier, from a property list. This
* function can search for multiple entries of an identifier by using the
* returned value and skip_first.
* If the property is not found, *value will not be modified, so it is safe to
* pass a variable with a default value to be potentially overwritten:
*
* uint16_t keepalive = 60; // default value
* // Get value from property list, or keep default if not found.
* mosquitto_property_read_int16(proplist, MQTT_PROP_SERVER_KEEP_ALIVE, &keepalive, false);
*
* Parameters:
* proplist - mosquitto_property pointer, the list of properties
* proplist - mosquitto_property pointer, the list of properties or single property
* identifier - property identifier (e.g. MQTT_PROP_PAYLOAD_FORMAT_INDICATOR)
* value - pointer to store the value, or NULL if the value is not required.
* skip_first - boolean that indicates whether the first item in the list
* should be ignored or not.
* should be ignored or not. Should usually be set to false.
*
* Returns:
* A valid property pointer if the property is found
@ -2447,30 +2456,17 @@ libmosq_EXPORT int mosquitto_property_add_string_pair(mosquitto_property **propl
* Example:
* // proplist is obtained from a callback
* mosquitto_property *prop;
* prop = mosquitto_property_get_property(proplist, MQTT_PROP_USER_PROPERTY, false);
* prop = mosquitto_property_read_byte(proplist, identifier, &value, false);
* while(prop){
* mosquitto_property_read_string_pair(prop, &key, &value);
* printf("key: %s value: %s\n", key, value);
*
* prop = mosquitto_property_get_property(prop, MQTT_PROP_USER_PROPERTY, true);
* printf("value: %s\n", value);
* prop = mosquitto_property_read_byte(prop, identifier, &value);
* }
*/
libmosq_EXPORT const mosquitto_property *mosquitto_property_get_property(const mosquitto_property *proplist, int identifier, bool skip_first);
/*
* Function: mosquitto_property_read_byte
*
* Read a byte property value from a property.
*
* Parameters:
* property - property to read
* value - pointer to integer, for the property to be stored in
*
* Returns:
* MOSQ_ERR_SUCCESS - on success
* MOSQ_ERR_INVAL - if property or value is NULL, or if property is not a byte
*/
libmosq_EXPORT int mosquitto_property_read_byte(const mosquitto_property *property, uint8_t *value);
libmosq_EXPORT const mosquitto_property *mosquitto_property_read_byte(
const mosquitto_property *proplist,
int identifier,
uint8_t *value,
bool skip_first);
/*
* Function: mosquitto_property_read_int16
@ -2479,13 +2475,23 @@ libmosq_EXPORT int mosquitto_property_read_byte(const mosquitto_property *proper
*
* Parameters:
* property - property to read
* value - pointer to integer, for the property to be stored in
* identifier - property identifier (e.g. MQTT_PROP_PAYLOAD_FORMAT_INDICATOR)
* value - pointer to store the value, or NULL if the value is not required.
* skip_first - boolean that indicates whether the first item in the list
* should be ignored or not. Should usually be set to false.
*
* Returns:
* MOSQ_ERR_SUCCESS - on success
* MOSQ_ERR_INVAL - if property or value is NULL, or if property is not a uint16
* A valid property pointer if the property is found
* NULL, if the property is not found, or proplist is NULL.
*
* Example:
* See <mosquitto_property_read_byte>
*/
libmosq_EXPORT int mosquitto_property_read_int16(const mosquitto_property *property, uint16_t *value);
libmosq_EXPORT const mosquitto_property *mosquitto_property_read_int16(
const mosquitto_property *proplist,
int identifier,
uint16_t *value,
bool skip_first);
/*
* Function: mosquitto_property_read_int32
@ -2494,13 +2500,23 @@ libmosq_EXPORT int mosquitto_property_read_int16(const mosquitto_property *prope
*
* Parameters:
* property - pointer to mosquitto_property pointer, the list of properties
* value - pointer to integer, for the property to be stored in
* identifier - property identifier (e.g. MQTT_PROP_PAYLOAD_FORMAT_INDICATOR)
* value - pointer to store the value, or NULL if the value is not required.
* skip_first - boolean that indicates whether the first item in the list
* should be ignored or not. Should usually be set to false.
*
* Returns:
* MOSQ_ERR_SUCCESS - on success
* MOSQ_ERR_INVAL - if property or value is NULL, or if property is not an int32
* A valid property pointer if the property is found
* NULL, if the property is not found, or proplist is NULL.
*
* Example:
* See <mosquitto_property_read_byte>
*/
libmosq_EXPORT int mosquitto_property_read_int32(const mosquitto_property *property, uint32_t *value);
libmosq_EXPORT const mosquitto_property *mosquitto_property_read_int32(
const mosquitto_property *proplist,
int identifier,
uint32_t *value,
bool skip_first);
/*
* Function: mosquitto_property_read_varint
@ -2509,13 +2525,23 @@ libmosq_EXPORT int mosquitto_property_read_int32(const mosquitto_property *prope
*
* Parameters:
* property - property to read
* value - pointer to integer, for the property to be stored in
* identifier - property identifier (e.g. MQTT_PROP_PAYLOAD_FORMAT_INDICATOR)
* value - pointer to store the value, or NULL if the value is not required.
* skip_first - boolean that indicates whether the first item in the list
* should be ignored or not. Should usually be set to false.
*
* Returns:
* MOSQ_ERR_SUCCESS - on success
* MOSQ_ERR_INVAL - if property or value is NULL, or if property is not a varint
* A valid property pointer if the property is found
* NULL, if the property is not found, or proplist is NULL.
*
* Example:
* See <mosquitto_property_read_byte>
*/
libmosq_EXPORT int mosquitto_property_read_varint(const mosquitto_property *property, uint32_t *value);
libmosq_EXPORT const mosquitto_property *mosquitto_property_read_varint(
const mosquitto_property *proplist,
int identifier,
uint32_t *value,
bool skip_first);
/*
* Function: mosquitto_property_read_binary
@ -2526,15 +2552,24 @@ libmosq_EXPORT int mosquitto_property_read_varint(const mosquitto_property *prop
*
* Parameters:
* property - property to read
* value - pointer to void pointer, for the property data to be stored in
* len - int pointer to store the data length
* identifier - property identifier (e.g. MQTT_PROP_PAYLOAD_FORMAT_INDICATOR)
* value - pointer to store the value, or NULL if the value is not required.
* skip_first - boolean that indicates whether the first item in the list
* should be ignored or not. Should usually be set to false.
*
* Returns:
* MOSQ_ERR_SUCCESS - on success
* MOSQ_ERR_INVAL - if property, len, or value is NULL, or if property is not a binary type
* MOSQ_ERR_NOMEM - on out of memory
* A valid property pointer if the property is found
* NULL, if the property is not found, or proplist is NULL, or if an out of memory condition occurred.
*
* Example:
* See <mosquitto_property_read_byte>
*/
libmosq_EXPORT int mosquitto_property_read_binary(const mosquitto_property *property, void **value, int *len);
libmosq_EXPORT const mosquitto_property *mosquitto_property_read_binary(
const mosquitto_property *proplist,
int identifier,
void **value,
int *len,
bool skip_first);
/*
* Function: mosquitto_property_read_string
@ -2545,14 +2580,24 @@ libmosq_EXPORT int mosquitto_property_read_binary(const mosquitto_property *prop
*
* Parameters:
* property - property to read
* value - pointer to char*, for the property data to be stored in
* identifier - property identifier (e.g. MQTT_PROP_PAYLOAD_FORMAT_INDICATOR)
* value - pointer to char*, for the property data to be stored in, or NULL if
* the value is not required.
* skip_first - boolean that indicates whether the first item in the list
* should be ignored or not. Should usually be set to false.
*
* Returns:
* MOSQ_ERR_SUCCESS - on success
* MOSQ_ERR_INVAL - if property or value is NULL, or if property is not a string
* MOSQ_ERR_NOMEM - on out of memory
* A valid property pointer if the property is found
* NULL, if the property is not found, or proplist is NULL, or if an out of memory condition occurred.
*
* Example:
* See <mosquitto_property_read_byte>
*/
libmosq_EXPORT int mosquitto_property_read_string(const mosquitto_property *property, char **value);
libmosq_EXPORT const mosquitto_property *mosquitto_property_read_string(
const mosquitto_property *proplist,
int identifier,
char **value,
bool skip_first);
/*
* Function: mosquitto_property_read_string_pair
@ -2563,15 +2608,27 @@ libmosq_EXPORT int mosquitto_property_read_string(const mosquitto_property *prop
*
* Parameters:
* property - property to read
* name - pointer to char* for the name property data to be stored in
* value - pointer to char* for the value property data to be stored in
* identifier - property identifier (e.g. MQTT_PROP_PAYLOAD_FORMAT_INDICATOR)
* name - pointer to char* for the name property data to be stored in, or NULL
* if the name is not required.
* value - pointer to char*, for the property data to be stored in, or NULL if
* the value is not required.
* skip_first - boolean that indicates whether the first item in the list
* should be ignored or not. Should usually be set to false.
*
* Returns:
* MOSQ_ERR_SUCCESS - on success
* MOSQ_ERR_INVAL - if property, name, or value is NULL, or if property is not a string pair
* MOSQ_ERR_NOMEM - on out of memory
*/
libmosq_EXPORT int mosquitto_property_read_string_pair(const mosquitto_property *property, char **name, char **value);
* A valid property pointer if the property is found
* NULL, if the property is not found, or proplist is NULL, or if an out of memory condition occurred.
*
* Example:
* See <mosquitto_property_read_byte>
*/
libmosq_EXPORT const mosquitto_property *mosquitto_property_read_string_pair(
const mosquitto_property *proplist,
int identifier,
char **name,
char **value,
bool skip_first);
/*
* Function: mosquitto_property_free_all

@ -636,6 +636,7 @@ int mosquitto_property_add_byte(mosquitto_property **proplist, int identifier, u
prop = mosquitto__calloc(1, sizeof(mosquitto_property));
if(!prop) return MOSQ_ERR_NOMEM;
prop->client_generated = true;
prop->identifier = identifier;
prop->value.i8 = value;
@ -659,6 +660,7 @@ int mosquitto_property_add_int16(mosquitto_property **proplist, int identifier,
prop = mosquitto__calloc(1, sizeof(mosquitto_property));
if(!prop) return MOSQ_ERR_NOMEM;
prop->client_generated = true;
prop->identifier = identifier;
prop->value.i16 = value;
@ -683,6 +685,7 @@ int mosquitto_property_add_int32(mosquitto_property **proplist, int identifier,
prop = mosquitto__calloc(1, sizeof(mosquitto_property));
if(!prop) return MOSQ_ERR_NOMEM;
prop->client_generated = true;
prop->identifier = identifier;
prop->value.i32 = value;
@ -701,6 +704,7 @@ int mosquitto_property_add_varint(mosquitto_property **proplist, int identifier,
prop = mosquitto__calloc(1, sizeof(mosquitto_property));
if(!prop) return MOSQ_ERR_NOMEM;
prop->client_generated = true;
prop->identifier = identifier;
prop->value.varint = value;
@ -723,6 +727,7 @@ int mosquitto_property_add_binary(mosquitto_property **proplist, int identifier,
prop = mosquitto__calloc(1, sizeof(mosquitto_property));
if(!prop) return MOSQ_ERR_NOMEM;
prop->client_generated = true;
prop->identifier = identifier;
if(len){
@ -764,6 +769,7 @@ int mosquitto_property_add_string(mosquitto_property **proplist, int identifier,
prop = mosquitto__calloc(1, sizeof(mosquitto_property));
if(!prop) return MOSQ_ERR_NOMEM;
prop->client_generated = true;
prop->identifier = identifier;
if(value && strlen(value)){
prop->value.s.v = mosquitto__strdup(value);
@ -795,6 +801,7 @@ int mosquitto_property_add_string_pair(mosquitto_property **proplist, int identi
prop = mosquitto__calloc(1, sizeof(mosquitto_property));
if(!prop) return MOSQ_ERR_NOMEM;
prop->client_generated = true;
prop->identifier = identifier;
if(name && strlen(name)){
@ -873,7 +880,7 @@ int mosquitto_property_check_all(int command, const mosquitto_property *properti
return MOSQ_ERR_SUCCESS;
}
const mosquitto_property *mosquitto_property_get_property(const mosquitto_property *proplist, int identifier, bool skip_first)
const mosquitto_property *property__get_property(const mosquitto_property *proplist, int identifier, bool skip_first)
{
const mosquitto_property *p;
bool is_first = true;
@ -893,132 +900,168 @@ const mosquitto_property *mosquitto_property_get_property(const mosquitto_proper
}
int mosquitto_property_read_byte(const mosquitto_property *property, uint8_t *value)
const mosquitto_property *mosquitto_property_read_byte(const mosquitto_property *proplist, int identifier, uint8_t *value, bool skip_first)
{
if(!property || !value) return MOSQ_ERR_INVAL;
if(property->identifier != MQTT_PROP_PAYLOAD_FORMAT_INDICATOR
&& property->identifier != MQTT_PROP_REQUEST_PROBLEM_INFORMATION
&& property->identifier != MQTT_PROP_REQUEST_RESPONSE_INFORMATION
&& property->identifier != MQTT_PROP_MAXIMUM_QOS
&& property->identifier != MQTT_PROP_RETAIN_AVAILABLE
&& property->identifier != MQTT_PROP_WILDCARD_SUB_AVAILABLE
&& property->identifier != MQTT_PROP_SUBSCRIPTION_ID_AVAILABLE
&& property->identifier != MQTT_PROP_SHARED_SUB_AVAILABLE){
return MOSQ_ERR_INVAL;
const mosquitto_property *p;
if(!proplist) return NULL;
p = property__get_property(proplist, identifier, skip_first);
if(!p) return NULL;
if(p->identifier != MQTT_PROP_PAYLOAD_FORMAT_INDICATOR
&& p->identifier != MQTT_PROP_REQUEST_PROBLEM_INFORMATION
&& p->identifier != MQTT_PROP_REQUEST_RESPONSE_INFORMATION
&& p->identifier != MQTT_PROP_MAXIMUM_QOS
&& p->identifier != MQTT_PROP_RETAIN_AVAILABLE
&& p->identifier != MQTT_PROP_WILDCARD_SUB_AVAILABLE
&& p->identifier != MQTT_PROP_SUBSCRIPTION_ID_AVAILABLE
&& p->identifier != MQTT_PROP_SHARED_SUB_AVAILABLE){
return NULL;
}
*value = property->value.i8;
if(value) *value = p->value.i8;
return MOSQ_ERR_SUCCESS;
return p;
}
int mosquitto_property_read_int16(const mosquitto_property *property, uint16_t *value)
const mosquitto_property *mosquitto_property_read_int16(const mosquitto_property *proplist, int identifier, uint16_t *value, bool skip_first)
{
if(!property || !value) return MOSQ_ERR_INVAL;
if(property->identifier != MQTT_PROP_SERVER_KEEP_ALIVE
&& property->identifier != MQTT_PROP_RECEIVE_MAXIMUM
&& property->identifier != MQTT_PROP_TOPIC_ALIAS_MAXIMUM
&& property->identifier != MQTT_PROP_TOPIC_ALIAS){
return MOSQ_ERR_INVAL;
const mosquitto_property *p;
if(!proplist) return NULL;
p = property__get_property(proplist, identifier, skip_first);
if(!p) return NULL;
if(p->identifier != MQTT_PROP_SERVER_KEEP_ALIVE
&& p->identifier != MQTT_PROP_RECEIVE_MAXIMUM
&& p->identifier != MQTT_PROP_TOPIC_ALIAS_MAXIMUM
&& p->identifier != MQTT_PROP_TOPIC_ALIAS){
return NULL;
}
*value = property->value.i16;
if(value) *value = p->value.i16;
return MOSQ_ERR_SUCCESS;
return p;
}
int mosquitto_property_read_int32(const mosquitto_property *property, uint32_t *value)
const mosquitto_property *mosquitto_property_read_int32(const mosquitto_property *proplist, int identifier, uint32_t *value, bool skip_first)
{
if(!property || !value) return MOSQ_ERR_INVAL;
if(property->identifier != MQTT_PROP_MESSAGE_EXPIRY_INTERVAL
&& property->identifier != MQTT_PROP_SESSION_EXPIRY_INTERVAL
&& property->identifier != MQTT_PROP_WILL_DELAY_INTERVAL
&& property->identifier != MQTT_PROP_MAXIMUM_PACKET_SIZE){
const mosquitto_property *p;
if(!proplist) return NULL;
return MOSQ_ERR_INVAL;
p = property__get_property(proplist, identifier, skip_first);
if(!p) return NULL;
if(p->identifier != MQTT_PROP_MESSAGE_EXPIRY_INTERVAL
&& p->identifier != MQTT_PROP_SESSION_EXPIRY_INTERVAL
&& p->identifier != MQTT_PROP_WILL_DELAY_INTERVAL
&& p->identifier != MQTT_PROP_MAXIMUM_PACKET_SIZE){
return NULL;
}
*value = property->value.i32;
if(value) *value = p->value.i32;
return MOSQ_ERR_SUCCESS;
return p;
}
int mosquitto_property_read_varint(const mosquitto_property *property, uint32_t *value)
const mosquitto_property *mosquitto_property_read_varint(const mosquitto_property *proplist, int identifier, uint32_t *value, bool skip_first)
{
if(!property || !value) return MOSQ_ERR_INVAL;
if(property->identifier != MQTT_PROP_SUBSCRIPTION_IDENTIFIER){
return MOSQ_ERR_INVAL;
const mosquitto_property *p;
if(!proplist) return NULL;
p = property__get_property(proplist, identifier, skip_first);
if(!p) return NULL;
if(p->identifier != MQTT_PROP_SUBSCRIPTION_IDENTIFIER){
return NULL;
}
*value = property->value.varint;
if(value) *value = p->value.varint;
return MOSQ_ERR_SUCCESS;
return p;
}
int mosquitto_property_read_binary(const mosquitto_property *property, void **value, int *len)
const mosquitto_property *mosquitto_property_read_binary(const mosquitto_property *proplist, int identifier, void **value, int *len, bool skip_first)
{
if(!property || !value || !len) return MOSQ_ERR_INVAL;
if(property->identifier != MQTT_PROP_CORRELATION_DATA
&& property->identifier != MQTT_PROP_AUTHENTICATION_DATA){
const mosquitto_property *p;
if(!proplist || (value && !len) || (!value && len)) return NULL;
return MOSQ_ERR_INVAL;
p = property__get_property(proplist, identifier, skip_first);
if(!p) return NULL;
if(p->identifier != MQTT_PROP_CORRELATION_DATA
&& p->identifier != MQTT_PROP_AUTHENTICATION_DATA){
return NULL;
}
*len = property->value.bin.len;
*value = malloc(*len);
if(!value) return MOSQ_ERR_NOMEM;
if(value){
*len = p->value.bin.len;
*value = malloc(*len);
if(!value) return NULL;
memcpy(*value, property->value.bin.v, *len);
memcpy(*value, p->value.bin.v, *len);
}
return MOSQ_ERR_SUCCESS;
return p;
}
int mosquitto_property_read_string(const mosquitto_property *property, char **value)
const mosquitto_property *mosquitto_property_read_string(const mosquitto_property *proplist, int identifier, char **value, bool skip_first)
{
if(!property || !value) return MOSQ_ERR_INVAL;
if(property->identifier != MQTT_PROP_CONTENT_TYPE
&& property->identifier != MQTT_PROP_RESPONSE_TOPIC
&& property->identifier != MQTT_PROP_ASSIGNED_CLIENT_IDENTIFIER
&& property->identifier != MQTT_PROP_AUTHENTICATION_METHOD
&& property->identifier != MQTT_PROP_RESPONSE_INFORMATION
&& property->identifier != MQTT_PROP_SERVER_REFERENCE
&& property->identifier != MQTT_PROP_REASON_STRING){
return MOSQ_ERR_INVAL;
const mosquitto_property *p;
if(!proplist) return NULL;
p = property__get_property(proplist, identifier, skip_first);
if(!p) return NULL;
if(p->identifier != MQTT_PROP_CONTENT_TYPE
&& p->identifier != MQTT_PROP_RESPONSE_TOPIC
&& p->identifier != MQTT_PROP_ASSIGNED_CLIENT_IDENTIFIER
&& p->identifier != MQTT_PROP_AUTHENTICATION_METHOD
&& p->identifier != MQTT_PROP_RESPONSE_INFORMATION
&& p->identifier != MQTT_PROP_SERVER_REFERENCE
&& p->identifier != MQTT_PROP_REASON_STRING){
return NULL;
}
*value = calloc(1, property->value.s.len+1);
if(!value) return MOSQ_ERR_NOMEM;
if(value){
*value = calloc(1, p->value.s.len+1);
if(!value) return NULL;
memcpy(*value, p->value.s.v, p->value.s.len);
}
memcpy(*value, property->value.s.v, property->value.s.len);
return MOSQ_ERR_SUCCESS;
return p;
}
int mosquitto_property_read_string_pair(const mosquitto_property *property, char **name, char **value)
const mosquitto_property *mosquitto_property_read_string_pair(const mosquitto_property *proplist, int identifier, char **name, char **value, bool skip_first)
{
if(!property || !name || !value) return MOSQ_ERR_INVAL;
if(property->identifier != MQTT_PROP_USER_PROPERTY) return MOSQ_ERR_INVAL;
const mosquitto_property *p;
if(!proplist) return NULL;
*name = calloc(1, property->name.len+1);
if(!name) return MOSQ_ERR_NOMEM;
p = property__get_property(proplist, identifier, skip_first);
if(!p) return NULL;
if(p->identifier != MQTT_PROP_USER_PROPERTY) return NULL;
*value = calloc(1, property->value.s.len+1);
if(!value){
free(*name);
return MOSQ_ERR_NOMEM;
if(name){
*name = calloc(1, p->name.len+1);
if(!name) return NULL;
memcpy(*name, p->name.v, p->name.len);
}
memcpy(*name, property->name.v, property->name.len);
memcpy(*value, property->value.s.v, property->value.s.len);
if(value){
*value = calloc(1, p->value.s.len+1);
if(!value){
if(name) free(*name);
return NULL;
}
memcpy(*value, p->value.s.v, p->value.s.len);
}
return MOSQ_ERR_SUCCESS;
return p;
}

@ -36,6 +36,7 @@ struct mqtt5__property {
} value;
struct mqtt__string name;
int32_t identifier;
bool client_generated;
};

@ -23,7 +23,13 @@ suback_packet = mosq_test.gen_suback(mid, 0, proto_ver=5)
props = mqtt5_props.gen_string_prop(mqtt5_props.PROP_RESPONSE_TOPIC, resp_topic)
props += mqtt5_props.gen_string_prop(mqtt5_props.PROP_CORRELATION_DATA, "corridor")
props = mqtt5_props.prop_finalise(props)
publish1_packet = mosq_test.gen_publish(pub_topic, qos=0, payload="action", proto_ver=5, properties=props)
publish1_packet_incoming = mosq_test.gen_publish(pub_topic, qos=0, payload="action", proto_ver=5, properties=props)
props = mqtt5_props.gen_string_prop(mqtt5_props.PROP_RESPONSE_TOPIC, resp_topic)
props += mqtt5_props.gen_string_prop(mqtt5_props.PROP_CORRELATION_DATA, "corridor")
props += mqtt5_props.gen_string_pair_prop(mqtt5_props.PROP_USER_PROPERTY, "user", "data")
props = mqtt5_props.prop_finalise(props)
publish1_packet_outgoing = mosq_test.gen_publish(pub_topic, qos=0, payload="action", proto_ver=5, properties=props)
props = mqtt5_props.gen_string_prop(mqtt5_props.PROP_CORRELATION_DATA, "corridor")
props = mqtt5_props.prop_finalise(props)
@ -65,8 +71,8 @@ try:
if mosq_test.expect_packet(conn2, "subscribe2", subscribe2_packet):
conn2.send(suback_packet)
if mosq_test.expect_packet(conn1, "publish1", publish1_packet):
conn2.send(publish1_packet)
if mosq_test.expect_packet(conn1, "publish1", publish1_packet_incoming):
conn2.send(publish1_packet_outgoing)
if mosq_test.expect_packet(conn2, "publish2", publish2_packet):
rc = 0

@ -24,13 +24,11 @@ void on_message_v5(struct mosquitto *mosq, void *obj, const struct mosquitto_mes
int rc;
if(!strcmp(msg->topic, "request/topic")){
p_resp = mosquitto_property_get_property(props, MQTT_PROP_RESPONSE_TOPIC, false);
p_resp = mosquitto_property_read_string(props, MQTT_PROP_RESPONSE_TOPIC, &resp_topic, false);
if(p_resp){
p_corr = mosquitto_property_get_property(props, MQTT_PROP_CORRELATION_DATA, false);
if(mosquitto_property_read_string(p_resp, &resp_topic) == MOSQ_ERR_SUCCESS){
rc = mosquitto_publish_v5(mosq, NULL, resp_topic, strlen("a response"), "a response", 0, false, p_corr);
free(resp_topic);
}
p_corr = mosquitto_property_read_binary(props, MQTT_PROP_CORRELATION_DATA, NULL, NULL, false);
rc = mosquitto_publish_v5(mosq, NULL, resp_topic, strlen("a response"), "a response", 0, false, p_corr);
free(resp_topic);
}
}
}

Loading…
Cancel
Save