source: azure_iot_hub_f767zi/trunk/azure_iot_sdk/iothub_client/src/iothub_client_diagnostic.c@ 457

Last change on this file since 457 was 457, checked in by coas-nagasima, 4 years ago

ファイルを追加

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