From 8e1bdfdca2ad2157fd74cedc1a6768a1b1c0849d Mon Sep 17 00:00:00 2001
From: gcontini <1121667+gcontini@users.noreply.github.com>
Date: 周日, 09 2月 2020 04:48:55 +0800
Subject: [PATCH] identifiers next work

---
 src/library/locate/ExternalDefinition.cpp                |    7 
 src/library/os/linux/execution_environment.cpp           |    5 
 src/library/pc_identifier/disk_strategy.cpp              |   36 +
 src/library/pc_identifier/default_strategy.hpp           |    3 
 src/library/base/base64.h                                |    3 
 src/library/limits/license_verifier.cpp                  |    8 
 src/library/os/network.hpp                               |   32 +
 src/library/pc_identifier/disk_strategy.hpp              |    4 
 src/library/locate/EnvironmentVarData.cpp                |    9 
 src/library/os/os.h                                      |   29 -
 src/inspector/inspector.cpp                              |    2 
 src/library/pc_identifier/identification_strategy.cpp    |   35 +
 src/library/os/CMakeLists.txt                            |    4 
 src/library/pc_identifier/identification_strategy.hpp    |    9 
 src/library/locate/LocatorStrategy.cpp                   |    2 
 test/functional/signature_verifier_test.cpp              |    9 
 src/library/pc_identifier/ethernet.hpp                   |    4 
 test/library/CMakeLists.txt                              |    3 
 test/functional/CMakeLists.txt                           |    6 
 src/library/os/openssl/signature_verifier.cpp            |    7 
 src/library/pc_identifier/pc_identifier.cpp              |   54 ++
 src/library/pc_identifier/ethernet.cpp                   |   74 ++--
 src/library/pc_identifier/pc_identifier.hpp              |   15 
 src/library/pc_identifier/pc_identifier_facade.cpp       |   46 -
 test/functional/pc_identifier_it_test.cpp                |   95 +++++
 test/library/pc_identifier/CMakeLists.txt                |   12 
 src/library/pc_identifier/pc_identifier_facade.hpp       |    4 
 test/library/pc_identifier/ethernet_test.cpp             |    0 
 test/library/pc_identifier/disk_strategy_test.cpp        |   10 
 src/library/os/signature_verifier.hpp                    |    4 
 /dev/null                                                |   10 
 test/library/os/CMakeLists.txt                           |   12 
 test/library/pc_identifier/pc_identifier_facade_test.cpp |   61 --
 src/library/os/linux/network.cpp                         |  143 ++++++++
 test/library/os/network_test.cpp                         |   50 ++
 src/library/licensecc.cpp                                |    2 
 src/library/os/windows/signature_verifier.cpp            |    5 
 src/library/pc_identifier/default_strategy.cpp           |   18 
 test/library/Os_Linux_test.cpp                           |   27 -
 src/library/pc_identifier/CMakeLists.txt                 |    2 
 src/library/base/base64.cpp                              |   35 -
 test/library/pc_identifier/pc_identifier_test.cpp        |   65 +++
 42 files changed, 684 insertions(+), 277 deletions(-)

diff --git a/src/inspector/inspector.cpp b/src/inspector/inspector.cpp
index 01b90aa..160c016 100644
--- a/src/inspector/inspector.cpp
+++ b/src/inspector/inspector.cpp
@@ -8,7 +8,7 @@
 using namespace std;
 const map<LCC_API_IDENTIFICATION_STRATEGY, string> stringByStrategyId = {
 	{STRATEGY_DEFAULT, "DEFAULT"}, {STRATEGY_ETHERNET, "MAC"},	 {STRATEGY_IP_ADDRESS, "IP"},
-	{STRATEGY_DISK_NUM, "Disk1"},  {STRATEGY_DISK_LABEL, "Disk2"}, {STRATEGY_PLATFORM_SPECIFIC, "Custom"}};
+	{STRATEGY_DISK_NUM, "Disk1"},  {STRATEGY_DISK_LABEL, "Disk2"}, {STRATEGY_NONE, "Custom"}};
 
 const unordered_map<LCC_EVENT_TYPE, string> stringByEventType = {
 	{LICENSE_OK, "OK "},
diff --git a/src/library/base/base64.cpp b/src/library/base/base64.cpp
index af66658..a8f1c4c 100644
--- a/src/library/base/base64.cpp
+++ b/src/library/base/base64.cpp
@@ -1,5 +1,6 @@
 #include <stdio.h>
 #include <stdlib.h>
+#include <algorithm>
 
 #include "base64.h"
 namespace license {
@@ -102,28 +103,26 @@
 	return encodeBuffer;
 }
 
-unsigned char* unbase64(const char* ascii, int len, int* flen) {
-	const unsigned char* safeAsciiPtr = (const unsigned char*)ascii;
-	unsigned char* bin;
+std::vector<uint8_t> unbase64(const std::string& base64_data) {
+	string tmp_str(base64_data);
+	tmp_str.erase(std::remove(tmp_str.begin(), tmp_str.end(), '\n'), tmp_str.end());
+	const unsigned char* safeAsciiPtr = (const unsigned char*)tmp_str.c_str();
+	std::vector<uint8_t> bin;
 	int cb = 0;
 	int charNo;
 	int pad = 0;
+	int len = tmp_str.size();
 
 	if (len < 2) {  // 2 accesses below would be OOB.
 		// catch empty string, return NULL as result.
 		puts("ERROR: You passed an invalid base64 string (too short). You get NULL back.");
-		*flen = 0;
-		return 0;
+		return bin;
 	}
 	if (safeAsciiPtr[len - 1] == '=') ++pad;
 	if (safeAsciiPtr[len - 2] == '=') ++pad;
 
-	*flen = 3 * len / 4 - pad;
-	bin = (unsigned char*)malloc(*flen);
-	if (!bin) {
-		puts("ERROR: unbase64 could not allocate enough memory.");
-		return 0;
-	}
+	unsigned int flen = 3 * len / 4 - pad;
+	bin.reserve(flen);
 
 	for (charNo = 0; charNo <= len - 4 - pad; charNo += 4) {
 		int A = unb64[safeAsciiPtr[charNo]];
@@ -131,23 +130,21 @@
 		int C = unb64[safeAsciiPtr[charNo + 2]];
 		int D = unb64[safeAsciiPtr[charNo + 3]];
 
-		bin[cb++] = (A << 2) | (B >> 4);
-		bin[cb++] = (B << 4) | (C >> 2);
-		bin[cb++] = (C << 6) | (D);
+		bin.push_back((A << 2) | (B >> 4));
+		bin.push_back((B << 4) | (C >> 2));
+		bin.push_back((C << 6) | (D));
 	}
 
 	if (pad == 1) {
 		int A = unb64[safeAsciiPtr[charNo]];
 		int B = unb64[safeAsciiPtr[charNo + 1]];
 		int C = unb64[safeAsciiPtr[charNo + 2]];
-
-		bin[cb++] = (A << 2) | (B >> 4);
-		bin[cb++] = (B << 4) | (C >> 2);
+		bin.push_back((A << 2) | (B >> 4));
+		bin.push_back((B << 4) | (C >> 2));
 	} else if (pad == 2) {
 		int A = unb64[safeAsciiPtr[charNo]];
 		int B = unb64[safeAsciiPtr[charNo + 1]];
-
-		bin[cb++] = (A << 2) | (B >> 4);
+		bin.push_back((A << 2) | (B >> 4));
 	}
 
 	return bin;
diff --git a/src/library/base/base64.h b/src/library/base/base64.h
index f64c4cd..466a263 100644
--- a/src/library/base/base64.h
+++ b/src/library/base/base64.h
@@ -2,6 +2,7 @@
 #define BASE64_H
 
 #include <string>
+#include <vector>
 
 #if _WIN32
 #include <wtypes.h>
@@ -9,7 +10,7 @@
 
 namespace license {
 
-unsigned char* unbase64(const char* ascii, int len, int* flen);
+std::vector<uint8_t> unbase64(const std::string& base64_data);
 std::string base64(const void* binaryData, size_t len, int lineLenght = -1);
 
 }  // namespace license
diff --git a/src/library/licensecc.cpp b/src/library/licensecc.cpp
index dee72dc..f4e6063 100644
--- a/src/library/licensecc.cpp
+++ b/src/library/licensecc.cpp
@@ -32,7 +32,7 @@
 	bool result = false;
 	if (*bufSize > LCC_API_PC_IDENTIFIER_SIZE && chbuffer != nullptr) {
 		try {
-			string pc_id = license::PcIdentifierFacade::generate_user_pc_signature(pc_id_method);
+			string pc_id = license::pc_identifier::PcIdentifierFacade::generate_user_pc_signature(pc_id_method);
 			strncpy(chbuffer, pc_id.c_str(), *bufSize);
 			result = true;
 		} catch (const std::exception& ex) {
diff --git a/src/library/limits/license_verifier.cpp b/src/library/limits/license_verifier.cpp
index 2f4a7d9..99277f1 100644
--- a/src/library/limits/license_verifier.cpp
+++ b/src/library/limits/license_verifier.cpp
@@ -10,8 +10,8 @@
 
 #include "license_verifier.hpp"
 #include "../pc_identifier/pc_identifier_facade.hpp"
-#include "../os/signature_verifier.h"
 #include "../base/StringUtils.h"
+#include "../os/signature_verifier.hpp"
 
 namespace license {
 using namespace std;
@@ -23,7 +23,7 @@
 FUNCTION_RETURN LicenseVerifier::verify_signature(const FullLicenseInfo& licInfo) {
 	const string licInfoData(licInfo.printForSign());
 
-	FUNCTION_RETURN ret = license::verify_signature(licInfoData, licInfo.license_signature);
+	FUNCTION_RETURN ret = license::os::verify_signature(licInfoData, licInfo.license_signature);
 
 	if (ret == FUNC_RET_OK) {
 		m_event_registry.addEvent(SIGNATURE_VERIFIED, licInfo.source);
@@ -57,7 +57,7 @@
 	}
 	const auto client_sig = licInfo.m_limits.find(PARAM_CLIENT_SIGNATURE);
 	if (is_valid && client_sig != licInfo.m_limits.end()) {
-		const LCC_EVENT_TYPE event = PcIdentifierFacade::validate_pc_signature(client_sig->second);
+		const LCC_EVENT_TYPE event = pc_identifier::PcIdentifierFacade::validate_pc_signature(client_sig->second);
 		m_event_registry.addEvent(event, licInfo.source);
 		is_valid = is_valid && (event == LICENSE_OK);
 	}
@@ -66,7 +66,7 @@
 
 LicenseInfo LicenseVerifier::toLicenseInfo(const FullLicenseInfo& fullLicInfo) const {
 	LicenseInfo info;
-	info.license_type = LOCAL;
+	info.license_type = LCC_LOCAL;
 
 	const auto expiry = fullLicInfo.m_limits.find(PARAM_EXPIRY_DATE);
 	if (expiry != fullLicInfo.m_limits.end()) {
diff --git a/src/library/locate/EnvironmentVarData.cpp b/src/library/locate/EnvironmentVarData.cpp
index 0162dbe..707d6a5 100644
--- a/src/library/locate/EnvironmentVarData.cpp
+++ b/src/library/locate/EnvironmentVarData.cpp
@@ -46,15 +46,14 @@
 }
 
 const std::string EnvironmentVarData::retrieve_license_content(const std::string &licenseLocation) const {
-	string tmpVal = getenv(LCC_LICENSE_LOCATION_ENV_VAR);
+	string env_val = getenv(LCC_LICENSE_LOCATION_ENV_VAR);
 	if (isBase64) {
 		int flen = 0;
-		unsigned char *raw = unbase64(tmpVal.c_str(), tmpVal.length(), &flen);
-		string str = string(reinterpret_cast<char *>(raw));
-		free(raw);
+		vector<uint8_t> data = unbase64(env_val);
+		string str = string(reinterpret_cast<char *>(data.data()));
 		return str;
 	}
-	return tmpVal;
+	return env_val;
 }
 
 }  // namespace locate
diff --git a/src/library/locate/ExternalDefinition.cpp b/src/library/locate/ExternalDefinition.cpp
index 7413aeb..7add948 100644
--- a/src/library/locate/ExternalDefinition.cpp
+++ b/src/library/locate/ExternalDefinition.cpp
@@ -54,10 +54,9 @@
 	if (licenseLocation == get_strategy_name()) {
 		string licData(m_location->licenseData, mstrnlen_s(m_location->licenseData, LCC_API_MAX_LICENSE_DATA_LENGTH));
 		if (m_location->license_data_type == LICENSE_ENCODED) {
-			int flen = 0;
-			unsigned char *raw = unbase64(licData.c_str(), licData.length(), &flen);
-			string str = string(reinterpret_cast<char *>(raw));
-			free(raw);
+			// FIXME what if license is wrong
+			vector<uint8_t> raw = unbase64(licData);
+			string str = string(reinterpret_cast<char *>(raw.data()));
 			return str;
 		} else {
 			return licData;
diff --git a/src/library/locate/LocatorStrategy.cpp b/src/library/locate/LocatorStrategy.cpp
index 8bde5f1..5e64648 100644
--- a/src/library/locate/LocatorStrategy.cpp
+++ b/src/library/locate/LocatorStrategy.cpp
@@ -15,7 +15,7 @@
 using namespace std;
 
 const string LocatorStrategy::retrieve_license_content(const string &licenseLocation) const {
-	return get_file_contents(licenseLocation.c_str(), MAX_LICENSE_LENGTH);
+	return get_file_contents(licenseLocation.c_str(), LCC_API_MAX_LICENSE_DATA_LENGTH);
 }
 
 }  // namespace locate
diff --git a/src/library/os/CMakeLists.txt b/src/library/os/CMakeLists.txt
index 897adb2..35e3f80 100644
--- a/src/library/os/CMakeLists.txt
+++ b/src/library/os/CMakeLists.txt
@@ -5,8 +5,8 @@
 		    linux/execution_environment.cpp
 		    cpu_info_common.cpp
 		    linux/cpu_info.cpp
-		    linux/os-linux.c 
-		    linux/network_id.c)
+		    linux/network.cpp
+		    linux/os-linux.c) 
 	ELSE(UNIX)
   	    add_library(os OBJECT 
   	    cpu_info_common.cpp openssl/signature_verifier.cpp windows/os-win.c)
diff --git a/src/library/os/linux/execution_environment.cpp b/src/library/os/linux/execution_environment.cpp
index a69122a..9744e27 100644
--- a/src/library/os/linux/execution_environment.cpp
+++ b/src/library/os/linux/execution_environment.cpp
@@ -98,7 +98,8 @@
 
 bool ExecutionEnvironment::is_docker() { return (checkContainerProc() == 1 || checkSystemdContainer() == 1); }
 
-CLOUD_PROVIDER ExecutionEnvironment::getCloudProvider() {}
-
+CLOUD_PROVIDER ExecutionEnvironment::getCloudProvider() {
+	// TODO
+}
 
 }  // namespace license
diff --git a/src/library/os/linux/network.cpp b/src/library/os/linux/network.cpp
new file mode 100644
index 0000000..e456989
--- /dev/null
+++ b/src/library/os/linux/network.cpp
@@ -0,0 +1,143 @@
+/**
+ * @file network_id.c
+ * @date 16 Sep 2014
+ * @brief File containing network interface detection functions for Linux.
+ *
+ * The only public function of this module is #getAdapterInfos(OsAdapterInfo *,
+ *		size_t *), other functions are either static or inline.
+ *
+ * Responsibility of this module is to fill OsAdapterInfo structures, in a
+ * predictable way (skip "lo" interfaces,
+ * @TODO: place physical interfaces in front in a repeatable order: "eth", "wlan","ib"
+ * and other interfaces later, first the one with a a specified mac address, then
+ * the ones with only an ip.)
+ */
+
+#ifndef _GNU_SOURCE
+#define _GNU_SOURCE /* To get defns of NI_MAXSERV and NI_MAXHOST */
+#endif
+#include <arpa/inet.h>
+#include <sys/socket.h>
+#include <net/if.h>
+#include <netdb.h>
+#include <ifaddrs.h>
+#include <linux/if_link.h>
+#include <netpacket/packet.h>
+#include <string.h>
+#include <stdio.h>
+#include <unordered_map>
+
+#include "../../base/StringUtils.h"
+#include "../../base/logger.h"
+#include "../network.hpp"
+
+namespace license {
+namespace os {
+using namespace std;
+
+/**
+ *
+ * @param ifnames
+ * @param ifname
+ * @param ifnames_max
+ * @return
+ */
+
+static int ifname_position(char *ifnames, char *ifname, int ifnames_max) {
+	int i, position;
+	position = -1;
+	for (i = 0; i < ifnames_max; i++) {
+		if (strcmp(ifname, &ifnames[i * NI_MAXHOST]) == 0) {
+			position = i;
+			break;
+		}
+	}
+	return position;
+}
+
+/**
+ *
+ * @param adapterInfos
+ * @param adapter_info_size
+ * @return
+ */
+FUNCTION_RETURN getAdapterInfos(vector<OsAdapterInfo> &adapterInfos) {
+	unordered_map<string, OsAdapterInfo> adapterByName;
+
+	FUNCTION_RETURN f_return = FUNC_RET_OK;
+	struct ifaddrs *ifaddr, *ifa;
+	int family, n = 0;
+	unsigned int if_num, if_max;
+
+	if (getifaddrs(&ifaddr) == -1) {
+		LOG_WARN("getifaddrs failed == -1");
+		return FUNC_RET_ERROR;
+	}
+
+	for (ifa = ifaddr, n = 0, if_num = 0; ifa != NULL; ifa = ifa->ifa_next, n++) {
+		if (ifa->ifa_addr == NULL || (ifa->ifa_flags & IFF_LOOPBACK) != 0) {
+			continue;
+		}
+		string if_name(ifa->ifa_name, mstrnlen_s(ifa->ifa_name, NI_MAXHOST));
+		// if_name_position = ifname_position(ifnames, ifa->ifa_name, if_num);
+		// interface name not seen en advance
+		OsAdapterInfo *currentAdapter;
+		// FIXME not working
+		if (adapterByName.find(if_name) == adapterByName.end()) {
+			OsAdapterInfo newAdapter;
+			memset(&newAdapter, 0, sizeof(OsAdapterInfo));
+			strncpy(&newAdapter.description[0], ifa->ifa_name, NI_MAXHOST);
+			adapterByName[if_name] = newAdapter;
+		}
+		auto it = adapterByName.find(if_name);
+		currentAdapter = &it->second;
+		family = ifa->ifa_addr->sa_family;
+		/* Display interface name and family (including symbolic
+		 form of the latter for the common families) */
+#ifdef _DEBUG
+		printf("%-8s %s (%d)\n", ifa->ifa_name,
+			   (family == AF_PACKET) ? "AF_PACKET"
+									 : (family == AF_INET) ? "AF_INET" : (family == AF_INET6) ? "AF_INET6" : "???",
+			   family);
+#endif
+		/* For an AF_INET* interface address, display the address
+		 * || family == AF_INET6*/
+		if (family == AF_INET) {
+			struct sockaddr_in *s1 = (struct sockaddr_in *)ifa->ifa_addr;
+			in_addr_t iaddr = s1->sin_addr.s_addr;
+			currentAdapter->ipv4_address[0] = (iaddr & 0x000000ff);
+			currentAdapter->ipv4_address[1] = (iaddr & 0x0000ff00) >> 8;
+			currentAdapter->ipv4_address[2] = (iaddr & 0x00ff0000) >> 16;
+			currentAdapter->ipv4_address[3] = (iaddr & 0xff000000) >> 24;
+
+		} else if (family == AF_PACKET && ifa->ifa_data != NULL) {
+			struct sockaddr_ll *s1 = (struct sockaddr_ll *)ifa->ifa_addr;
+			int i;
+			for (i = 0; i < 6; i++) {
+				currentAdapter->mac_address[i] = s1->sll_addr[i];
+#ifdef _DEBUG
+				printf("%02x:", s1->sll_addr[i]);
+#endif
+			}
+#ifdef _DEBUG
+			printf("\t %s\n", ifa->ifa_name);
+#endif
+		}
+	}
+	freeifaddrs(ifaddr);
+
+	// FIXME sort by eth , enps, wlan
+	if (adapterByName.size() == 0) {
+		f_return = FUNC_RET_NOT_AVAIL;
+	} else {
+		f_return = FUNC_RET_OK;
+		adapterInfos.reserve(adapterByName.size());
+		for (auto &it : adapterByName) {
+			adapterInfos.push_back(it.second);
+		}
+	}
+	return f_return;
+}
+
+}  // namespace os
+}  // namespace license
diff --git a/src/library/os/linux/network_id.c b/src/library/os/linux/network_id.c
deleted file mode 100644
index 7f48a3f..0000000
--- a/src/library/os/linux/network_id.c
+++ /dev/null
@@ -1,176 +0,0 @@
-/**
- * @file network_id.c
- * @date 16 Sep 2014
- * @brief File containing network interface detection functions for Linux.
- *
- * The only public function of this module is #getAdapterInfos(OsAdapterInfo *,
- *		size_t *), other functions are either static or inline.
- *
- * Responsibility of this module is to fill OsAdapterInfo structures, in a
- * predictable way (skip "lo" interfaces,
- * @TODO: place physical interfaces in front in a repeatable order: "eth", "wlan","ib"
- * and other interfaces later, first the one with a a specified mac address, then
- * the ones with only an ip.)
- */
-
-#ifndef _GNU_SOURCE
-#define _GNU_SOURCE     /* To get defns of NI_MAXSERV and NI_MAXHOST */
-#endif
-#include <arpa/inet.h>
-#include <sys/socket.h>
-#include <netdb.h>
-#include <ifaddrs.h>
-#include <linux/if_link.h>
-#include <netpacket/packet.h>
-#include <string.h>
-#include <stdio.h>
-
-#include "../os.h"
-
-/**
- *
- * @param ifnames
- * @param ifname
- * @param ifnames_max
- * @return
- */
-
-static int ifname_position(char *ifnames, char * ifname, int ifnames_max) {
-	int i, position;
-	position = -1;
-	for (i = 0; i < ifnames_max; i++) {
-		if (strcmp(ifname, &ifnames[i * NI_MAXHOST]) == 0) {
-			position = i;
-			break;
-		}
-	}
-	return position;
-}
-
-/**
- *
- * @param adapterInfos
- * @param adapter_info_size
- * @return
- */
-FUNCTION_RETURN getAdapterInfos(OsAdapterInfo * adapterInfos,
-		size_t * adapter_info_size) {
-
-	FUNCTION_RETURN f_return = FUNC_RET_OK;
-	struct ifaddrs *ifaddr, *ifa;
-	int family, n = 0, if_name_position;
-	unsigned int if_num, if_max;
-	//char host[NI_MAXHOST];
-	char *ifnames;
-
-	if (getifaddrs(&ifaddr) == -1) {
-		perror("getifaddrs");
-		return FUNC_RET_ERROR;
-	}
-
-	if (adapterInfos != NULL) {
-		memset(adapterInfos, 0, (*adapter_info_size) * sizeof(OsAdapterInfo));
-	}
-
-	/* count the maximum number of interfaces */
-	for (ifa = ifaddr, if_max = 0; ifa != NULL; ifa = ifa->ifa_next, n++) {
-		if (ifa->ifa_addr == NULL) {
-			continue;
-		}
-		if_max++;
-	}
-
-	/* allocate space for names */
-	ifnames = (char*) malloc(NI_MAXHOST * if_max);
-	memset(ifnames, 0, NI_MAXHOST * if_max);
-	/* Walk through linked list, maintaining head pointer so we
-	 can free list later */
-	for (ifa = ifaddr, n = 0, if_num = 0; ifa != NULL;
-			ifa = ifa->ifa_next, n++) {
-		if (ifa->ifa_addr == NULL) {
-			continue;
-		}
-		if_name_position = ifname_position(ifnames, ifa->ifa_name, if_num);
-		//interface name not seen en advance
-		if (if_name_position < 0) {
-			strncpy(&ifnames[if_num * NI_MAXHOST], ifa->ifa_name, NI_MAXHOST);
-			if (adapterInfos != NULL && if_num < *adapter_info_size) {
-				strncpy(adapterInfos[if_num].description, ifa->ifa_name,
-				NI_MAXHOST-1);
-			}
-			if_name_position = if_num;
-			if_num++;
-			if (adapterInfos == NULL) {
-				continue;
-			}
-		}
-		family = ifa->ifa_addr->sa_family;
-		/* Display interface name and family (including symbolic
-		 form of the latter for the common families) */
-#ifdef _DEBUG
-		printf("%-8s %s (%d)\n", ifa->ifa_name,
-				(family == AF_PACKET) ? "AF_PACKET" :
-				(family == AF_INET) ? "AF_INET" :
-				(family == AF_INET6) ? "AF_INET6" : "???", family);
-#endif
-		/* For an AF_INET* interface address, display the address
-		 * || family == AF_INET6*/
-		if (family == AF_INET) {
-			/*
-			 s = getnameinfo(ifa->ifa_addr,
-			 (family == AF_INET) ?
-			 sizeof(struct sockaddr_in) :
-			 sizeof(struct sockaddr_in6), host, NI_MAXHOST,
-			 NULL, 0, NI_NUMERICHOST);
-
-			 #ifdef _DEBUG
-			 s = getnameinfo(ifa->ifa_addr, sizeof(struct sockaddr_in), host,
-			 NI_MAXHOST,
-			 NULL, 0, NI_NUMERICHOST);
-			 if (s != 0) {
-			 printf("getnameinfo() failed: %s\n", gai_strerror(s));
-			 }
-			 printf("\t\taddress: <%s>\n", host);
-			 #endif
-			 */
-			if (adapterInfos != NULL && if_name_position < *adapter_info_size) {
-				struct sockaddr_in *s1 = (struct sockaddr_in*) ifa->ifa_addr;
-				in_addr_t iaddr = s1->sin_addr.s_addr;
-				adapterInfos[if_name_position].ipv4_address[0] = (iaddr
-						& 0x000000ff);
-				adapterInfos[if_name_position].ipv4_address[1] = (iaddr
-						& 0x0000ff00) >> 8;
-				adapterInfos[if_name_position].ipv4_address[2] = (iaddr
-						& 0x00ff0000) >> 16;
-				adapterInfos[if_name_position].ipv4_address[3] = (iaddr
-						& 0xff000000) >> 24;
-			}
-		} else if (family == AF_PACKET && ifa->ifa_data != NULL) {
-			struct sockaddr_ll *s1 = (struct sockaddr_ll*) ifa->ifa_addr;
-			if (adapterInfos != NULL && if_name_position < *adapter_info_size) {
-				int i;
-				for (i = 0; i < 6; i++) {
-					adapterInfos[if_name_position].mac_address[i] =
-							s1->sll_addr[i];
-#ifdef _DEBUG
-					printf("%02x:", s1->sll_addr[i]);
-#endif
-				}
-#ifdef _DEBUG
-				printf("\t %s\n", ifa->ifa_name);
-#endif
-
-			}
-		}
-	}
-
-	*adapter_info_size = if_num;
-	if (adapterInfos == NULL) {
-		f_return = FUNC_RET_OK;
-	} else if (*adapter_info_size < if_num) {
-		f_return = FUNC_RET_BUFFER_TOO_SMALL;
-	}
-	freeifaddrs(ifaddr);
-	free(ifnames);
-	return f_return;
-}
diff --git a/src/library/os/network.hpp b/src/library/os/network.hpp
new file mode 100644
index 0000000..6ba1611
--- /dev/null
+++ b/src/library/os/network.hpp
@@ -0,0 +1,32 @@
+/*
+ * network.hpp
+ *
+ *  Created on: Feb 8, 2020
+ *      Author: devel
+ */
+
+#ifndef SRC_LIBRARY_OS_NETWORK_HPP_
+#define SRC_LIBRARY_OS_NETWORK_HPP_
+#include <stdlib.h>
+#include <vector>
+
+#include "../base/base.h"
+
+namespace license {
+namespace os {
+
+typedef enum { IFACE_TYPE_ETHERNET, IFACE_TYPE_WIRELESS } IFACE_TYPE;
+
+typedef struct {
+	int id;
+	char description[1024];
+	unsigned char mac_address[8];
+	unsigned char ipv4_address[4];
+	IFACE_TYPE type;
+} OsAdapterInfo;
+
+FUNCTION_RETURN getAdapterInfos(std::vector<OsAdapterInfo>& adapterInfos);
+
+}  // namespace os
+}  // namespace license
+#endif /* SRC_LIBRARY_OS_NETWORK_HPP_ */
diff --git a/src/library/os/openssl/signature_verifier.cpp b/src/library/os/openssl/signature_verifier.cpp
index 700210b..7760a68 100644
--- a/src/library/os/openssl/signature_verifier.cpp
+++ b/src/library/os/openssl/signature_verifier.cpp
@@ -16,10 +16,11 @@
 
 #include <public_key.h>
 
-#include "../signature_verifier.h"
+#include "../signature_verifier.hpp"
+#include "../../base/logger.h"
 
 namespace license {
-#include "../../base/logger.h"
+namespace os {
 
 static void free_resources(EVP_PKEY* pkey, EVP_MD_CTX* mdctx) {
 	if (pkey) {
@@ -103,5 +104,5 @@
 	free_resources(pkey, mdctx);
 	return result;
 }
-
+}  // namespace os
 } /* namespace license */
diff --git a/src/library/os/os.h b/src/library/os/os.h
index d59e33c..e8d6863 100644
--- a/src/library/os/os.h
+++ b/src/library/os/os.h
@@ -17,25 +17,12 @@
 #include <string.h>
 #include <ctype.h>
 #include <sys/types.h>
-//definition of size_t
+// definition of size_t
 #include <stdlib.h>
 #ifdef __unix__
 #include <unistd.h>
 #include <stdbool.h>
 #endif
-
-
-typedef enum {
-	IFACE_TYPE_ETHERNET, IFACE_TYPE_WIRELESS
-} IFACE_TYPE;
-
-typedef struct {
-	int id;
-	char description[1024];
-	unsigned char mac_address[8];
-	unsigned char ipv4_address[4];
-	IFACE_TYPE type;
-} OsAdapterInfo;
 
 typedef struct {
 	int id;
@@ -45,12 +32,10 @@
 	bool preferred;
 } DiskInfo;
 
-FUNCTION_RETURN getAdapterInfos(OsAdapterInfo * adapterInfos,
-		size_t * adapter_info_size);
-FUNCTION_RETURN getDiskInfos(DiskInfo * diskInfos, size_t * disk_info_size);
+FUNCTION_RETURN getDiskInfos(DiskInfo* diskInfos, size_t* disk_info_size);
 FUNCTION_RETURN getUserHomePath(char[MAX_PATH]);
 FUNCTION_RETURN getModuleName(char buffer[MAX_PATH]);
-FUNCTION_RETURN getCpuId(unsigned char identifier[6]);
+// FUNCTION_RETURN getCpuId(unsigned char identifier[6]);
 FUNCTION_RETURN getMachineName(unsigned char identifier[6]);
 /**
  * Get an identifier of the machine in an os specific way.
@@ -75,11 +60,11 @@
 // FUNCTION_RETURN verifySignature(const char* stringToVerify, const char* signatureB64);
 
 #ifdef _WIN32
-#define SETENV(VAR,VAL) _putenv_s(VAR, VAL);
-#define	UNSETENV(P) _putenv_s(P, "");
+#define SETENV(VAR, VAL) _putenv_s(VAR, VAL);
+#define UNSETENV(P) _putenv_s(P, "");
 #else
-#define SETENV(VAR,VAL) setenv(VAR, VAL, 1);
-#define	UNSETENV(P)	unsetenv(P);
+#define SETENV(VAR, VAL) setenv(VAR, VAL, 1);
+#define UNSETENV(P) unsetenv(P);
 #endif
 
 #ifdef __cplusplus
diff --git a/src/library/os/signature_verifier.h b/src/library/os/signature_verifier.hpp
similarity index 95%
rename from src/library/os/signature_verifier.h
rename to src/library/os/signature_verifier.hpp
index 4dfe1d0..410b229 100644
--- a/src/library/os/signature_verifier.h
+++ b/src/library/os/signature_verifier.hpp
@@ -12,9 +12,9 @@
 #include "../base/base.h"
 
 namespace license {
-
+namespace os {
 FUNCTION_RETURN verify_signature(const std::string& stringToVerify, const std::string& signatureB64);
-
+}
 } /* namespace license */
 
 #endif /* SRC_LIBRARY_OS_VERIFIER_HPP_ */
diff --git a/src/library/os/windows/signature_verifier.cpp b/src/library/os/windows/signature_verifier.cpp
index 3c8779c..05849b4 100644
--- a/src/library/os/windows/signature_verifier.cpp
+++ b/src/library/os/windows/signature_verifier.cpp
@@ -20,11 +20,12 @@
 #include <public_key.h>
 #include "../../base/logger.h"
 #include "../../base/base64.h"
-#include "../signature_verifier.h"
+#include "../signature_verifier.hpp"
 
 #define RSA_KEY_BITLEN 1024
 
 namespace license {
+namespace os {
 using namespace std;
 #define NT_SUCCESS(Status) (((NTSTATUS)(Status)) >= 0)
 
@@ -241,5 +242,5 @@
 	}
 	return result;
 }
-
+}  // namespace os
 } /* namespace license */
diff --git a/src/library/pc_identifier/CMakeLists.txt b/src/library/pc_identifier/CMakeLists.txt
index d0f581e..506c25c 100644
--- a/src/library/pc_identifier/CMakeLists.txt
+++ b/src/library/pc_identifier/CMakeLists.txt
@@ -5,8 +5,6 @@
 	disk_strategy.cpp
 	pc_identifier.cpp
 	default_strategy.cpp
-	
-	#pc-identifiers.c
 )
 
 if(CODE_COVERAGE AND UNIX)
diff --git a/src/library/pc_identifier/default_strategy.cpp b/src/library/pc_identifier/default_strategy.cpp
index 2f1bd7d..0ef4561 100644
--- a/src/library/pc_identifier/default_strategy.cpp
+++ b/src/library/pc_identifier/default_strategy.cpp
@@ -12,6 +12,7 @@
 
 using namespace std;
 namespace license {
+namespace pc_identifier {
 
 static vector<LCC_API_IDENTIFICATION_STRATEGY> available_strategies() {
 	ExecutionEnvironment exec;
@@ -46,11 +47,8 @@
 	FUNCTION_RETURN ret = FUNC_RET_NOT_AVAIL;
 	for (auto it : strategy_to_try) {
 		LCC_API_IDENTIFICATION_STRATEGY strat_to_try = it;
-		auto strategy_ptr = PcIdentifierFacade::STRATEGY_MAP.find(strat_to_try);
-		if (strategy_ptr == PcIdentifierFacade::STRATEGY_MAP.end()) {
-			throw logic_error("strategy not found");
-		}
-		ret = strategy_ptr->second->identify_pc(pc_id);
+		unique_ptr<IdentificationStrategy> strategy_ptr = IdentificationStrategy::get_strategy(strat_to_try);
+		ret = strategy_ptr->identify_pc(pc_id);
 		if (ret == FUNC_RET_OK) {
 			break;
 		}
@@ -64,12 +62,9 @@
 	FUNCTION_RETURN ret = FUNC_RET_NOT_AVAIL;
 	for (auto it : strategy_to_try) {
 		LCC_API_IDENTIFICATION_STRATEGY strat_to_try = it;
-		auto strategy_ptr = PcIdentifierFacade::STRATEGY_MAP.find(strat_to_try);
-		if (strategy_ptr == PcIdentifierFacade::STRATEGY_MAP.end()) {
-			throw logic_error("strategy not found");
-		}
-		vector<PcIdentifier> alt_ids = strategy_ptr->second->alternative_ids();
-		// identifiers.push_back(alt_ids);
+		unique_ptr<IdentificationStrategy> strategy_ptr = IdentificationStrategy::get_strategy(strat_to_try);
+		vector<PcIdentifier> alt_ids = strategy_ptr->alternative_ids();
+		identifiers.insert(alt_ids.begin(), alt_ids.end(), identifiers.end());
 	}
 	return identifiers;
 }
@@ -79,4 +74,5 @@
 	return IDENTIFIERS_MISMATCH;
 }
 
+}  // namespace pc_identifier
 } /* namespace license */
diff --git a/src/library/pc_identifier/default_strategy.hpp b/src/library/pc_identifier/default_strategy.hpp
index b0cda7c..cefb9f8 100644
--- a/src/library/pc_identifier/default_strategy.hpp
+++ b/src/library/pc_identifier/default_strategy.hpp
@@ -10,6 +10,7 @@
 #include "identification_strategy.hpp"
 
 namespace license {
+namespace pc_identifier {
 
 class DefaultStrategy : public IdentificationStrategy {
 public:
@@ -20,7 +21,7 @@
 	virtual std::vector<PcIdentifier> alternative_ids() const;
 	virtual LCC_EVENT_TYPE validate_identifier(const PcIdentifier &identifier) const;
 };
-
+}  // namespace pc_identifier
 } /* namespace license */
 
 #endif /* SRC_LIBRARY_PC_IDENTIFIER_DEFAULT_STRATEGY_HPP_ */
diff --git a/src/library/pc_identifier/disk_strategy.cpp b/src/library/pc_identifier/disk_strategy.cpp
index b2e6c1f..20fe310 100644
--- a/src/library/pc_identifier/disk_strategy.cpp
+++ b/src/library/pc_identifier/disk_strategy.cpp
@@ -10,14 +10,16 @@
 
 using namespace std;
 namespace license {
+namespace pc_identifier {
 
-static FUNCTION_RETURN generate_disk_pc_id(vector<array<uint8_t, 6>> &v_disk_id, bool use_id) {
+static FUNCTION_RETURN generate_disk_pc_id(vector<array<uint8_t, PC_IDENTIFIER_PROPRIETARY_DATA>> &v_disk_id,
+										   bool use_id) {
 	size_t disk_num, available_disk_info = 0;
 	FUNCTION_RETURN result_diskinfos;
 	unsigned int i;
 	DiskInfo *diskInfos;
 
-	result_diskinfos = getDiskInfos(NULL, &disk_num);
+	result_diskinfos = getDiskInfos(nullptr, &disk_num);
 	if (result_diskinfos != FUNC_RET_OK && result_diskinfos != FUNC_RET_BUFFER_TOO_SMALL) {
 		return result_diskinfos;
 	}
@@ -26,6 +28,9 @@
 	}
 
 	diskInfos = (DiskInfo *)malloc(disk_num * sizeof(DiskInfo));
+	if (diskInfos == nullptr) {
+		return FUNC_RET_NOT_AVAIL;
+	}
 	memset(diskInfos, 0, disk_num * sizeof(DiskInfo));
 	result_diskinfos = getDiskInfos(diskInfos, &disk_num);
 	if (result_diskinfos != FUNC_RET_OK) {
@@ -42,7 +47,7 @@
 	}
 	v_disk_id.reserve(available_disk_info);
 	for (i = 0; i < disk_num; i++) {
-		array<uint8_t, 6> a_disk_id;
+		array<uint8_t, PC_IDENTIFIER_PROPRIETARY_DATA> a_disk_id;
 		if (use_id) {
 			if (diskInfos[i].disk_sn[0] != 0) {
 				memcpy(&a_disk_id[0], &diskInfos[i].disk_sn[2], a_disk_id.size());
@@ -51,7 +56,7 @@
 		} else {
 			if (diskInfos[i].label[0] != 0) {
 				a_disk_id.fill(0);
-				// strncpy((&a_disk_id[0], diskInfos[i].label, a_disk_id.size());
+				strncpy((char *)&a_disk_id[0], diskInfos[i].label, a_disk_id.size());
 				v_disk_id.push_back(a_disk_id);
 			}
 		}
@@ -71,7 +76,7 @@
 }
 
 FUNCTION_RETURN DiskStrategy::identify_pc(PcIdentifier &pc_id) const {
-	vector<array<uint8_t, 6>> data;
+	vector<array<uint8_t, PC_IDENTIFIER_PROPRIETARY_DATA>> data;
 	FUNCTION_RETURN result = generate_disk_pc_id(data, m_use_id);
 	if (result == FUNC_RET_OK) {
 		pc_id.set_data(data[0]);
@@ -79,16 +84,31 @@
 	return result;
 }
 
-std::vector<PcIdentifier> DiskStrategy::alternative_ids() const {}
+std::vector<PcIdentifier> DiskStrategy::alternative_ids() const {
+	vector<array<uint8_t, PC_IDENTIFIER_PROPRIETARY_DATA>> data;
+	FUNCTION_RETURN result = generate_disk_pc_id(data, m_use_id);
+	vector<PcIdentifier> identifiers;
+	if (result == FUNC_RET_OK) {
+		identifiers.resize(data.size());
+		for (auto &it : data) {
+			PcIdentifier pc_id;
+			pc_id.set_identification_strategy(identification_strategy());
+			pc_id.set_data(it);
+			identifiers.push_back(pc_id);
+		}
+	}
+	return identifiers;
+}
 
 LCC_EVENT_TYPE DiskStrategy::validate_identifier(const PcIdentifier &identifier) const {
-	vector<array<uint8_t, 6>> data;
+	vector<array<uint8_t, PC_IDENTIFIER_PROPRIETARY_DATA>> data;
 	FUNCTION_RETURN generate_ethernet = generate_disk_pc_id(data, m_use_id);
 	LCC_EVENT_TYPE result = IDENTIFIERS_MISMATCH;
 	if (generate_ethernet == FUNC_RET_OK) {
-		// result = const_cast<IdentificationStrategy *>(this)->validate_identifier(identifier, data);
+		result = validate_identifier(identifier, data);
 	}
 	return result;
 }
 
+}  // namespace pc_identifier
 } /* namespace license */
diff --git a/src/library/pc_identifier/disk_strategy.hpp b/src/library/pc_identifier/disk_strategy.hpp
index 5246269..dd095d3 100644
--- a/src/library/pc_identifier/disk_strategy.hpp
+++ b/src/library/pc_identifier/disk_strategy.hpp
@@ -11,20 +11,22 @@
 #include "identification_strategy.hpp"
 
 namespace license {
+namespace pc_identifier {
 
 class DiskStrategy : public IdentificationStrategy {
 private:
 	bool m_use_id;
-
 public:
 	DiskStrategy(bool use_id);
 	virtual ~DiskStrategy();
 	virtual LCC_API_IDENTIFICATION_STRATEGY identification_strategy() const;
 	virtual FUNCTION_RETURN identify_pc(PcIdentifier &pc_id) const;
 	virtual std::vector<PcIdentifier> alternative_ids() const;
+	using IdentificationStrategy::validate_identifier;
 	virtual LCC_EVENT_TYPE validate_identifier(const PcIdentifier &identifier) const;
 };
 
+}  // namespace pc_identifier
 } /* namespace license */
 
 #endif /* SRC_LIBRARY_PC_IDENTIFIER_DISK_STRATEGY_HPP_ */
diff --git a/src/library/pc_identifier/disk_strategy_test.cpp b/src/library/pc_identifier/disk_strategy_test.cpp
deleted file mode 100644
index f267dfa..0000000
--- a/src/library/pc_identifier/disk_strategy_test.cpp
+++ /dev/null
@@ -1,10 +0,0 @@
-/*
- * disk_strategy_test.cpp
- *
- *  Created on: Jan 14, 2020
- *      Author: devel
- */
-
-#include "disk_strategy.hpp"
-
-namespace license {} /* namespace license */
diff --git a/src/library/pc_identifier/ethernet.cpp b/src/library/pc_identifier/ethernet.cpp
index f7166a7..8c42735 100644
--- a/src/library/pc_identifier/ethernet.cpp
+++ b/src/library/pc_identifier/ethernet.cpp
@@ -4,53 +4,51 @@
  *  Created on: Jan 11, 2020
  *      Author: devel
  */
-#include <array>
 
 #include "ethernet.hpp"
-#include "../os/os.h"
+
+#include <bits/stdint-uintn.h>
+#include <array>
+#include <vector>
+
+#include "../../../include/licensecc/datatypes.h"
+#include "../../../projects/DEFAULT/include/licensecc/DEFAULT/licensecc_properties.h"
+#include "../base/base.h"
+#include "../os/network.hpp"
+#include "pc_identifier.hpp"
 
 namespace license {
+namespace pc_identifier {
 using namespace std;
 
-static FUNCTION_RETURN generate_ethernet_pc_id(vector<array<uint8_t, 6>> &data, bool use_mac) {
-	OsAdapterInfo *adapterInfos;
-	size_t defined_adapters, adapters = 0;
+static FUNCTION_RETURN generate_ethernet_pc_id(vector<array<uint8_t, PC_IDENTIFIER_PROPRIETARY_DATA>> &data,
+											   const bool use_ip) {
+	vector<os::OsAdapterInfo> adapters;
 
-	FUNCTION_RETURN result_adapterInfos = getAdapterInfos(NULL, &adapters);
-	if (result_adapterInfos != FUNC_RET_BUFFER_TOO_SMALL) {
+	FUNCTION_RETURN result_adapterInfos = getAdapterInfos(adapters);
+	if (result_adapterInfos != FUNC_RET_OK) {
 		return result_adapterInfos;
 	}
-	if (adapters == 0) {
+	if (adapters.size() == 0) {
 		return FUNC_RET_NOT_AVAIL;
 	}
 
-	defined_adapters = adapters;
-	data.reserve(adapters);
-	adapterInfos = static_cast<OsAdapterInfo *>(malloc(adapters * sizeof(OsAdapterInfo)));
-	result_adapterInfos = getAdapterInfos(adapterInfos, &adapters);
-	if (result_adapterInfos == FUNC_RET_OK) {
-		unsigned int j;
-		for (j = 0; j < adapters; j++) {
-			unsigned int k;
-			array<uint8_t, 6> identifier;
-			for (k = 0; k < 6; k++) {
-				if (use_mac) {
-					identifier[k] = adapterInfos[j].mac_address[k + 2];
-				} else {
-					// use ip
-					if (k < 4) {
-						identifier[k] = adapterInfos[j].ipv4_address[k];
-					} else {
-						// padding
-						identifier[k] = 42;
-					}
-				}
+	for (auto &it : adapters) {
+		unsigned int k, data_len, data_byte;
+		array<uint8_t, PC_IDENTIFIER_PROPRIETARY_DATA> identifier;
+		data_len = use_ip ? sizeof(os::OsAdapterInfo::ipv4_address) : sizeof(os::OsAdapterInfo::mac_address);
+
+		for (k = 0; k < PC_IDENTIFIER_PROPRIETARY_DATA; k++) {
+			if (k < data_len) {
+				identifier[k] = use_ip ? it.ipv4_address[k] : it.mac_address[k];
+			} else {
+				identifier[k] = 42;
 			}
-			identifier[6] = identifier[6] & 0x1F;
-			data.push_back(identifier);
 		}
-	}
-	free(adapterInfos);
+		identifier[0] = identifier[0] & 0x1F;
+		data.push_back(identifier);
+		}
+
 	return result_adapterInfos;
 }
 
@@ -61,7 +59,7 @@
 LCC_API_IDENTIFICATION_STRATEGY Ethernet::identification_strategy() const { return STRATEGY_ETHERNET; }
 
 FUNCTION_RETURN Ethernet::identify_pc(PcIdentifier &pc_id) const {
-	vector<array<uint8_t, 6>> data;
+	vector<array<uint8_t, PC_IDENTIFIER_PROPRIETARY_DATA>> data;
 	FUNCTION_RETURN result = generate_ethernet_pc_id(data, use_ip);
 	if (result == FUNC_RET_OK) {
 		pc_id.set_data(data[0]);
@@ -70,7 +68,7 @@
 }
 
 std::vector<PcIdentifier> Ethernet::alternative_ids() const {
-	vector<array<uint8_t, 6>> data;
+	vector<array<uint8_t, PC_IDENTIFIER_PROPRIETARY_DATA>> data;
 	FUNCTION_RETURN result = generate_ethernet_pc_id(data, use_ip);
 	vector<PcIdentifier> identifiers;
 	if (result == FUNC_RET_OK) {
@@ -86,14 +84,14 @@
 }
 
 LCC_EVENT_TYPE Ethernet::validate_identifier(const PcIdentifier &identifier) const {
-	vector<array<uint8_t, 6>> data;
+	vector<array<uint8_t, PC_IDENTIFIER_PROPRIETARY_DATA>> data;
 	FUNCTION_RETURN generate_ethernet = generate_ethernet_pc_id(data, use_ip);
 	LCC_EVENT_TYPE result = IDENTIFIERS_MISMATCH;
 	if (generate_ethernet == FUNC_RET_OK) {
-		// fixme
-		// result = validate_identifier(identifier, data);
+		result = validate_identifier(identifier, data);
 	}
 	return result;
 }
 
+}  // namespace pc_identifier
 } /* namespace license */
diff --git a/src/library/pc_identifier/ethernet.hpp b/src/library/pc_identifier/ethernet.hpp
index c35e9f6..f857ba4 100644
--- a/src/library/pc_identifier/ethernet.hpp
+++ b/src/library/pc_identifier/ethernet.hpp
@@ -11,20 +11,22 @@
 #include "identification_strategy.hpp"
 
 namespace license {
+namespace pc_identifier {
 
 class Ethernet : public IdentificationStrategy {
 private:
 	const bool use_ip;
-
 public:
 	Ethernet(bool use_ip);
 	virtual ~Ethernet();
 	virtual LCC_API_IDENTIFICATION_STRATEGY identification_strategy() const;
 	virtual FUNCTION_RETURN identify_pc(PcIdentifier &pc_id) const;
 	virtual std::vector<PcIdentifier> alternative_ids() const;
+	using IdentificationStrategy::validate_identifier;
 	virtual LCC_EVENT_TYPE validate_identifier(const PcIdentifier &identifier) const;
 };
 
+}  // namespace pc_identifier
 } /* namespace license */
 
 #endif /* SRC_LIBRARY_PC_IDENTIFIER_ETHERNET_HPP_ */
diff --git a/src/library/pc_identifier/identification_strategy.cpp b/src/library/pc_identifier/identification_strategy.cpp
index 1248b43..db9c107 100644
--- a/src/library/pc_identifier/identification_strategy.cpp
+++ b/src/library/pc_identifier/identification_strategy.cpp
@@ -1,10 +1,14 @@
 #include <array>
 #include "identification_strategy.hpp"
-
+#include "default_strategy.hpp"
+#include "ethernet.hpp"
+#include "disk_strategy.hpp"
 namespace license {
+namespace pc_identifier {
+
 using namespace std;
-LCC_EVENT_TYPE IdentificationStrategy::validate_identifier(const PcIdentifier& identifier,
-														   const vector<array<uint8_t, 6>>& available_ids) const {
+LCC_EVENT_TYPE IdentificationStrategy::validate_identifier(
+	const PcIdentifier& identifier, const vector<array<uint8_t, PC_IDENTIFIER_PROPRIETARY_DATA>>& available_ids) const {
 	LCC_EVENT_TYPE result = IDENTIFIERS_MISMATCH;
 
 	if (identifier.get_identification_strategy() == identification_strategy()) {
@@ -18,4 +22,29 @@
 	return result;
 }
 
+std::unique_ptr<IdentificationStrategy> IdentificationStrategy::get_strategy(LCC_API_IDENTIFICATION_STRATEGY strategy) {
+	unique_ptr<IdentificationStrategy> result;
+	switch (strategy) {
+		case STRATEGY_DEFAULT:
+			result = unique_ptr<IdentificationStrategy>(dynamic_cast<IdentificationStrategy*>(new DefaultStrategy()));
+			break;
+		case STRATEGY_ETHERNET:
+			result = unique_ptr<IdentificationStrategy>(dynamic_cast<IdentificationStrategy*>(new Ethernet(false)));
+			break;
+		case STRATEGY_IP_ADDRESS:
+			result = unique_ptr<IdentificationStrategy>(dynamic_cast<IdentificationStrategy*>(new Ethernet(true)));
+			break;
+		case STRATEGY_DISK_NUM:
+			result = unique_ptr<IdentificationStrategy>(dynamic_cast<IdentificationStrategy*>(new DiskStrategy(true)));
+			break;
+		case STRATEGY_DISK_LABEL:
+			result = unique_ptr<IdentificationStrategy>(dynamic_cast<IdentificationStrategy*>(new DiskStrategy(false)));
+			break;
+		default:
+			throw logic_error("strategy not supported");
+	}
+	return result;
+}
+}  // namespace pc_identifier
 }  // namespace license
+
diff --git a/src/library/pc_identifier/identification_strategy.hpp b/src/library/pc_identifier/identification_strategy.hpp
index 77ecb8f..8eef0c8 100644
--- a/src/library/pc_identifier/identification_strategy.hpp
+++ b/src/library/pc_identifier/identification_strategy.hpp
@@ -10,16 +10,17 @@
 
 #include <licensecc/datatypes.h>
 #include <licensecc_properties.h>
-
 #include <vector>
+#include <bits/unique_ptr.h>
 #include "../base/base.h"
 #include "pc_identifier.hpp"
 namespace license {
+namespace pc_identifier {
 
 class IdentificationStrategy {
 protected:
 	LCC_EVENT_TYPE validate_identifier(const PcIdentifier& identifier,
-									   const std::vector<std::array<uint8_t, 6>>& available_ids) const;
+									   const std::vector<std::array<uint8_t, 8>>& available_ids) const;
 
 public:
 	IdentificationStrategy(){};
@@ -27,9 +28,11 @@
 	virtual LCC_API_IDENTIFICATION_STRATEGY identification_strategy() const = 0;
 	virtual FUNCTION_RETURN identify_pc(PcIdentifier& identifier) const = 0;
 	virtual std::vector<PcIdentifier> alternative_ids() const = 0;
-	virtual LCC_EVENT_TYPE validate_identifier(const PcIdentifier &identifier) const = 0;
+	virtual LCC_EVENT_TYPE validate_identifier(const PcIdentifier& identifier) const = 0;
+	static std::unique_ptr<IdentificationStrategy> get_strategy(LCC_API_IDENTIFICATION_STRATEGY strategy);
 };
 
+}  // namespace pc_identifier
 } /* namespace license */
 
 #endif /* SRC_LIBRARY_PC_IDENTIFIER_IDENTIFICATION_STRATEGY_HPP_ */
diff --git a/src/library/pc_identifier/pc_identifier.cpp b/src/library/pc_identifier/pc_identifier.cpp
index e4e5860..9bf9ea0 100644
--- a/src/library/pc_identifier/pc_identifier.cpp
+++ b/src/library/pc_identifier/pc_identifier.cpp
@@ -10,12 +10,21 @@
 #include "../base/base64.h"
 
 namespace license {
+namespace pc_identifier {
+
 using namespace std;
 
 PcIdentifier::PcIdentifier() {}
 
 PcIdentifier::PcIdentifier(const std::string& param) {
-	// TODO Auto-generated constructor stub
+	string tmp_str(param);  // throw away const
+	std::replace(tmp_str.begin(), tmp_str.end(), '-', '\n');
+	vector<uint8_t> decoded = unbase64(tmp_str);
+	if (decoded.size() != PC_IDENTIFIER_PROPRIETARY_DATA + 1) {
+		cerr << decoded.size();
+		throw logic_error("wrong identifier size " + param);
+	}
+	std::copy_n(decoded.begin(), PC_IDENTIFIER_PROPRIETARY_DATA + 1, m_data.begin());
 }
 
 PcIdentifier::~PcIdentifier() {}
@@ -43,20 +52,39 @@
 	m_data[0] = (m_data[0] && ~0x30) | virt << 4;
 }
 
-void PcIdentifier::set_virtualization(VIRTUALIZATION_DETAIL virtualization_detail) {}
-
-void PcIdentifier::set_cloud_provider(CLOUD_PROVIDER cloud_provider) {}
-
-void PcIdentifier::set_data(const std::array<uint8_t, 6>& data) {}
-
-std::string PcIdentifier::print() const {
-	string result = base64(m_data.data(), m_data.size(), 4);
-	std::replace(result.begin(), result.end(), '\n', '-');
-	return result;
+void PcIdentifier::set_virtualization(VIRTUALIZATION_DETAIL virtualization_detail) {  // TODO
 }
 
-LCC_API_IDENTIFICATION_STRATEGY PcIdentifier::get_identification_strategy() const {}
+void PcIdentifier::set_cloud_provider(CLOUD_PROVIDER cloud_provider) {
+	// TODO
+}
 
-bool PcIdentifier::data_match(const std::array<uint8_t, 6>& data) const {}
+void PcIdentifier::set_data(const std::array<uint8_t, PC_IDENTIFIER_PROPRIETARY_DATA>& data) {
+	m_data[1] = (m_data[1] & (~0x1f)) | (data[0] & 0x1f);
+	for (int i = 1; i < PC_IDENTIFIER_PROPRIETARY_DATA; i++) {
+		m_data[i + 1] = data[i];
+	}
+}
+
+std::string PcIdentifier::print() const {
+	string result = base64(m_data.data(), m_data.size(), 5);
+	std::replace(result.begin(), result.end(), '\n', '-');
+	return result.substr(0, result.size() - 1);
+}
+
+LCC_API_IDENTIFICATION_STRATEGY PcIdentifier::get_identification_strategy() const {
+	uint8_t stratMov = m_data[1] >> 5;
+	return static_cast<LCC_API_IDENTIFICATION_STRATEGY>(stratMov);
+}
+
+bool PcIdentifier::data_match(const std::array<uint8_t, PC_IDENTIFIER_PROPRIETARY_DATA>& data) const {
+	bool equals = true;
+	for (int i = 0; i < PC_IDENTIFIER_PROPRIETARY_DATA && equals; i++) {
+		equals = (i == 0) ? ((data[i] & 0x1f) == (m_data[i + 1] & 0x1f)) : (data[i] == m_data[i + 1]);
+	}
+	return equals;
+}
+
+}  // namespace pc_identifier
 } /* namespace license */
 
diff --git a/src/library/pc_identifier/pc_identifier.hpp b/src/library/pc_identifier/pc_identifier.hpp
index 01856c3..d1aa699 100644
--- a/src/library/pc_identifier/pc_identifier.hpp
+++ b/src/library/pc_identifier/pc_identifier.hpp
@@ -17,11 +17,15 @@
 #include "../../../include/licensecc/datatypes.h"
 #include "../os/execution_environment.hpp"
 #include "../os/cpu_info.hpp"
+
 namespace license {
+namespace pc_identifier {
+
+#define PC_IDENTIFIER_PROPRIETARY_DATA 8
 
 /**
  * data[0]
- * bit 7 = 0 if pc id is being generated 1 if it is included in a license.
+ * bit 7 = 0 if pc id is being generated 1 if it is coming from an issued license.
  *
  * if bit 7 = 0
  * bit 6 = environment variable was used to generate pc_id
@@ -34,12 +38,12 @@
  * bit 6 = 1 enable magic file/registry key
  * ----
  * data[1] bit 7-6-5 define identification strategy.
- * data[1] bits 4-0 and data[1-5] are pc identifier proprietary strategy data.
+ * data[1] bits 4-0, data[2-8] are pc identifier proprietary strategy data.
  */
 
 class PcIdentifier {
 private:
-	std::array<uint8_t, 6> m_data = {};
+	std::array<uint8_t, PC_IDENTIFIER_PROPRIETARY_DATA + 1> m_data = {};
 
 public:
 	PcIdentifier();
@@ -52,8 +56,8 @@
 	void set_virtual_environment(VIRTUALIZATION virtualization);
 	void set_virtualization(VIRTUALIZATION_DETAIL virtualization_detail);
 	void set_cloud_provider(CLOUD_PROVIDER cloud_provider);
-	void set_data(const std::array<uint8_t, 6> &data);
-	bool data_match(const std::array<uint8_t, 6> &data) const;
+	void set_data(const std::array<uint8_t, PC_IDENTIFIER_PROPRIETARY_DATA> &data);
+	bool data_match(const std::array<uint8_t, PC_IDENTIFIER_PROPRIETARY_DATA> &data) const;
 	std::string print() const;
 	friend std::ostream &operator<<(std::ostream &output, const PcIdentifier &d) {
 		output << d.print();
@@ -61,6 +65,7 @@
 	};
 };
 
+}  // namespace pc_identifier
 } /* namespace license */
 
 #endif /* SRC_LIBRARY_PC_IDENTIFIER_PC_IDENTIFIER_HPP_ */
diff --git a/src/library/pc_identifier/pc_identifier_facade.cpp b/src/library/pc_identifier/pc_identifier_facade.cpp
index 1e0e93c..a9aa9b8 100644
--- a/src/library/pc_identifier/pc_identifier_facade.cpp
+++ b/src/library/pc_identifier/pc_identifier_facade.cpp
@@ -10,47 +10,34 @@
 #include <cstdlib>
 #include <stdexcept>
 
-#include "../../../projects/DEFAULT/include/licensecc/DEFAULT/licensecc_properties.h"
 #include "../base/base.h"
 #include "../base/logger.h"
 #include "../os/cpu_info.hpp"
 #include "../os/execution_environment.hpp"
-#include "default_strategy.hpp"
-#include "ethernet.hpp"
+#include "identification_strategy.hpp"
 #include "pc_identifier.hpp"
 
 namespace license {
+namespace pc_identifier {
+
 using namespace std;
-static std::unordered_map<LCC_API_IDENTIFICATION_STRATEGY, std::unique_ptr<IdentificationStrategy>> init() {
-	unordered_map<LCC_API_IDENTIFICATION_STRATEGY, std::unique_ptr<IdentificationStrategy>> strategy_map;
-	strategy_map[STRATEGY_DEFAULT] =
-		unique_ptr<IdentificationStrategy>(dynamic_cast<IdentificationStrategy*>(new DefaultStrategy()));
-	strategy_map[STRATEGY_ETHERNET] =
-		unique_ptr<IdentificationStrategy>(dynamic_cast<IdentificationStrategy*>(new Ethernet(false)));
-	strategy_map[STRATEGY_IP_ADDRESS] =
-		unique_ptr<IdentificationStrategy>(dynamic_cast<IdentificationStrategy*>(new Ethernet(true)));
-
-	return strategy_map;
-}
-
-std::unordered_map<LCC_API_IDENTIFICATION_STRATEGY, std::unique_ptr<IdentificationStrategy>>
-	PcIdentifierFacade::STRATEGY_MAP = init();
 
 LCC_EVENT_TYPE PcIdentifierFacade::validate_pc_signature(const std::string& str_code) {
 	PcIdentifier pc_id(str_code);
 	LCC_API_IDENTIFICATION_STRATEGY id_strategy = pc_id.get_identification_strategy();
-	auto it = STRATEGY_MAP.find(id_strategy);
 	LCC_EVENT_TYPE result = IDENTIFIERS_MISMATCH;
-	if (it != STRATEGY_MAP.end()) {
-		result = it->second->validate_identifier(pc_id);
-	} else {
-		// TODO: log
+	try {
+		unique_ptr<IdentificationStrategy> strategy = IdentificationStrategy::get_strategy(id_strategy);
+		result = strategy->validate_identifier(pc_id);
+	} catch (logic_error& e) {
+		LOG_ERROR("Error validating identifier %s: %s", str_code.c_str(), e.what());
 	}
 	return result;
 }
 
 std::string PcIdentifierFacade::generate_user_pc_signature(LCC_API_IDENTIFICATION_STRATEGY strategy) {
 	bool use_env_var = false;
+	vector<LCC_API_IDENTIFICATION_STRATEGY> strategies_to_try;
 	if (strategy == STRATEGY_DEFAULT) {
 		char* env_var_value = getenv(LCC_IDENTIFICATION_STRATEGY_ENV_VAR);
 		if (env_var_value != nullptr && env_var_value[0] != '\0') {
@@ -63,15 +50,12 @@
 			}
 		}
 	}
-	auto it = STRATEGY_MAP.find(strategy);
+
+	unique_ptr<IdentificationStrategy> strategy_ptr = IdentificationStrategy::get_strategy(strategy);
 	PcIdentifier pc_id;
-	if (it != STRATEGY_MAP.end()) {
-		FUNCTION_RETURN result = it->second->identify_pc(pc_id);
-		if (result != FUNC_RET_OK) {
-			/// FIXME
-		}
-	} else {
-		throw logic_error("Specified identification strategy invalid");
+	FUNCTION_RETURN result = strategy_ptr->identify_pc(pc_id);
+	if (result != FUNC_RET_OK) {
+		/// FIXME
 	}
 	ExecutionEnvironment exec;
 	VIRTUALIZATION virtualization = exec.getVirtualization();
@@ -88,4 +72,6 @@
 	}
 	return pc_id.print();
 }
+
+}  // namespace pc_identifier
 } /* namespace license */
diff --git a/src/library/pc_identifier/pc_identifier_facade.hpp b/src/library/pc_identifier/pc_identifier_facade.hpp
index 02b2d0e..5494fe1 100644
--- a/src/library/pc_identifier/pc_identifier_facade.hpp
+++ b/src/library/pc_identifier/pc_identifier_facade.hpp
@@ -15,16 +15,18 @@
 #include "identification_strategy.hpp"
 
 namespace license {
+namespace pc_identifier {
+
 class PcIdentifierFacade {
 private:
 	PcIdentifierFacade(){};
 	virtual ~PcIdentifierFacade(){};
 public:
-	static std::unordered_map<LCC_API_IDENTIFICATION_STRATEGY, std::unique_ptr<IdentificationStrategy>> STRATEGY_MAP;
 	static LCC_EVENT_TYPE validate_pc_signature(const std::string& str_code);
 	static std::string generate_user_pc_signature(LCC_API_IDENTIFICATION_STRATEGY strategy);
 };
 
+}  // namespace pc_identifier
 } /* namespace license */
 
 #endif /* SRC_LIBRARY_PC_IDENTIFIER_PC_IDENTIFIER_FACADE_HPP_ */
diff --git a/test/functional/CMakeLists.txt b/test/functional/CMakeLists.txt
index 71cf989..a72ac30 100644
--- a/test/functional/CMakeLists.txt
+++ b/test/functional/CMakeLists.txt
@@ -46,9 +46,9 @@
 )
 
 
-add_executable(test_volid volid_test.cpp)
+add_executable(test_it_pc_identifer pc_identifier_it_test.cpp)
 
-target_link_libraries( test_volid
+target_link_libraries(test_it_pc_identifer
  licensecc_static
  license_generator_snippet
  Boost::unit_test_framework 
@@ -68,8 +68,8 @@
 
 ADD_TEST(NAME test_crack COMMAND test_crack WORKING_DIRECTORY ${CMAKE_BINARY_DIR})
 ADD_TEST(NAME test_date COMMAND test_date WORKING_DIRECTORY ${CMAKE_BINARY_DIR})
+ADD_TEST(NAME test_it_pc_identifer COMMAND test_it_pc_identifer WORKING_DIRECTORY ${CMAKE_BINARY_DIR})
 ADD_TEST(NAME test_standard_license COMMAND test_standard_license WORKING_DIRECTORY ${CMAKE_BINARY_DIR})
 ADD_TEST(NAME test_signature_verifier COMMAND test_signature_verifier WORKING_DIRECTORY ${CMAKE_BINARY_DIR})
-ADD_TEST(NAME test_volid COMMAND test_volid WORKING_DIRECTORY ${CMAKE_BINARY_DIR})
 
 
diff --git a/test/functional/pc_identifier_it_test.cpp b/test/functional/pc_identifier_it_test.cpp
new file mode 100644
index 0000000..ebafc0d
--- /dev/null
+++ b/test/functional/pc_identifier_it_test.cpp
@@ -0,0 +1,95 @@
+#define BOOST_TEST_MODULE integration_test_pc_identifier
+
+#include <boost/test/unit_test.hpp>
+#include <fstream>
+#include <iostream>
+#include <stdio.h>
+#include <cstring>
+#include <boost/filesystem.hpp>
+#include <licensecc_properties.h>
+#include <licensecc_properties_test.h>
+
+#include <licensecc/licensecc.h>
+#include "../../src/library/ini/SimpleIni.h"
+#include "../../src/library/pc_identifier/pc_identifier_facade.hpp"
+#include "../../src/library/os/os.h"
+#include "../../src/library/os/network.hpp"
+#include "generate-license.h"
+
+
+namespace license {
+namespace test {
+namespace fs = boost::filesystem;
+using namespace std;
+using namespace pc_identifier;
+
+/**
+ * If the current pc has at least one disk generate a pc identifier using disk, generate a license, verify the license
+ * is OK
+ */
+
+static void generate_and_verify_license(LCC_API_IDENTIFICATION_STRATEGY strategy, const string& lic_fname) {
+	BOOST_TEST_CHECKPOINT("Before generate");
+	const string identifier_out = PcIdentifierFacade::generate_user_pc_signature(strategy);
+	BOOST_TEST_CHECKPOINT("After generate signature");
+	cout << "Identifier:" << identifier_out << endl;
+	vector<string> extraArgs;
+	extraArgs.push_back("-s");
+	extraArgs.push_back(identifier_out);
+	BOOST_TEST_CHECKPOINT("Before generate license");
+	const string licLocation = generate_license(lic_fname, extraArgs);
+	LicenseInfo license;
+	LicenseLocation location = {LICENSE_PATH};
+	std::copy(licLocation.begin(), licLocation.end(), location.licenseData);
+	const LCC_EVENT_TYPE result = acquire_license(nullptr, &location, &license);
+	BOOST_CHECK_EQUAL(result, LICENSE_OK);
+	BOOST_CHECK_EQUAL(license.has_expiry, false);
+	BOOST_CHECK_EQUAL(license.linked_to_pc, true);
+}
+
+BOOST_AUTO_TEST_CASE(volid_lic_file) {
+	PcIdentifier identifier_out;
+	size_t disk_num;
+	FUNCTION_RETURN result_diskinfos = getDiskInfos(nullptr, &disk_num);
+	if ((result_diskinfos == FUNC_RET_BUFFER_TOO_SMALL || result_diskinfos == FUNC_RET_OK) && disk_num > 0) {
+		generate_and_verify_license(LCC_API_IDENTIFICATION_STRATEGY::STRATEGY_DISK_NUM, "volid_lic_file");
+	} else {
+		BOOST_TEST_MESSAGE("No disk found skipping testing disk pc identifier");
+	}
+}
+
+BOOST_AUTO_TEST_CASE(volume_name_lic_file) {
+	PcIdentifier identifier_out;
+	size_t disk_num;
+	FUNCTION_RETURN result_diskinfos = getDiskInfos(nullptr, &disk_num);
+	if ((result_diskinfos == FUNC_RET_BUFFER_TOO_SMALL || result_diskinfos == FUNC_RET_OK) && disk_num > 0) {
+		generate_and_verify_license(LCC_API_IDENTIFICATION_STRATEGY::STRATEGY_DISK_LABEL, "volume_name_lic_file");
+	} else {
+		BOOST_TEST_MESSAGE("No disk found skipping testing volume name disk pc identifier");
+	}
+}
+
+BOOST_AUTO_TEST_CASE(strategy_mac_address) {
+	vector<os::OsAdapterInfo> adapters;
+	FUNCTION_RETURN result_adapterInfos = os::getAdapterInfos(adapters);
+	if ((result_adapterInfos == FUNC_RET_BUFFER_TOO_SMALL || result_adapterInfos == FUNC_RET_OK) &&
+		adapters.size() > 0) {
+		generate_and_verify_license(LCC_API_IDENTIFICATION_STRATEGY::STRATEGY_ETHERNET, "strategy_mac_address");
+	} else {
+		BOOST_TEST_MESSAGE("No ethernet adapter found skipping testing mac address pc identifier");
+	}
+}
+/*
+BOOST_AUTO_TEST_CASE(strategy_ip_address) {
+	vector<os::OsAdapterInfo> adapters;
+	FUNCTION_RETURN result_adapterInfos = os::getAdapterInfos(adapters);
+	if ((result_adapterInfos == FUNC_RET_BUFFER_TOO_SMALL || result_adapterInfos == FUNC_RET_OK) &&
+		adapters.size() > 0) {
+		generate_and_verify_license(LCC_API_IDENTIFICATION_STRATEGY::STRATEGY_IP_ADDRESS, "strategy_ip_address");
+	} else {
+		BOOST_TEST_MESSAGE("No ethernet adapter found skipping testing ip pc identifier");
+	}
+}
+*/
+}  // namespace test
+}  // namespace license
diff --git a/test/functional/signature_verifier_test.cpp b/test/functional/signature_verifier_test.cpp
index 709f7fc..631b47d 100644
--- a/test/functional/signature_verifier_test.cpp
+++ b/test/functional/signature_verifier_test.cpp
@@ -1,3 +1,4 @@
+
 /*
  * LicenseVerifier_test.cpp
  *
@@ -10,7 +11,7 @@
 #include <licensecc_properties_test.h>
 #include <licensecc_properties.h>
 
-#include "../../src/library/os/signature_verifier.h"
+#include "../../src/library/os/signature_verifier.hpp"
 #include "generate-license.h"
 
 namespace license {
@@ -21,7 +22,7 @@
 	const string test_data("test_data");
 	const string signature = sign_data(test_data, string("verify_signature"));
 
-	FUNCTION_RETURN result = license::verify_signature(test_data, signature);
+	FUNCTION_RETURN result = license::os::verify_signature(test_data, signature);
 	BOOST_CHECK_MESSAGE(result == FUNC_RET_OK, "signature verified");
 }
 
@@ -29,7 +30,7 @@
 	const string test_data("test_data");
 	const string signature = sign_data(test_data, string("verify_signature"));
 
-	FUNCTION_RETURN result = license::verify_signature(string("other data"), signature);
+	FUNCTION_RETURN result = license::os::verify_signature(string("other data"), signature);
 	BOOST_CHECK_MESSAGE(result == FUNC_RET_ERROR, "signature NOT verified");
 }
 
@@ -37,7 +38,7 @@
 	const string test_data("test_data");
 	string signature = sign_data(test_data, string("verify_signature"));
 	signature[2] = signature[2] + 1;
-	FUNCTION_RETURN result = license::verify_signature(test_data, signature);
+	FUNCTION_RETURN result = license::os::verify_signature(test_data, signature);
 	BOOST_CHECK_MESSAGE(result == FUNC_RET_ERROR, "signature NOT verified");
 }
 
diff --git a/test/library/CMakeLists.txt b/test/library/CMakeLists.txt
index 056ed89..467ce24 100644
--- a/test/library/CMakeLists.txt
+++ b/test/library/CMakeLists.txt
@@ -59,3 +59,6 @@
 ADD_TEST(NAME test_license_reader COMMAND test_license_reader)
 ADD_TEST(NAME test_license_locator COMMAND test_license_locator)
 ADD_TEST(NAME test_event_registry COMMAND test_event_registry)
+
+ADD_SUBDIRECTORY(os)
+ADD_SUBDIRECTORY(pc_identifier)
\ No newline at end of file
diff --git a/test/library/Os_Linux_test.cpp b/test/library/Os_Linux_test.cpp
index 6d272bf..21e94e0 100644
--- a/test/library/Os_Linux_test.cpp
+++ b/test/library/Os_Linux_test.cpp
@@ -38,33 +38,6 @@
 	}
 }
 
-BOOST_AUTO_TEST_CASE(read_network_adapters) {
-	OsAdapterInfo *adapter_info = NULL;
-	size_t adapter_info_size = 0;
-	FUNCTION_RETURN result = getAdapterInfos(NULL, &adapter_info_size);
-	BOOST_CHECK_EQUAL(result, FUNC_RET_OK);
-	BOOST_CHECK_GT(adapter_info_size, 0);
-	adapter_info = (OsAdapterInfo *)malloc(sizeof(OsAdapterInfo) * adapter_info_size);
-	result = getAdapterInfos(adapter_info, &adapter_info_size);
-	BOOST_CHECK_EQUAL(result, FUNC_RET_OK);
-	for (size_t i = 0; i < adapter_info_size; i++) {
-		cout << "Interface found: " << string(adapter_info[i].description) << endl;
-		BOOST_CHECK_GT(strlen(adapter_info[i].description), 0);
-		// lo mac address is always 0 but it has ip
-		// other interfaces may not be connected
-		if (string(adapter_info[i].description) == "lo") {
-			BOOST_CHECK_NE(adapter_info[i].ipv4_address[0], 0);
-		} else {
-			bool mac_is_0 = true;
-			for (int j = 0; j < 6; j++) {
-				mac_is_0 = mac_is_0 && (adapter_info[i].mac_address[j] == 0);
-			}
-			BOOST_CHECK_MESSAGE(!mac_is_0, "Mac address for interface " << adapter_info[i].description << " is 0");
-		}
-	}
-	free(adapter_info);
-}
-
 // To test if virtualization is detected correctly define an env variable VIRT_ENV
 // otherwise the test is skipped
 BOOST_AUTO_TEST_CASE(test_virtualization) {
diff --git a/test/library/os/CMakeLists.txt b/test/library/os/CMakeLists.txt
new file mode 100644
index 0000000..2cda53e
--- /dev/null
+++ b/test/library/os/CMakeLists.txt
@@ -0,0 +1,12 @@
+add_executable( test_network
+ network_test.cpp
+)
+
+target_link_libraries( test_network
+ licensecc_static
+ Boost::unit_test_framework 
+ Boost::filesystem
+ Boost::system
+)
+
+ADD_TEST(NAME test_network COMMAND test_network)
\ No newline at end of file
diff --git a/test/library/os/network_test.cpp b/test/library/os/network_test.cpp
new file mode 100644
index 0000000..b917914
--- /dev/null
+++ b/test/library/os/network_test.cpp
@@ -0,0 +1,50 @@
+#define BOOST_TEST_MODULE network_test
+#include <string>
+#include <iostream>
+#include <boost/test/unit_test.hpp>
+
+#include <licensecc_properties.h>
+#include <licensecc_properties_test.h>
+#include "../../src/library/base/StringUtils.h"
+#include "../../src/library/os/network.hpp"
+#include "../../src/library/os/execution_environment.hpp"
+
+namespace license {
+namespace os {
+namespace test {
+
+using namespace license::os;
+using namespace std;
+
+BOOST_AUTO_TEST_CASE(read_network_adapters) {
+	std::vector<license::os::OsAdapterInfo> adapters;
+	// we can suppose every test environment  other than docker has at least one network interface (it's hard to
+	// download this source code)
+	FUNCTION_RETURN result = getAdapterInfos(adapters);
+	ExecutionEnvironment exec_env;
+	if (result != FUNC_RET_OK && exec_env.is_docker()) {
+		BOOST_TEST_INFO("detected docker environment, not having network interfaces is normal here");
+		return;
+	}
+	BOOST_CHECK_EQUAL(result, FUNC_RET_OK);
+	for (auto& it : adapters) {
+		cout << "Interface found: " << string(it.description) << endl;
+		BOOST_CHECK_GT(strlen(it.description), 0);
+		// lo mac address is always 0 but it has ip
+		// other interfaces may not be connected
+		if (string(it.description) == "lo") {
+			BOOST_FAIL("loopback adapters shouldn't appear");
+		} else {
+			// check mac address are not all zero
+			bool mac_is_0 = true;
+			for (int j = 0; j < 6; j++) {
+				mac_is_0 = mac_is_0 || (it.mac_address[j] != 0);
+			}
+			BOOST_CHECK_MESSAGE(mac_is_0, "Mac address for interface " << it.description << " is 0");
+		}
+	}
+}
+
+}  // namespace test
+}  // namespace os
+}  // namespace license
diff --git a/test/library/pc_identifier/CMakeLists.txt b/test/library/pc_identifier/CMakeLists.txt
new file mode 100644
index 0000000..82b27e8
--- /dev/null
+++ b/test/library/pc_identifier/CMakeLists.txt
@@ -0,0 +1,12 @@
+add_executable( test_pc_identifier
+ pc_identifier_test.cpp
+)
+
+target_link_libraries( test_pc_identifier
+ licensecc_static
+ Boost::unit_test_framework 
+ Boost::filesystem
+ Boost::system
+)
+
+ADD_TEST(NAME test_pc_identifier COMMAND test_pc_identifier)
diff --git a/test/library/pc_identifier/disk_strategy_test.cpp b/test/library/pc_identifier/disk_strategy_test.cpp
new file mode 100644
index 0000000..8cba3cf
--- /dev/null
+++ b/test/library/pc_identifier/disk_strategy_test.cpp
@@ -0,0 +1,10 @@
+/*
+ * default_strategy_test.cpp
+ *
+ *  Created on: Jan 2, 2020
+ *      Author: devel
+ */
+
+#include "default_strategy.hpp"
+
+namespace license {} /* namespace license */
diff --git a/src/library/pc_identifier/ethernet_test.cpp b/test/library/pc_identifier/ethernet_test.cpp
similarity index 100%
rename from src/library/pc_identifier/ethernet_test.cpp
rename to test/library/pc_identifier/ethernet_test.cpp
diff --git a/test/functional/volid_test.cpp b/test/library/pc_identifier/pc_identifier_facade_test.cpp
similarity index 66%
rename from test/functional/volid_test.cpp
rename to test/library/pc_identifier/pc_identifier_facade_test.cpp
index 14144df..45d4a88 100644
--- a/test/functional/volid_test.cpp
+++ b/test/library/pc_identifier/pc_identifier_facade_test.cpp
@@ -1,51 +1,19 @@
-#define BOOST_TEST_MODULE test_volid
+/*
+ * pc_identifier_facade_test.cpp
+ *
+ *  Created on: Dec 26, 2019
+ *      Author: devel
+ */
 
-#include <boost/test/unit_test.hpp>
-#include <fstream>
-#include <iostream>
-#include <stdio.h>
-#include <cstring>
-#include <boost/filesystem.hpp>
-#include <licensecc_properties.h>
-#include <licensecc_properties_test.h>
-
-#include <licensecc/licensecc.h>
-#include "../../src/library/ini/SimpleIni.h"
-#include "../../src/library/pc-identifiers.h"
-#include "../../src/library/os/os.h"
-#include "generate-license.h"
-
-namespace fs = boost::filesystem;
-using namespace license;
-using namespace std;
+#include "pc_identifier_facade.hpp"
 
 namespace license {
-namespace test {
-
-BOOST_AUTO_TEST_CASE(default_volid_lic_file) {
-	PcSignature identifier_out;
-
-	const LCC_API_IDENTIFICATION_STRATEGY strategy = LCC_API_IDENTIFICATION_STRATEGY::STRATEGY_ETHERNET;
-	BOOST_TEST_CHECKPOINT("Before generate");
-	const FUNCTION_RETURN generate_ok = generate_user_pc_signature(identifier_out, strategy);
-	BOOST_TEST_CHECKPOINT("After generate signature");
-	BOOST_ASSERT(generate_ok == FUNCTION_RETURN::FUNC_RET_OK);
-	cout << "Identifier:" << identifier_out << endl;
-	vector<string> extraArgs;
-	extraArgs.push_back("-s");
-	extraArgs.push_back(identifier_out);
-	BOOST_TEST_CHECKPOINT("Before generate license");
-	const string licLocation = generate_license("volid_license", extraArgs);
-
-	LicenseInfo license;
-	LicenseLocation location = {LICENSE_PATH};
-	std::copy(licLocation.begin(), licLocation.end(), location.licenseData);
-	const LCC_EVENT_TYPE result = acquire_license(nullptr, &location, &license);
-	BOOST_CHECK_EQUAL(result, LICENSE_OK);
-	BOOST_CHECK_EQUAL(license.has_expiry, false);
-	BOOST_CHECK_EQUAL(license.linked_to_pc, true);
-}
-
+/*
+ * Test identifier stability:
+ * 1) generate the pc-identifier
+ * 2) save it to disk
+ * 3) every time check that the identifier can still be verified.
+ */
 static void generate_reference_file(const string &idfileLocation, LCC_API_IDENTIFICATION_STRATEGY strategies[],
 									int num_strategies) {
 	ofstream idfile(idfileLocation);
@@ -129,5 +97,4 @@
 	}
 }
 
-}  // namespace test
-}  // namespace license
+} /* namespace license */
diff --git a/test/library/pc_identifier/pc_identifier_test.cpp b/test/library/pc_identifier/pc_identifier_test.cpp
new file mode 100644
index 0000000..82fc503
--- /dev/null
+++ b/test/library/pc_identifier/pc_identifier_test.cpp
@@ -0,0 +1,65 @@
+/*
+ * Test on class PcIdentifier
+ *
+ *  Created on: Dec 26, 2019
+ *      Author: devel
+ */
+
+#define BOOST_TEST_MODULE test_pc_identifier
+
+#include <boost/test/unit_test.hpp>
+#include <fstream>
+#include <iostream>
+#include <stdio.h>
+#include <cstring>
+#include <boost/filesystem.hpp>
+#include <licensecc_properties.h>
+#include <licensecc_properties_test.h>
+
+#include <licensecc/licensecc.h>
+#include "../../../src/library/pc_identifier/pc_identifier.hpp"
+
+namespace license {
+namespace test {
+using namespace std;
+using namespace license::pc_identifier;
+
+/**
+ * Test get and set and compare pc identifier data
+ */
+BOOST_AUTO_TEST_CASE(set_and_compare_data) {
+	array<uint8_t, PC_IDENTIFIER_PROPRIETARY_DATA> data = {0xFF, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42};
+	PcIdentifier pc_id;
+	pc_id.set_data(data);
+	data[0] = data[0] & 0x1f;
+	BOOST_CHECK_MESSAGE(pc_id.data_match(data), "Data match");
+}
+/**
+ * Test get and set and compare pc identifier data
+ */
+BOOST_AUTO_TEST_CASE(compare_wrong_data) {
+	array<uint8_t, PC_IDENTIFIER_PROPRIETARY_DATA> data = {0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42};
+	PcIdentifier pc_id;
+	pc_id.set_data(data);
+	data[4] = 0;
+	BOOST_CHECK_MESSAGE(!pc_id.data_match(data), "Data shouldn't match");
+}
+
+/**
+ * Print a pc identifier and read it from the same string, check the data matches
+ */
+BOOST_AUTO_TEST_CASE(print_and_read) {
+	array<uint8_t, PC_IDENTIFIER_PROPRIETARY_DATA> data = {0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42};
+	PcIdentifier pc_id;
+	pc_id.set_data(data);
+	pc_id.set_identification_strategy(LCC_API_IDENTIFICATION_STRATEGY::STRATEGY_ETHERNET);
+	string pc_id_str = pc_id.print();
+	cout << pc_id_str << endl;
+	const PcIdentifier id2(pc_id_str);
+	BOOST_CHECK_MESSAGE(id2.get_identification_strategy() == LCC_API_IDENTIFICATION_STRATEGY::STRATEGY_ETHERNET,
+						"Strategy decoded correctly");
+	BOOST_CHECK_MESSAGE(id2.data_match(data), "Data deserialized correctly");
+}
+
+}  // namespace test
+}  // namespace license
diff --git a/test/library/pc_identifier_facade_test.cpp b/test/library/pc_identifier_facade_test.cpp
deleted file mode 100644
index 2571bc0..0000000
--- a/test/library/pc_identifier_facade_test.cpp
+++ /dev/null
@@ -1,10 +0,0 @@
-/*
- * pc_identifier_facade_test.cpp
- *
- *  Created on: Dec 26, 2019
- *      Author: devel
- */
-
-#include "pc_identifier_facade.hpp"
-
-namespace license {} /* namespace license */
diff --git a/test/library/pc_identifier_test.cpp b/test/library/pc_identifier_test.cpp
deleted file mode 100644
index 108961a..0000000
--- a/test/library/pc_identifier_test.cpp
+++ /dev/null
@@ -1,10 +0,0 @@
-/*
- * pc_identifier_test.cpp
- *
- *  Created on: Dec 26, 2019
- *      Author: devel
- */
-
-#include "../../src/library/pc_identifier/pc_identifier.hpp"
-
-namespace license {} /* namespace license */

--
Gitblit v1.9.1