Utils.cpp
1 #include "Utils.h" 2 3 #include <iomanip> 4 #include <iostream> 5 #include <sstream> 6 7 #include <sdkddkver.h> 8 9 #if WDK_NTDDI_VERSION < NTDDI_WIN10_VB 10 #error "Windows SDK version before 10.0.19041.0 is not supported" 11 #elif WDK_NTDDI_VERSION == NTDDI_WIN10_VB 12 // For Windows SDK version before 10.0.19041.0, remap functions to post-10.0.19041.0 versions 13 #define WINRT_IMPL_CoGetApartmentType WINRT_CoGetApartmentType 14 #endif 15 16 #define MAC_ADDRESS_STR_LENGTH (size_t)17 // Two chars per byte, 5 chars for colon 17 18 namespace ble_peripheral 19 { 20 21 std::string _mac_address_to_str(uint64_t mac_address) 22 { 23 uint8_t *mac_ptr = (uint8_t *)&mac_address; 24 char mac_str[MAC_ADDRESS_STR_LENGTH + 1] = {0}; 25 snprintf(mac_str, MAC_ADDRESS_STR_LENGTH + 1, "%02x:%02x:%02x:%02x:%02x:%02x", mac_ptr[5], mac_ptr[4], mac_ptr[3], 26 mac_ptr[2], mac_ptr[1], mac_ptr[0]); 27 return std::string(mac_str); 28 } 29 30 uint64_t _str_to_mac_address(std::string mac_str) 31 { 32 // TODO: Validate input - Expected Format: XX:XX:XX:XX:XX:XX 33 uint64_t mac_address_number = 0; 34 uint8_t *mac_ptr = (uint8_t *)&mac_address_number; 35 sscanf_s(mac_str.c_str(), "%02hhx:%02hhx:%02hhx:%02hhx:%02hhx:%02hhx", &mac_ptr[5], &mac_ptr[4], &mac_ptr[3], 36 &mac_ptr[2], &mac_ptr[1], &mac_ptr[0]); 37 return mac_address_number; 38 } 39 40 winrt::guid uuid_to_guid(const std::string &uuid) 41 { 42 // TODO: Add proper cleanup / validation 43 std::stringstream helper; 44 for (int i = 0; i < uuid.length(); i++) 45 { 46 if (uuid[i] != '-') 47 { 48 helper << uuid[i]; 49 } 50 } 51 std::string clean_uuid = helper.str(); 52 winrt::guid guid; 53 uint64_t *data4_ptr = (uint64_t *)guid.Data4; 54 55 guid.Data1 = static_cast<uint32_t>(std::strtoul(clean_uuid.substr(0, 8).c_str(), nullptr, 16)); 56 guid.Data2 = static_cast<uint16_t>(std::strtoul(clean_uuid.substr(8, 4).c_str(), nullptr, 16)); 57 guid.Data3 = static_cast<uint16_t>(std::strtoul(clean_uuid.substr(12, 4).c_str(), nullptr, 16)); 58 *data4_ptr = _byteswap_uint64(std::strtoull(clean_uuid.substr(16, 16).c_str(), nullptr, 16)); 59 60 return guid; 61 } 62 63 std::string guid_to_uuid(const winrt::guid &guid) 64 { 65 std::stringstream helper; 66 // TODO: It might be cleaner to use snprintf instead of string streams. 67 68 for (uint32_t i = 0; i < 4; i++) 69 { 70 // * NOTE: We're performing a byte swap! 71 helper << std::hex << std::setw(2) << std::setfill('0') << (int)((uint8_t *)&guid.Data1)[3 - i]; 72 } 73 helper << '-'; 74 for (uint32_t i = 0; i < 2; i++) 75 { 76 // * NOTE: We're performing a byte swap! 77 helper << std::hex << std::setw(2) << std::setfill('0') << (int)((uint8_t *)&guid.Data2)[1 - i]; 78 } 79 helper << '-'; 80 for (uint32_t i = 0; i < 2; i++) 81 { 82 // * NOTE: We're performing a byte swap! 83 helper << std::hex << std::setw(2) << std::setfill('0') << (int)((uint8_t *)&guid.Data3)[1 - i]; 84 } 85 helper << '-'; 86 for (uint32_t i = 0; i < 2; i++) 87 { 88 helper << std::hex << std::setw(2) << std::setfill('0') << (int)guid.Data4[i]; 89 } 90 helper << '-'; 91 for (uint32_t i = 0; i < 6; i++) 92 { 93 helper << std::hex << std::setw(2) << std::setfill('0') << (int)guid.Data4[2 + i]; 94 } 95 return helper.str(); 96 } 97 98 std::vector<uint8_t> to_bytevc(IBuffer buffer) 99 { 100 auto reader = DataReader::FromBuffer(buffer); 101 auto result = std::vector<uint8_t>(reader.UnconsumedBufferLength()); 102 reader.ReadBytes(result); 103 return result; 104 } 105 106 IBuffer from_bytevc(std::vector<uint8_t> bytes) 107 { 108 auto writer = DataWriter(); 109 writer.WriteBytes(bytes); 110 return writer.DetachBuffer(); 111 } 112 113 std::string to_hexstring(std::vector<uint8_t> bytes) 114 { 115 auto ss = std::stringstream(); 116 for (auto b : bytes) 117 ss << std::setw(2) << std::setfill('0') << std::hex << static_cast<int>(b); 118 return ss.str(); 119 } 120 121 std::string to_lower_case(std::string str) 122 { 123 std::transform(str.begin(), str.end(), str.begin(), 124 [](unsigned char c) -> char 125 { return static_cast<char>(std::tolower(c)); }); 126 return str; 127 } 128 129 std::string to_uuidstr(winrt::guid guid) 130 { 131 char chars[36 + 1]; 132 sprintf_s(chars, "%08x-%04hx-%04hx-%02hhx%02hhx-%02hhx%02hhx%02hhx%02hhx%02hhx%02hhx", 133 guid.Data1, guid.Data2, guid.Data3, guid.Data4[0], guid.Data4[1], guid.Data4[2], 134 guid.Data4[3], guid.Data4[4], guid.Data4[5], guid.Data4[6], guid.Data4[7]); 135 return std::string{chars}; 136 } 137 138 } // namespace ble_peripheral