Microsoft Azure IoTHub client libraries

Dependents:   sht15_remote_monitoring RobotArmDemo iothub_client_sample_amqp f767zi_mqtt ... more

This library implements the Microsoft Azure IoTHub client library. The code is replicated from https://github.com/Azure/azure-iot-sdks

Files at this revision

API Documentation at this revision

Comitter:
AzureIoTClient
Date:
Thu Oct 04 09:15:49 2018 -0700
Parent:
92:97148cf9aa2a
Commit message:
1.2.10

Changed in this revision

blob.c Show annotated file Show diff for this revision Revisions of this file
internal/iothub_client_private.h Show annotated file Show diff for this revision Revisions of this file
iothub.c Show annotated file Show diff for this revision Revisions of this file
iothub_client_authorization.c Show annotated file Show diff for this revision Revisions of this file
iothub_client_core_ll.c Show annotated file Show diff for this revision Revisions of this file
iothub_client_version.h Show annotated file Show diff for this revision Revisions of this file
parson.c Show annotated file Show diff for this revision Revisions of this file
parson.h Show annotated file Show diff for this revision Revisions of this file
diff -r 97148cf9aa2a -r 7c0bbb86b167 blob.c
--- a/blob.c	Tue Sep 11 11:13:11 2018 -0700
+++ b/blob.c	Thu Oct 04 09:15:49 2018 -0700
@@ -285,7 +285,7 @@
                                                 /*Codes_SRS_BLOB_02_026: [ Otherwise, if HTTP response code is >=300 then Blob_UploadMultipleBlocksFromSasUri shall succeed and return BLOB_OK. ]*/
                                                 if (result != BLOB_OK || *httpStatus >= 300)
                                                 {
-                                                    LogError("unable to Blob_UploadBlock. Returned value=%d, httpStatus=%u", result, httpStatus);
+                                                    LogError("unable to Blob_UploadBlock. Returned value=%d, httpStatus=%u", result, (unsigned int)*httpStatus);
                                                     isError = 1;
                                                 }
                                             }
diff -r 97148cf9aa2a -r 7c0bbb86b167 internal/iothub_client_private.h
--- a/internal/iothub_client_private.h	Tue Sep 11 11:13:11 2018 -0700
+++ b/internal/iothub_client_private.h	Thu Oct 04 09:15:49 2018 -0700
@@ -66,6 +66,7 @@
     void* context;
     DLIST_ENTRY entry;
     tickcounter_ms_t ms_timesOutAfter; /* a value of "0" means "no timeout", if the IOTHUBCLIENT_LL's handle tickcounter > msTimesOutAfer then the message shall timeout*/
+    tickcounter_ms_t message_timeout_value;
 }IOTHUB_MESSAGE_LIST;
 
 typedef struct IOTHUB_DEVICE_TWIN_TAG
diff -r 97148cf9aa2a -r 7c0bbb86b167 iothub.c
--- a/iothub.c	Tue Sep 11 11:13:11 2018 -0700
+++ b/iothub.c	Thu Oct 04 09:15:49 2018 -0700
@@ -8,7 +8,7 @@
 #include "azure_c_shared_utility/macro_utils.h"
 #include "iothub.h"
 
-int IoTHub_Init()
+int IoTHub_Init(void)
 {
     int result;
     if (platform_init() != 0)
@@ -23,7 +23,7 @@
     return result;
 }
 
-void IoTHub_Deinit()
+void IoTHub_Deinit(void)
 {
     platform_deinit();
 }
diff -r 97148cf9aa2a -r 7c0bbb86b167 iothub_client_authorization.c
--- a/iothub_client_authorization.c	Tue Sep 11 11:13:11 2018 -0700
+++ b/iothub_client_authorization.c	Thu Oct 04 09:15:49 2018 -0700
@@ -178,7 +178,8 @@
             }
             else
             {
-                if (iothub_device_auth_get_type(result->device_auth_handle) == AUTH_TYPE_SAS)
+                DEVICE_AUTH_TYPE auth_type = iothub_device_auth_get_type(result->device_auth_handle);
+                if (auth_type == AUTH_TYPE_SAS || auth_type == AUTH_TYPE_SYMM_KEY)
                 {
                     result->cred_type = IOTHUB_CREDENTIAL_TYPE_DEVICE_AUTH;
                 }
diff -r 97148cf9aa2a -r 7c0bbb86b167 iothub_client_core_ll.c
--- a/iothub_client_core_ll.c	Tue Sep 11 11:13:11 2018 -0700
+++ b/iothub_client_core_ll.c	Thu Oct 04 09:15:49 2018 -0700
@@ -702,13 +702,6 @@
             free(result);
             result = NULL;
         }
-        else if (tickcounter_get_current_ms(handleData->tickCounter, &result->ms_timesOutAfter) != 0)
-        {
-            LogError("Failure getting tickcount info");
-            CONSTBUFFER_Destroy(result->report_data_handle);
-            free(result);
-            result = NULL;
-        }
         else
         {
             result->item_id = id;
@@ -1324,6 +1317,7 @@
     if (handleData->currentMessageTimeout == 0)
     {
         newEntry->ms_timesOutAfter = 0; /*do not timeout*/
+        newEntry->message_timeout_value = 0;
         result = 0;
     }
     else
@@ -1336,7 +1330,7 @@
         }
         else
         {
-            newEntry->ms_timesOutAfter += handleData->currentMessageTimeout;
+            newEntry->message_timeout_value = handleData->currentMessageTimeout;
             result = 0;
         }
     }
@@ -1581,7 +1575,7 @@
         {
             IOTHUB_MESSAGE_LIST* fullEntry = containingRecord(currentItemInWaitingToSend, IOTHUB_MESSAGE_LIST, entry);
             /*Codes_SRS_IOTHUBCLIENT_LL_02_041: [ If more than value miliseconds have passed since the call to IoTHubClientCore_LL_SendEventAsync then the message callback shall be called with a status code of IOTHUB_CLIENT_CONFIRMATION_TIMEOUT. ]*/
-            if ((fullEntry->ms_timesOutAfter != 0) && (fullEntry->ms_timesOutAfter < nowTick))
+            if ((fullEntry->ms_timesOutAfter != 0) && (((nowTick - fullEntry->ms_timesOutAfter) / 1000) > fullEntry->message_timeout_value))
             {
                 PDLIST_ENTRY theNext = currentItemInWaitingToSend->Flink; /*need to save the next item, because the below operations are destructive*/
                 DList_RemoveEntryList(currentItemInWaitingToSend);
diff -r 97148cf9aa2a -r 7c0bbb86b167 iothub_client_version.h
--- a/iothub_client_version.h	Tue Sep 11 11:13:11 2018 -0700
+++ b/iothub_client_version.h	Thu Oct 04 09:15:49 2018 -0700
@@ -8,7 +8,7 @@
 #ifndef IOTHUB_CLIENT_VERSION_H
 #define IOTHUB_CLIENT_VERSION_H
 
-#define IOTHUB_SDK_VERSION "1.2.9"
+#define IOTHUB_SDK_VERSION "1.2.10"
 
 #include "azure_c_shared_utility/umock_c_prod.h"
 
diff -r 97148cf9aa2a -r 7c0bbb86b167 parson.c
--- a/parson.c	Tue Sep 11 11:13:11 2018 -0700
+++ b/parson.c	Thu Oct 04 09:15:49 2018 -0700
@@ -41,7 +41,9 @@
 
 #define STARTING_CAPACITY 16
 #define MAX_NESTING       2048
-#define FLOAT_FORMAT      "%1.17g"
+
+#define FLOAT_FORMAT "%1.17g" /* do not increase precision without incresing NUM_BUF_SIZE */
+#define NUM_BUF_SIZE 64 /* double printed with "%1.17g" shouldn't be longer than 25 bytes so let's be paranoid and use 64 */
 
 #define SIZEOF_TOKEN(a)       (sizeof(a) - 1)
 #define SKIP_CHAR(str)        ((*str)++)
@@ -51,6 +53,12 @@
 #undef malloc
 #undef free
 
+#if defined(isnan) && defined(isinf)
+#define IS_NUMBER_INVALID(x) (isnan((x)) || isinf((x)))
+#else
+#define IS_NUMBER_INVALID(x) (((x) * 0.0) != 0.0)
+#endif
+
 static JSON_Malloc_Function parson_malloc = malloc;
 static JSON_Free_Function parson_free = free;
 
@@ -102,8 +110,11 @@
 /* JSON Object */
 static JSON_Object * json_object_init(JSON_Value *wrapping_value);
 static JSON_Status   json_object_add(JSON_Object *object, const char *name, JSON_Value *value);
+static JSON_Status   json_object_addn(JSON_Object *object, const char *name, size_t name_len, JSON_Value *value);
 static JSON_Status   json_object_resize(JSON_Object *object, size_t new_capacity);
-static JSON_Value  * json_object_nget_value(const JSON_Object *object, const char *name, size_t n);
+static JSON_Value  * json_object_getn_value(const JSON_Object *object, const char *name, size_t name_len);
+static JSON_Status   json_object_remove_internal(JSON_Object *object, const char *name, int free_value);
+static JSON_Status   json_object_dotremove_internal(JSON_Object *object, const char *name, int free_value);
 static void          json_object_free(JSON_Object *object);
 
 /* JSON Array */
@@ -262,7 +273,8 @@
 
 static char * read_file(const char * filename) {
     FILE *fp = fopen(filename, "r");
-    size_t file_size;
+    size_t size_to_read = 0;
+    size_t size_read = 0;
     long pos;
     char *file_contents;
     if (!fp) {
@@ -274,22 +286,21 @@
         fclose(fp);
         return NULL;
     }
-    file_size = pos;
+    size_to_read = pos;
     rewind(fp);
-    file_contents = (char*)parson_malloc(sizeof(char) * (file_size + 1));
+    file_contents = (char*)parson_malloc(sizeof(char) * (size_to_read + 1));
     if (!file_contents) {
         fclose(fp);
         return NULL;
     }
-    if (fread(file_contents, file_size, 1, fp) < 1) {
-        if (ferror(fp)) {
-            fclose(fp);
-            parson_free(file_contents);
-            return NULL;
-        }
+    size_read = fread(file_contents, 1, size_to_read, fp);
+    if (size_read == 0 || ferror(fp)) {
+        fclose(fp);
+        parson_free(file_contents);
+        return NULL;
     }
     fclose(fp);
-    file_contents[file_size] = '\0';
+    file_contents[size_read] = '\0';
     return file_contents;
 }
 
@@ -343,11 +354,18 @@
 }
 
 static JSON_Status json_object_add(JSON_Object *object, const char *name, JSON_Value *value) {
+    if (name == NULL) {
+        return JSONFailure;
+    }
+    return json_object_addn(object, name, strlen(name), value);
+}
+
+static JSON_Status json_object_addn(JSON_Object *object, const char *name, size_t name_len, JSON_Value *value) {
     size_t index = 0;
     if (object == NULL || name == NULL || value == NULL) {
         return JSONFailure;
     }
-    if (json_object_get_value(object, name) != NULL) {
+    if (json_object_getn_value(object, name, name_len) != NULL) {
         return JSONFailure;
     }
     if (object->count >= object->capacity) {
@@ -357,7 +375,7 @@
         }
     }
     index = object->count;
-    object->names[index] = parson_strdup(name);
+    object->names[index] = parson_strndup(name, name_len);
     if (object->names[index] == NULL) {
         return JSONFailure;
     }
@@ -397,20 +415,58 @@
     return JSONSuccess;
 }
 
-static JSON_Value * json_object_nget_value(const JSON_Object *object, const char *name, size_t n) {
+static JSON_Value * json_object_getn_value(const JSON_Object *object, const char *name, size_t name_len) {
     size_t i, name_length;
     for (i = 0; i < json_object_get_count(object); i++) {
         name_length = strlen(object->names[i]);
-        if (name_length != n) {
+        if (name_length != name_len) {
             continue;
         }
-        if (strncmp(object->names[i], name, n) == 0) {
+        if (strncmp(object->names[i], name, name_len) == 0) {
             return object->values[i];
         }
     }
     return NULL;
 }
 
+static JSON_Status json_object_remove_internal(JSON_Object *object, const char *name, int free_value) {
+    size_t i = 0, last_item_index = 0;
+    if (object == NULL || json_object_get_value(object, name) == NULL) {
+        return JSONFailure;
+    }
+    last_item_index = json_object_get_count(object) - 1;
+    for (i = 0; i < json_object_get_count(object); i++) {
+        if (strcmp(object->names[i], name) == 0) {
+            parson_free(object->names[i]);
+            if (free_value) {
+                json_value_free(object->values[i]);
+            }
+            if (i != last_item_index) { /* Replace key value pair with one from the end */
+                object->names[i] = object->names[last_item_index];
+                object->values[i] = object->values[last_item_index];
+            }
+            object->count -= 1;
+            return JSONSuccess;
+        }
+    }
+    return JSONFailure; /* No execution path should end here */
+}
+
+static JSON_Status json_object_dotremove_internal(JSON_Object *object, const char *name, int free_value) {
+    JSON_Value *temp_value = NULL;
+    JSON_Object *temp_object = NULL;
+    const char *dot_pos = strchr(name, '.');
+    if (dot_pos == NULL) {
+        return json_object_remove_internal(object, name, free_value);
+    }
+    temp_value = json_object_getn_value(object, name, dot_pos - name);
+    if (json_value_get_type(temp_value) != JSONObject) {
+        return JSONFailure;
+    }
+    temp_object = json_value_get_object(temp_value);
+    return json_object_dotremove_internal(temp_object, dot_pos + 1, free_value);
+}
+
 static void json_object_free(JSON_Object *object) {
     size_t i;
     for (i = 0; i < object->count; i++) {
@@ -650,12 +706,18 @@
 }
 
 static JSON_Value * parse_object_value(const char **string, size_t nesting) {
-    JSON_Value *output_value = json_value_init_object(), *new_value = NULL;
-    JSON_Object *output_object = json_value_get_object(output_value);
+    JSON_Value *output_value = NULL, *new_value = NULL;
+    JSON_Object *output_object = NULL;
     char *new_key = NULL;
-    if (output_value == NULL || **string != '{') {
+    output_value = json_value_init_object();
+    if (output_value == NULL) {
         return NULL;
     }
+    if (**string != '{') {
+        json_value_free(output_value);
+        return NULL;
+    }
+    output_object = json_value_get_object(output_value);
     SKIP_CHAR(string);
     SKIP_WHITESPACES(string);
     if (**string == '}') { /* empty object */
@@ -706,11 +768,17 @@
 }
 
 static JSON_Value * parse_array_value(const char **string, size_t nesting) {
-    JSON_Value *output_value = json_value_init_array(), *new_array_value = NULL;
-    JSON_Array *output_array = json_value_get_array(output_value);
-    if (!output_value || **string != '[') {
+    JSON_Value *output_value = NULL, *new_array_value = NULL;
+    JSON_Array *output_array = NULL;
+    output_value = json_value_init_array();
+    if (output_value == NULL) {
         return NULL;
     }
+    if (**string != '[') {
+        json_value_free(output_value);
+        return NULL;
+    }
+    output_array = json_value_get_array(output_value);
     SKIP_CHAR(string);
     SKIP_WHITESPACES(string);
     if (**string == ']') { /* empty array */
@@ -1074,7 +1142,7 @@
     if (object == NULL || name == NULL) {
         return NULL;
     }
-    return json_object_nget_value(object, name, strlen(name));
+    return json_object_getn_value(object, name, strlen(name));
 }
 
 const char * json_object_get_string(const JSON_Object *object, const char *name) {
@@ -1102,7 +1170,7 @@
     if (!dot_position) {
         return json_object_get_value(object, name);
     }
-    object = json_value_get_object(json_object_nget_value(object, name, dot_position - name));
+    object = json_value_get_object(json_object_getn_value(object, name, dot_position - name));
     return json_object_dotget_value(object, dot_position + 1);
 }
 
@@ -1302,7 +1370,7 @@
 
 JSON_Value * json_value_init_number(double number) {
     JSON_Value *new_value = NULL;
-    if ((number * 0.0) != 0.0) { /* nan and inf test */
+    if (IS_NUMBER_INVALID(number)) {
         return NULL;
     }
     new_value = (JSON_Value*)parson_malloc(sizeof(JSON_Value));
@@ -1416,7 +1484,7 @@
 }
 
 size_t json_serialization_size(const JSON_Value *value) {
-    char num_buf[1100]; /* recursively allocating buffer on stack is a bad idea, so let's do it only once */
+    char num_buf[NUM_BUF_SIZE]; /* recursively allocating buffer on stack is a bad idea, so let's do it only once */
     int res = json_serialize_to_buffer_r(value, NULL, 0, 0, num_buf);
     return res < 0 ? 0 : (size_t)(res + 1);
 }
@@ -1441,7 +1509,7 @@
     if (serialized_string == NULL) {
         return JSONFailure;
     }
-    fp = fopen (filename, "w");
+    fp = fopen(filename, "w");
     if (fp == NULL) {
         json_free_serialized_string(serialized_string);
         return JSONFailure;
@@ -1476,7 +1544,7 @@
 }
 
 size_t json_serialization_size_pretty(const JSON_Value *value) {
-    char num_buf[1100]; /* recursively allocating buffer on stack is a bad idea, so let's do it only once */
+    char num_buf[NUM_BUF_SIZE]; /* recursively allocating buffer on stack is a bad idea, so let's do it only once */
     int res = json_serialize_to_buffer_r(value, NULL, 0, 1, num_buf);
     return res < 0 ? 0 : (size_t)(res + 1);
 }
@@ -1501,7 +1569,7 @@
     if (serialized_string == NULL) {
         return JSONFailure;
     }
-    fp = fopen (filename, "w");
+    fp = fopen(filename, "w");
     if (fp == NULL) {
         json_free_serialized_string(serialized_string);
         return JSONFailure;
@@ -1715,34 +1783,44 @@
 
 JSON_Status json_object_dotset_value(JSON_Object *object, const char *name, JSON_Value *value) {
     const char *dot_pos = NULL;
-    char *current_name = NULL;
-    JSON_Object *temp_obj = NULL;
-    JSON_Value *new_value = NULL;
+    JSON_Value *temp_value = NULL, *new_value = NULL;
+    JSON_Object *temp_object = NULL, *new_object = NULL;
+    JSON_Status status = JSONFailure;
+    size_t name_len = 0;
     if (object == NULL || name == NULL || value == NULL) {
         return JSONFailure;
     }
     dot_pos = strchr(name, '.');
     if (dot_pos == NULL) {
         return json_object_set_value(object, name, value);
-    } else {
-        current_name = parson_strndup(name, dot_pos - name);
-        temp_obj = json_object_get_object(object, current_name);
-        if (temp_obj == NULL) {
-            new_value = json_value_init_object();
-            if (new_value == NULL) {
-                parson_free(current_name);
-                return JSONFailure;
-            }
-            if (json_object_add(object, current_name, new_value) == JSONFailure) {
-                json_value_free(new_value);
-                parson_free(current_name);
-                return JSONFailure;
-            }
-            temp_obj = json_object_get_object(object, current_name);
+    }
+    name_len = dot_pos - name;
+    temp_value = json_object_getn_value(object, name, name_len);
+    if (temp_value) {
+        /* Don't overwrite existing non-object (unlike json_object_set_value, but it shouldn't be changed at this point) */
+        if (json_value_get_type(temp_value) != JSONObject) {
+            return JSONFailure;
         }
-        parson_free(current_name);
-        return json_object_dotset_value(temp_obj, dot_pos + 1, value);
+        temp_object = json_value_get_object(temp_value);
+        return json_object_dotset_value(temp_object, dot_pos + 1, value);
+    }
+    new_value = json_value_init_object();
+    if (new_value == NULL) {
+        return JSONFailure;
     }
+    new_object = json_value_get_object(new_value);
+    status = json_object_dotset_value(new_object, dot_pos + 1, value);
+    if (status != JSONSuccess) {
+        json_value_free(new_value);
+        return JSONFailure;
+    }
+    status = json_object_addn(object, name, name_len, new_value);
+    if (status != JSONSuccess) {
+        json_object_dotremove_internal(new_object, dot_pos + 1, 0);
+        json_value_free(new_value);
+        return JSONFailure;
+    }
+    return JSONSuccess;
 }
 
 JSON_Status json_object_dotset_string(JSON_Object *object, const char *name, const char *string) {
@@ -1794,41 +1872,11 @@
 }
 
 JSON_Status json_object_remove(JSON_Object *object, const char *name) {
-    size_t i = 0, last_item_index = 0;
-    if (object == NULL || json_object_get_value(object, name) == NULL) {
-        return JSONFailure;
-    }
-    last_item_index = json_object_get_count(object) - 1;
-    for (i = 0; i < json_object_get_count(object); i++) {
-        if (strcmp(object->names[i], name) == 0) {
-            parson_free(object->names[i]);
-            json_value_free(object->values[i]);
-            if (i != last_item_index) { /* Replace key value pair with one from the end */
-                object->names[i] = object->names[last_item_index];
-                object->values[i] = object->values[last_item_index];
-            }
-            object->count -= 1;
-            return JSONSuccess;
-        }
-    }
-    return JSONFailure; /* No execution path should end here */
+    return json_object_remove_internal(object, name, 1);
 }
 
 JSON_Status json_object_dotremove(JSON_Object *object, const char *name) {
-    const char *dot_pos = strchr(name, '.');
-    char *current_name = NULL;
-    JSON_Object *temp_obj = NULL;
-    if (dot_pos == NULL) {
-        return json_object_remove(object, name);
-    } else {
-        current_name = parson_strndup(name, dot_pos - name);
-        temp_obj = json_object_get_object(object, current_name);
-        parson_free(current_name);
-        if (temp_obj == NULL) {
-            return JSONFailure;
-        }
-        return json_object_dotremove(temp_obj, dot_pos + 1);
-    }
+    return json_object_dotremove_internal(object, name, 1);
 }
 
 JSON_Status json_object_clear(JSON_Object *object) {
diff -r 97148cf9aa2a -r 7c0bbb86b167 parson.h
--- a/parson.h	Tue Sep 11 11:13:11 2018 -0700
+++ b/parson.h	Thu Oct 04 09:15:49 2018 -0700
@@ -174,7 +174,7 @@
 int           json_array_get_boolean(const JSON_Array *array, size_t index); /* returns -1 on fail */
 size_t        json_array_get_count  (const JSON_Array *array);
 JSON_Value  * json_array_get_wrapping_value(const JSON_Array *array);
-    
+
 /* Frees and removes value at given index, does nothing and returns JSONFailure if index doesn't exist.
  * Order of values in array may change during execution.  */
 JSON_Status json_array_remove(JSON_Array *array, size_t i);