Xin Zhang / azure-iot-c-sdk-f767zi

Dependents:   samplemqtt

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?

UserRevisionLine numberNew 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 }