diff --git a/lib/property_mosq.c b/lib/property_mosq.c index f41fb3da..d5ce5631 100644 --- a/lib/property_mosq.c +++ b/lib/property_mosq.c @@ -281,6 +281,83 @@ void property__free_all(struct mqtt5__property **property) } +int property__get_length(struct mqtt5__property *property) +{ + if(!property) return 0; + + switch(property->identifier){ + case PROP_PAYLOAD_FORMAT_INDICATOR: + case PROP_REQUEST_PROBLEM_INFO: + case PROP_REQUEST_RESPONSE_INFO: + case PROP_MAXIMUM_QOS: + case PROP_RETAIN_AVAILABLE: + case PROP_WILDCARD_SUB_AVAILABLE: + case PROP_SUBSCRIPTION_ID_AVAILABLE: + case PROP_SHARED_SUB_AVAILABLE: + return 2; /* 1 (identifier) + 1 byte */ + + case PROP_SERVER_KEEP_ALIVE: + case PROP_RECEIVE_MAXIMUM: + case PROP_TOPIC_ALIAS_MAXIMUM: + case PROP_TOPIC_ALIAS: + return 3; /* 1 (identifier) + 2 bytes */ + + case PROP_MESSAGE_EXPIRY_INTERVAL: + case PROP_WILL_DELAY_INTERVAL: + case PROP_MAXIMUM_PACKET_SIZE: + case PROP_SESSION_EXPIRY_INTERVAL: + return 5; /* 1 (identifier) + 5 bytes */ + + case PROP_SUBSCRIPTION_IDENTIFIER: + if(property->value.varint < 128){ + return 1; + }else if(property->value.varint < 16384){ + return 2; + }else if(property->value.varint < 2097152){ + return 3; + }else if(property->value.varint < 268435456){ + return 4; + }else{ + return 0; + } + + case PROP_CORRELATION_DATA: + case PROP_AUTHENTICATION_DATA: + return 3 + property->value.bin.len; /* 1 + 2 bytes (len) + X bytes (payload) */ + + case PROP_CONTENT_TYPE: + case PROP_RESPONSE_TOPIC: + case PROP_ASSIGNED_CLIENT_IDENTIFIER: + case PROP_AUTHENTICATION_METHOD: + case PROP_RESPONSE_INFO: + case PROP_SERVER_REFERENCE: + case PROP_REASON_STRING: + return 3 + property->value.s.len; /* 1 + 2 bytes (len) + X bytes (string) */ + + case PROP_USER_PROPERTY: + return 5 + property->value.s.len + property->name.len; /* 1 + 2*(2 bytes (len) + X bytes (string))*/ + + default: + return 0; + } + return 0; +} + + +int property__get_length_all(struct mqtt5__property *property) +{ + struct mqtt5__property *p; + int len = 0; + + p = property; + while(p){ + len += property__get_length(p); + p = p->next; + } + return len; +} + + int property__write_all(struct mosquitto__packet *packet, struct mqtt5__property **property) { packet__write_byte(packet, 0); diff --git a/lib/property_mosq.h b/lib/property_mosq.h index 27301eac..7f7ea548 100644 --- a/lib/property_mosq.h +++ b/lib/property_mosq.h @@ -44,4 +44,7 @@ int property__write_all(struct mosquitto__packet *packet, struct mqtt5__property void property__free(struct mqtt5__property **property); void property__free_all(struct mqtt5__property **property); +int property__get_length(struct mqtt5__property *property); +int property__get_length_all(struct mqtt5__property *property); + #endif diff --git a/test/unit/property_read.c b/test/unit/property_read.c index 9022e734..4a8fa75d 100644 --- a/test/unit/property_read.c +++ b/test/unit/property_read.c @@ -27,6 +27,7 @@ static void byte_prop_read_helper( CU_ASSERT_EQUAL(properties->identifier, identifier); CU_ASSERT_EQUAL(properties->value.i8, value_expected); CU_ASSERT_PTR_EQUAL(properties->next, NULL); + CU_ASSERT_EQUAL(property__get_length_all(properties), 2); property__free_all(&properties); } CU_ASSERT_PTR_EQUAL(properties, NULL); @@ -81,6 +82,7 @@ static void int32_prop_read_helper( CU_ASSERT_EQUAL(properties->identifier, identifier); CU_ASSERT_EQUAL(properties->value.i32, value_expected); CU_ASSERT_PTR_EQUAL(properties->next, NULL); + CU_ASSERT_EQUAL(property__get_length_all(properties), 5); property__free_all(&properties); } CU_ASSERT_PTR_EQUAL(properties, NULL); @@ -129,6 +131,7 @@ static void int16_prop_read_helper( CU_ASSERT_EQUAL(properties->identifier, identifier); CU_ASSERT_EQUAL(properties->value.i16, value_expected); CU_ASSERT_PTR_EQUAL(properties->next, NULL); + CU_ASSERT_EQUAL(property__get_length_all(properties), 3); property__free_all(&properties); } CU_ASSERT_PTR_EQUAL(properties, NULL); @@ -173,6 +176,7 @@ static void string_prop_read_helper( CU_ASSERT_EQUAL(properties->value.s.len, strlen(value_expected)); CU_ASSERT_STRING_EQUAL(properties->value.s.v, value_expected); CU_ASSERT_PTR_EQUAL(properties->next, NULL); + CU_ASSERT_EQUAL(property__get_length_all(properties), 1+2+strlen(value_expected)); property__free_all(&properties); } CU_ASSERT_PTR_EQUAL(properties, NULL); @@ -236,6 +240,7 @@ static void binary_prop_read_helper( CU_ASSERT_EQUAL(properties->value.bin.len, len_expected); CU_ASSERT_EQUAL(memcmp(properties->value.bin.v, value_expected, len_expected), 0); CU_ASSERT_PTR_EQUAL(properties->next, NULL); + CU_ASSERT_EQUAL(property__get_length_all(properties), 1+2+len_expected); property__free_all(&properties); } CU_ASSERT_PTR_EQUAL(properties, NULL); @@ -289,6 +294,7 @@ static void string_pair_prop_read_helper( CU_ASSERT_PTR_NOT_NULL(properties->next); }else{ CU_ASSERT_PTR_NULL(properties->next); + CU_ASSERT_EQUAL(property__get_length_all(properties), 1+2+strlen(name_expected)+2+strlen(value_expected)); } property__free_all(&properties); } @@ -316,6 +322,17 @@ static void varint_prop_read_helper( CU_ASSERT_EQUAL(properties->identifier, identifier); CU_ASSERT_EQUAL(properties->value.varint, value_expected); CU_ASSERT_PTR_NULL(properties->next); + if(value_expected < 128){ + CU_ASSERT_EQUAL(property__get_length_all(properties), 2); + }else if(value_expected < 16384){ + CU_ASSERT_EQUAL(property__get_length_all(properties), 3); + }else if(value_expected < 2097152){ + CU_ASSERT_EQUAL(property__get_length_all(properties), 4); + }else if(value_expected < 268435456){ + CU_ASSERT_EQUAL(property__get_length_all(properties), 5); + }else{ + CU_FAIL("Incorrect varint value."); + } property__free_all(&properties); } CU_ASSERT_PTR_NULL(properties);