-
Notifications
You must be signed in to change notification settings - Fork 207
Expand file tree
/
Copy pathuniqueid_azsphere.c
More file actions
81 lines (70 loc) · 2.9 KB
/
uniqueid_azsphere.c
File metadata and controls
81 lines (70 loc) · 2.9 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
// Copyright (c) Microsoft. All rights reserved.
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
#include <stdlib.h>
#include <stdint.h>
#include <string.h>
#include <sys/random.h>
#include "azure_macro_utils/macro_utils.h"
#include "azure_c_shared_utility/uniqueid.h"
#include "azure_c_shared_utility/xlogging.h"
#define UUID_LENGTH 36
MU_DEFINE_ENUM_STRINGS(UNIQUEID_RESULT, UNIQUEID_RESULT_VALUES);
// UUID fields as specified in RFC 4122
typedef struct UUID_TAG
{
uint32_t time_low;
uint16_t time_mid;
uint16_t time_hi_and_version;
uint16_t clock_seq_and_variant;
uint8_t node[6];
} UUID;
// lowercase uuid format expected by azure iot sdk
static const char* uuid_format =
"%08x-%04x-%04x-%02x%02x-%02x%02x%02x%02x%02x%02x";
UNIQUEID_RESULT UniqueId_Generate(char* uid, size_t len)
{
UNIQUEID_RESULT result;
/* Codes_SRS_UNIQUEID_07_002: [If uid is NULL then UniqueId_Generate shall return UNIQUEID_INVALID_ARG] */
/* Codes_SRS_UNIQUEID_07_003: [If len is less then 37 then UniqueId_Generate shall return UNIQUEID_INVALID_ARG] */
if (uid == NULL || len < (UUID_LENGTH + 1)) // UUID_LENGTH + 1 to compensate "/0"
{
result = UNIQUEID_INVALID_ARG;
LogError("Buffer Size is Null or Shorter than 37 Characters. (result = %" PRI_MU_ENUM ")", MU_ENUM_VALUE(UNIQUEID_RESULT, result));
}
else
{
// generate version 4 uuid
UUID unique_id;
// get random bytes
ssize_t bytes_got = getrandom(&unique_id, sizeof(unique_id), GRND_NONBLOCK);
if (bytes_got != sizeof(unique_id))
{
LogError("Failed to obtain random numbers from getrandom.");
result = UNIQUEID_ERROR;
}
else
{
// format as version 4 (random) uuid variant 2
unique_id.clock_seq_and_variant = (unique_id.clock_seq_and_variant & 0x3FFF) | 0x8000;
unique_id.time_hi_and_version = (unique_id.time_hi_and_version & 0x0FFF) | 0x4000;
/* Codes_SRS_UNIQUEID_07_001: [UniqueId_Generate shall create a unique Id 36 character long string.] */
// write out unique_id as string
memset(uid, 0, len);
int chars_written = snprintf(uid, len, uuid_format,
unique_id.time_low, unique_id.time_mid, unique_id.time_hi_and_version,
unique_id.clock_seq_and_variant >> 8, unique_id.clock_seq_and_variant & 0xFF,
unique_id.node[0], unique_id.node[1], unique_id.node[2],
unique_id.node[3], unique_id.node[4], unique_id.node[5]);
if (chars_written != UUID_LENGTH)
{
LogError("Failed to convert binary uuid to string format.");
result = UNIQUEID_ERROR;
}
else
{
result = UNIQUEID_OK;
}
}
}
return result;
}