Azure IoT / azure_c_shared_utility

Dependents:   STM32F746_iothub_client_sample_mqtt f767zi_mqtt iothub_client_sample_amqp iothub_client_sample_http ... more

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers uuid.c Source File

uuid.c

00001 // Copyright (c) Microsoft. All rights reserved.
00002 // Licensed under the MIT license. See LICENSE file in the project root for full license information.
00003 
00004 #include <stdlib.h>
00005 #include <stdio.h>
00006 #include "azure_c_shared_utility/gballoc.h"
00007 #include "azure_c_shared_utility/uuid.h"
00008 #include "azure_c_shared_utility/uniqueid.h"
00009 #include "azure_c_shared_utility/optimize_size.h"
00010 #include "azure_c_shared_utility/xlogging.h"
00011 
00012 #define UUID_STRING_LENGTH          36
00013 #define UUID_STRING_SIZE            (UUID_STRING_LENGTH + 1)
00014 #define __SUCCESS__                 0
00015 #define UUID_FORMAT_STRING          "%02x%02x%02x%02x-%02x%02x-%02x%02x-%02x%02x-%02x%02x%02x%02x%02x%02x"
00016 
00017 int UUID_from_string(const char* uuid_string, UUID_T* uuid)
00018 {
00019     int result;
00020 
00021     // Codes_SRS_UUID_09_007: [ If `uuid_string` or `uuid` are NULL, UUID_from_string shall return a non-zero value ]
00022     if (uuid_string == NULL || uuid == NULL)
00023     {
00024         LogError("Invalid argument (uuid_string=%p, uuid=%p)", uuid_string, uuid);
00025         result = __FAILURE__;
00026     }
00027     else
00028     {
00029         size_t uuid_string_length = strlen(uuid_string);
00030 
00031         if (uuid_string_length != UUID_STRING_LENGTH)
00032         {
00033             LogError("Unexpected size for an UUID string (%d)", uuid_string_length);
00034             result = __FAILURE__;
00035         }
00036         else
00037         {
00038             // Codes_SRS_UUID_09_008: [ Each pair of digits in `uuid_string`, excluding dashes, shall be read as a single HEX value and saved on the respective position in `uuid` ]
00039             size_t i, j;
00040             unsigned char* uuid_bytes;
00041 
00042             uuid_bytes = (unsigned char*)uuid;
00043             // Codes_SRS_UUID_09_010: [ If no failures occur, UUID_from_string shall return zero ]
00044             result = __SUCCESS__;
00045 
00046             for (i = 0, j = 0; i < uuid_string_length; )
00047             {
00048                 if (uuid_string[i] == '-')
00049                 {
00050                     i++;
00051                 }
00052                 else
00053                 {
00054                     char double_hex_digit[3] = { 0, 0, 0 };
00055 
00056                     (void)memcpy(double_hex_digit, uuid_string + i, 2);
00057 
00058                     if (sscanf(double_hex_digit, "%02hhx", uuid_bytes + j) != 1)
00059                     {
00060                         // Codes_SRS_UUID_09_009: [ If `uuid` fails to be generated, UUID_from_string shall return a non-zero value ]
00061                         LogError("Failed decoding UUID string (%d)", i);
00062                         result = __FAILURE__;
00063                         break;
00064                     }
00065                     else
00066                     {
00067                         i += 2;
00068                         j++;
00069                     }
00070                 }
00071             }
00072         }
00073     }
00074 
00075     return result;
00076 }
00077 
00078 char* UUID_to_string(const UUID_T* uuid)
00079 {
00080     char* result;
00081 
00082     // Codes_SRS_UUID_09_011: [ If `uuid` is NULL, UUID_to_string shall return a non-zero value ]
00083     if (uuid == NULL)
00084     {
00085         LogError("Invalid argument (uuid is NULL)");
00086         result = NULL;
00087     }
00088     // Codes_SRS_UUID_09_012: [ UUID_to_string shall allocate a valid UUID string (`uuid_string`) as per RFC 4122 ]
00089     else if ((result = (char*)malloc(sizeof(char) * UUID_STRING_SIZE)) == NULL)
00090     {
00091         // Codes_SRS_UUID_09_013: [ If `uuid_string` fails to be allocated, UUID_to_string shall return NULL ]
00092         LogError("Failed allocating UUID string");
00093     }
00094     else
00095     {
00096         unsigned char* uuid_bytes;
00097         int number_of_chars_written;
00098 
00099         uuid_bytes = (unsigned char*)uuid;
00100 
00101         // Codes_SRS_UUID_09_014: [ Each character in `uuid` shall be written in the respective positions of `uuid_string` as a 2-digit HEX value ]  
00102         number_of_chars_written = sprintf(result, "%" PRI_UUID,
00103             UUID_FORMAT_VALUES(uuid_bytes));
00104 
00105         if (number_of_chars_written != UUID_STRING_LENGTH)
00106         {
00107             // Tests_SRS_UUID_09_015: [ If `uuid_string` fails to be set, UUID_to_string shall return NULL ]
00108             LogError("Failed encoding UUID string");
00109             free(result);
00110             result = NULL;
00111         }
00112     }
00113 
00114     // Codes_SRS_UUID_09_016: [ If no failures occur, UUID_to_string shall return `uuid_string` ]
00115     return result;
00116 }
00117 
00118 int UUID_generate(UUID_T* uuid)
00119 {
00120     int result;
00121 
00122     // Codes_SRS_UUID_09_001: [ If `uuid` is NULL, UUID_generate shall return a non-zero value ]
00123     if (uuid == NULL)
00124     {
00125         LogError("Invalid argument (uuid is NULL)");
00126         result = __FAILURE__;
00127     }
00128     else
00129     {
00130         char* uuid_string;
00131 
00132         if ((uuid_string = (char*)malloc(sizeof(char) * UUID_STRING_SIZE)) == NULL)
00133         {
00134             // Codes_SRS_UUID_09_003: [ If the UUID string fails to be obtained, UUID_generate shall fail and return a non-zero value ]
00135             LogError("Failed allocating UUID string");
00136             result = __FAILURE__;
00137         }
00138         else
00139         {
00140             (void)memset(uuid_string, 0, sizeof(char) * UUID_STRING_SIZE);
00141 
00142             // Codes_SRS_UUID_09_002: [ UUID_generate shall obtain an UUID string from UniqueId_Generate ]
00143             if (UniqueId_Generate(uuid_string, UUID_STRING_SIZE) != UNIQUEID_OK)
00144             {
00145                 // Codes_SRS_UUID_09_003: [ If the UUID string fails to be obtained, UUID_generate shall fail and return a non-zero value ]
00146                 LogError("Failed generating UUID");
00147                 result = __FAILURE__;
00148             }
00149             // Codes_SRS_UUID_09_004: [ The UUID string shall be parsed into an UUID_T type (16 unsigned char array) and filled in `uuid` ]
00150             else if (UUID_from_string(uuid_string, uuid) != 0)
00151             {
00152                 // Codes_SRS_UUID_09_005: [ If `uuid` fails to be set, UUID_generate shall fail and return a non-zero value ]
00153                 LogError("Failed parsing UUID string");
00154                 result = __FAILURE__;
00155             }
00156             else
00157             {
00158                 // Codes_SRS_UUID_09_006: [ If no failures occur, UUID_generate shall return zero ]
00159                 result = __SUCCESS__;
00160             }
00161 
00162             free(uuid_string);
00163         }
00164     }
00165 
00166     return result;
00167 }