Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
iothub_client/src/iothub_client_diagnostic.c@0:f7f1f0d76dd6, 2018-08-23 (annotated)
- Committer:
- XinZhangMS
- Date:
- Thu Aug 23 06:52:14 2018 +0000
- Revision:
- 0:f7f1f0d76dd6
azure-c-sdk for mbed os supporting NUCLEO_F767ZI
Who changed what in which revision?
User | Revision | Line number | New contents of line |
---|---|---|---|
XinZhangMS | 0:f7f1f0d76dd6 | 1 | // Copyright (c) Microsoft. All rights reserved. |
XinZhangMS | 0:f7f1f0d76dd6 | 2 | // Licensed under the MIT license. See LICENSE file in the project root for full license information. |
XinZhangMS | 0:f7f1f0d76dd6 | 3 | |
XinZhangMS | 0:f7f1f0d76dd6 | 4 | #include <stdlib.h> |
XinZhangMS | 0:f7f1f0d76dd6 | 5 | #include <inttypes.h> |
XinZhangMS | 0:f7f1f0d76dd6 | 6 | #include <math.h> |
XinZhangMS | 0:f7f1f0d76dd6 | 7 | #include "azure_c_shared_utility/optimize_size.h" |
XinZhangMS | 0:f7f1f0d76dd6 | 8 | #include "azure_c_shared_utility/gballoc.h" |
XinZhangMS | 0:f7f1f0d76dd6 | 9 | #include "azure_c_shared_utility/xlogging.h" |
XinZhangMS | 0:f7f1f0d76dd6 | 10 | #include "azure_c_shared_utility/agenttime.h" |
XinZhangMS | 0:f7f1f0d76dd6 | 11 | #include "azure_c_shared_utility/buffer_.h" |
XinZhangMS | 0:f7f1f0d76dd6 | 12 | |
XinZhangMS | 0:f7f1f0d76dd6 | 13 | #include "internal/iothub_client_diagnostic.h" |
XinZhangMS | 0:f7f1f0d76dd6 | 14 | |
XinZhangMS | 0:f7f1f0d76dd6 | 15 | #define TIME_STRING_BUFFER_LEN 30 |
XinZhangMS | 0:f7f1f0d76dd6 | 16 | |
XinZhangMS | 0:f7f1f0d76dd6 | 17 | static const int BASE_36 = 36; |
XinZhangMS | 0:f7f1f0d76dd6 | 18 | |
XinZhangMS | 0:f7f1f0d76dd6 | 19 | #define INDEFINITE_TIME ((time_t)-1) |
XinZhangMS | 0:f7f1f0d76dd6 | 20 | |
XinZhangMS | 0:f7f1f0d76dd6 | 21 | static char* get_epoch_time(char* timeBuffer) |
XinZhangMS | 0:f7f1f0d76dd6 | 22 | { |
XinZhangMS | 0:f7f1f0d76dd6 | 23 | char* result; |
XinZhangMS | 0:f7f1f0d76dd6 | 24 | time_t epochTime; |
XinZhangMS | 0:f7f1f0d76dd6 | 25 | int timeLen = sizeof(time_t); |
XinZhangMS | 0:f7f1f0d76dd6 | 26 | |
XinZhangMS | 0:f7f1f0d76dd6 | 27 | if ((epochTime = get_time(NULL)) == INDEFINITE_TIME) |
XinZhangMS | 0:f7f1f0d76dd6 | 28 | { |
XinZhangMS | 0:f7f1f0d76dd6 | 29 | LogError("Failed getting current time"); |
XinZhangMS | 0:f7f1f0d76dd6 | 30 | result = NULL; |
XinZhangMS | 0:f7f1f0d76dd6 | 31 | } |
XinZhangMS | 0:f7f1f0d76dd6 | 32 | else if (timeLen == sizeof(int64_t)) |
XinZhangMS | 0:f7f1f0d76dd6 | 33 | { |
XinZhangMS | 0:f7f1f0d76dd6 | 34 | if (sprintf(timeBuffer, "%"PRIu64, (int64_t)epochTime) < 0) |
XinZhangMS | 0:f7f1f0d76dd6 | 35 | { |
XinZhangMS | 0:f7f1f0d76dd6 | 36 | LogError("Failed sprintf to timeBuffer with 8 bytes of time_t"); |
XinZhangMS | 0:f7f1f0d76dd6 | 37 | result = NULL; |
XinZhangMS | 0:f7f1f0d76dd6 | 38 | } |
XinZhangMS | 0:f7f1f0d76dd6 | 39 | else |
XinZhangMS | 0:f7f1f0d76dd6 | 40 | { |
XinZhangMS | 0:f7f1f0d76dd6 | 41 | result = timeBuffer; |
XinZhangMS | 0:f7f1f0d76dd6 | 42 | } |
XinZhangMS | 0:f7f1f0d76dd6 | 43 | } |
XinZhangMS | 0:f7f1f0d76dd6 | 44 | else if (timeLen == sizeof(int32_t)) |
XinZhangMS | 0:f7f1f0d76dd6 | 45 | { |
XinZhangMS | 0:f7f1f0d76dd6 | 46 | if (sprintf(timeBuffer, "%"PRIu32, (int32_t)epochTime) < 0) |
XinZhangMS | 0:f7f1f0d76dd6 | 47 | { |
XinZhangMS | 0:f7f1f0d76dd6 | 48 | LogError("Failed sprintf to timeBuffer with 4 bytes of time_t"); |
XinZhangMS | 0:f7f1f0d76dd6 | 49 | result = NULL; |
XinZhangMS | 0:f7f1f0d76dd6 | 50 | } |
XinZhangMS | 0:f7f1f0d76dd6 | 51 | else |
XinZhangMS | 0:f7f1f0d76dd6 | 52 | { |
XinZhangMS | 0:f7f1f0d76dd6 | 53 | result = timeBuffer; |
XinZhangMS | 0:f7f1f0d76dd6 | 54 | } |
XinZhangMS | 0:f7f1f0d76dd6 | 55 | } |
XinZhangMS | 0:f7f1f0d76dd6 | 56 | else |
XinZhangMS | 0:f7f1f0d76dd6 | 57 | { |
XinZhangMS | 0:f7f1f0d76dd6 | 58 | LogError("Unknown size of time_t"); |
XinZhangMS | 0:f7f1f0d76dd6 | 59 | result = NULL; |
XinZhangMS | 0:f7f1f0d76dd6 | 60 | } |
XinZhangMS | 0:f7f1f0d76dd6 | 61 | |
XinZhangMS | 0:f7f1f0d76dd6 | 62 | return result; |
XinZhangMS | 0:f7f1f0d76dd6 | 63 | } |
XinZhangMS | 0:f7f1f0d76dd6 | 64 | |
XinZhangMS | 0:f7f1f0d76dd6 | 65 | static char get_base36_char(unsigned char value) |
XinZhangMS | 0:f7f1f0d76dd6 | 66 | { |
XinZhangMS | 0:f7f1f0d76dd6 | 67 | return value <= 9 ? '0' + value : 'a' + value - 10; |
XinZhangMS | 0:f7f1f0d76dd6 | 68 | } |
XinZhangMS | 0:f7f1f0d76dd6 | 69 | |
XinZhangMS | 0:f7f1f0d76dd6 | 70 | static char* generate_eight_random_characters(char *randomString) |
XinZhangMS | 0:f7f1f0d76dd6 | 71 | { |
XinZhangMS | 0:f7f1f0d76dd6 | 72 | int i; |
XinZhangMS | 0:f7f1f0d76dd6 | 73 | char* randomStringPos = randomString; |
XinZhangMS | 0:f7f1f0d76dd6 | 74 | for (i = 0; i < 4; ++i) |
XinZhangMS | 0:f7f1f0d76dd6 | 75 | { |
XinZhangMS | 0:f7f1f0d76dd6 | 76 | int rawRandom = rand(); |
XinZhangMS | 0:f7f1f0d76dd6 | 77 | int first = rawRandom % BASE_36; |
XinZhangMS | 0:f7f1f0d76dd6 | 78 | int second = rawRandom / BASE_36 % BASE_36; |
XinZhangMS | 0:f7f1f0d76dd6 | 79 | *randomStringPos++ = get_base36_char((unsigned char)first); |
XinZhangMS | 0:f7f1f0d76dd6 | 80 | *randomStringPos++ = get_base36_char((unsigned char)second); |
XinZhangMS | 0:f7f1f0d76dd6 | 81 | } |
XinZhangMS | 0:f7f1f0d76dd6 | 82 | *randomStringPos = 0; |
XinZhangMS | 0:f7f1f0d76dd6 | 83 | |
XinZhangMS | 0:f7f1f0d76dd6 | 84 | return randomString; |
XinZhangMS | 0:f7f1f0d76dd6 | 85 | } |
XinZhangMS | 0:f7f1f0d76dd6 | 86 | |
XinZhangMS | 0:f7f1f0d76dd6 | 87 | static bool should_add_diagnostic_info(IOTHUB_DIAGNOSTIC_SETTING_DATA* diagSetting) |
XinZhangMS | 0:f7f1f0d76dd6 | 88 | { |
XinZhangMS | 0:f7f1f0d76dd6 | 89 | bool result = false; |
XinZhangMS | 0:f7f1f0d76dd6 | 90 | if (diagSetting->diagSamplingPercentage > 0) |
XinZhangMS | 0:f7f1f0d76dd6 | 91 | { |
XinZhangMS | 0:f7f1f0d76dd6 | 92 | double number; |
XinZhangMS | 0:f7f1f0d76dd6 | 93 | double percentage; |
XinZhangMS | 0:f7f1f0d76dd6 | 94 | |
XinZhangMS | 0:f7f1f0d76dd6 | 95 | if (diagSetting->currentMessageNumber == UINT32_MAX) |
XinZhangMS | 0:f7f1f0d76dd6 | 96 | { |
XinZhangMS | 0:f7f1f0d76dd6 | 97 | diagSetting->currentMessageNumber %= diagSetting->diagSamplingPercentage * 100; |
XinZhangMS | 0:f7f1f0d76dd6 | 98 | } |
XinZhangMS | 0:f7f1f0d76dd6 | 99 | ++diagSetting->currentMessageNumber; |
XinZhangMS | 0:f7f1f0d76dd6 | 100 | |
XinZhangMS | 0:f7f1f0d76dd6 | 101 | number = diagSetting->currentMessageNumber; |
XinZhangMS | 0:f7f1f0d76dd6 | 102 | percentage = diagSetting->diagSamplingPercentage; |
XinZhangMS | 0:f7f1f0d76dd6 | 103 | result = (floor((number - 2) * percentage / 100.0) < floor((number - 1) * percentage / 100.0)); |
XinZhangMS | 0:f7f1f0d76dd6 | 104 | } |
XinZhangMS | 0:f7f1f0d76dd6 | 105 | return result; |
XinZhangMS | 0:f7f1f0d76dd6 | 106 | } |
XinZhangMS | 0:f7f1f0d76dd6 | 107 | |
XinZhangMS | 0:f7f1f0d76dd6 | 108 | static IOTHUB_MESSAGE_DIAGNOSTIC_PROPERTY_DATA* prepare_message_diagnostic_data() |
XinZhangMS | 0:f7f1f0d76dd6 | 109 | { |
XinZhangMS | 0:f7f1f0d76dd6 | 110 | IOTHUB_MESSAGE_DIAGNOSTIC_PROPERTY_DATA* result = (IOTHUB_MESSAGE_DIAGNOSTIC_PROPERTY_DATA*)malloc(sizeof(IOTHUB_MESSAGE_DIAGNOSTIC_PROPERTY_DATA)); |
XinZhangMS | 0:f7f1f0d76dd6 | 111 | if (result == NULL) |
XinZhangMS | 0:f7f1f0d76dd6 | 112 | { |
XinZhangMS | 0:f7f1f0d76dd6 | 113 | LogError("malloc for DiagnosticData failed"); |
XinZhangMS | 0:f7f1f0d76dd6 | 114 | } |
XinZhangMS | 0:f7f1f0d76dd6 | 115 | else |
XinZhangMS | 0:f7f1f0d76dd6 | 116 | { |
XinZhangMS | 0:f7f1f0d76dd6 | 117 | char* diagId = (char*)malloc(9); |
XinZhangMS | 0:f7f1f0d76dd6 | 118 | if (diagId == NULL) |
XinZhangMS | 0:f7f1f0d76dd6 | 119 | { |
XinZhangMS | 0:f7f1f0d76dd6 | 120 | LogError("malloc for diagId failed"); |
XinZhangMS | 0:f7f1f0d76dd6 | 121 | free(result); |
XinZhangMS | 0:f7f1f0d76dd6 | 122 | result = NULL; |
XinZhangMS | 0:f7f1f0d76dd6 | 123 | } |
XinZhangMS | 0:f7f1f0d76dd6 | 124 | else |
XinZhangMS | 0:f7f1f0d76dd6 | 125 | { |
XinZhangMS | 0:f7f1f0d76dd6 | 126 | char* timeBuffer; |
XinZhangMS | 0:f7f1f0d76dd6 | 127 | |
XinZhangMS | 0:f7f1f0d76dd6 | 128 | (void)generate_eight_random_characters(diagId); |
XinZhangMS | 0:f7f1f0d76dd6 | 129 | result->diagnosticId = diagId; |
XinZhangMS | 0:f7f1f0d76dd6 | 130 | |
XinZhangMS | 0:f7f1f0d76dd6 | 131 | timeBuffer = (char*)malloc(TIME_STRING_BUFFER_LEN); |
XinZhangMS | 0:f7f1f0d76dd6 | 132 | if (timeBuffer == NULL) |
XinZhangMS | 0:f7f1f0d76dd6 | 133 | { |
XinZhangMS | 0:f7f1f0d76dd6 | 134 | LogError("malloc for timeBuffer failed"); |
XinZhangMS | 0:f7f1f0d76dd6 | 135 | free(result->diagnosticId); |
XinZhangMS | 0:f7f1f0d76dd6 | 136 | free(result); |
XinZhangMS | 0:f7f1f0d76dd6 | 137 | result = NULL; |
XinZhangMS | 0:f7f1f0d76dd6 | 138 | } |
XinZhangMS | 0:f7f1f0d76dd6 | 139 | else if (get_epoch_time(timeBuffer) == NULL) |
XinZhangMS | 0:f7f1f0d76dd6 | 140 | { |
XinZhangMS | 0:f7f1f0d76dd6 | 141 | LogError("Failed getting current time"); |
XinZhangMS | 0:f7f1f0d76dd6 | 142 | free(result->diagnosticId); |
XinZhangMS | 0:f7f1f0d76dd6 | 143 | free(result); |
XinZhangMS | 0:f7f1f0d76dd6 | 144 | result = NULL; |
XinZhangMS | 0:f7f1f0d76dd6 | 145 | } |
XinZhangMS | 0:f7f1f0d76dd6 | 146 | else |
XinZhangMS | 0:f7f1f0d76dd6 | 147 | { |
XinZhangMS | 0:f7f1f0d76dd6 | 148 | result->diagnosticCreationTimeUtc = timeBuffer; |
XinZhangMS | 0:f7f1f0d76dd6 | 149 | } |
XinZhangMS | 0:f7f1f0d76dd6 | 150 | } |
XinZhangMS | 0:f7f1f0d76dd6 | 151 | } |
XinZhangMS | 0:f7f1f0d76dd6 | 152 | return result; |
XinZhangMS | 0:f7f1f0d76dd6 | 153 | } |
XinZhangMS | 0:f7f1f0d76dd6 | 154 | |
XinZhangMS | 0:f7f1f0d76dd6 | 155 | int IoTHubClient_Diagnostic_AddIfNecessary(IOTHUB_DIAGNOSTIC_SETTING_DATA* diagSetting, IOTHUB_MESSAGE_HANDLE messageHandle) |
XinZhangMS | 0:f7f1f0d76dd6 | 156 | { |
XinZhangMS | 0:f7f1f0d76dd6 | 157 | int result; |
XinZhangMS | 0:f7f1f0d76dd6 | 158 | /* Codes_SRS_IOTHUB_DIAGNOSTIC_13_001: [ IoTHubClient_Diagnostic_AddIfNecessary should return nonezero if diagSetting or messageHandle is NULL. ]*/ |
XinZhangMS | 0:f7f1f0d76dd6 | 159 | if (diagSetting == NULL || messageHandle == NULL) |
XinZhangMS | 0:f7f1f0d76dd6 | 160 | { |
XinZhangMS | 0:f7f1f0d76dd6 | 161 | result = __FAILURE__; |
XinZhangMS | 0:f7f1f0d76dd6 | 162 | } |
XinZhangMS | 0:f7f1f0d76dd6 | 163 | /* Codes_SRS_IOTHUB_DIAGNOSTIC_13_003: [ If diagSamplingPercentage is equal to 0, message number should not be increased and no diagnostic properties added ]*/ |
XinZhangMS | 0:f7f1f0d76dd6 | 164 | else if (should_add_diagnostic_info(diagSetting)) |
XinZhangMS | 0:f7f1f0d76dd6 | 165 | { |
XinZhangMS | 0:f7f1f0d76dd6 | 166 | /* Codes_SRS_IOTHUB_DIAGNOSTIC_13_004: [ If diagSamplingPercentage is equal to 100, diagnostic properties should be added to all messages]*/ |
XinZhangMS | 0:f7f1f0d76dd6 | 167 | /* Codes_SRS_IOTHUB_DIAGNOSTIC_13_005: [ If diagSamplingPercentage is between(0, 100), diagnostic properties should be added based on percentage]*/ |
XinZhangMS | 0:f7f1f0d76dd6 | 168 | |
XinZhangMS | 0:f7f1f0d76dd6 | 169 | IOTHUB_MESSAGE_DIAGNOSTIC_PROPERTY_DATA* diagnosticData; |
XinZhangMS | 0:f7f1f0d76dd6 | 170 | if ((diagnosticData = prepare_message_diagnostic_data()) == NULL) |
XinZhangMS | 0:f7f1f0d76dd6 | 171 | { |
XinZhangMS | 0:f7f1f0d76dd6 | 172 | result = __FAILURE__; |
XinZhangMS | 0:f7f1f0d76dd6 | 173 | } |
XinZhangMS | 0:f7f1f0d76dd6 | 174 | else |
XinZhangMS | 0:f7f1f0d76dd6 | 175 | { |
XinZhangMS | 0:f7f1f0d76dd6 | 176 | if (IoTHubMessage_SetDiagnosticPropertyData(messageHandle, diagnosticData) != IOTHUB_MESSAGE_OK) |
XinZhangMS | 0:f7f1f0d76dd6 | 177 | { |
XinZhangMS | 0:f7f1f0d76dd6 | 178 | /* Codes_SRS_IOTHUB_DIAGNOSTIC_13_002: [ IoTHubClient_Diagnostic_AddIfNecessary should return nonezero if failing to add diagnostic property. ]*/ |
XinZhangMS | 0:f7f1f0d76dd6 | 179 | result = __FAILURE__; |
XinZhangMS | 0:f7f1f0d76dd6 | 180 | } |
XinZhangMS | 0:f7f1f0d76dd6 | 181 | else |
XinZhangMS | 0:f7f1f0d76dd6 | 182 | { |
XinZhangMS | 0:f7f1f0d76dd6 | 183 | result = 0; |
XinZhangMS | 0:f7f1f0d76dd6 | 184 | } |
XinZhangMS | 0:f7f1f0d76dd6 | 185 | |
XinZhangMS | 0:f7f1f0d76dd6 | 186 | free(diagnosticData->diagnosticCreationTimeUtc); |
XinZhangMS | 0:f7f1f0d76dd6 | 187 | free(diagnosticData->diagnosticId); |
XinZhangMS | 0:f7f1f0d76dd6 | 188 | free(diagnosticData); |
XinZhangMS | 0:f7f1f0d76dd6 | 189 | diagnosticData = NULL; |
XinZhangMS | 0:f7f1f0d76dd6 | 190 | } |
XinZhangMS | 0:f7f1f0d76dd6 | 191 | } |
XinZhangMS | 0:f7f1f0d76dd6 | 192 | else |
XinZhangMS | 0:f7f1f0d76dd6 | 193 | { |
XinZhangMS | 0:f7f1f0d76dd6 | 194 | result = 0; |
XinZhangMS | 0:f7f1f0d76dd6 | 195 | } |
XinZhangMS | 0:f7f1f0d76dd6 | 196 | |
XinZhangMS | 0:f7f1f0d76dd6 | 197 | return result; |
XinZhangMS | 0:f7f1f0d76dd6 | 198 | } |