From 1d1082fe695366da3498f528b953203a90fe7385 Mon Sep 17 00:00:00 2001
From: Gabriele Contini <contini.mailing@gmail.com>
Date: 周六, 01 2月 2020 02:48:51 +0800
Subject: [PATCH] rename enums and further developments

---
 src/library/locate/ExternalDefinition.cpp             |    4 
 src/library/os/linux/execution_environment.cpp        |   54 ++
 src/library/pc_identifier/ethernet_test.cpp           |   10 
 src/library/pc_identifier/disk_strategy.cpp           |   94 +++++
 src/library/pc_identifier/default_strategy.hpp        |    7 
 src/library/limits/license_verifier.cpp               |    6 
 src/library/pc_identifier/disk_strategy.hpp           |   30 +
 src/library/locate/EnvironmentVarData.cpp             |   12 
 src/inspector/inspector.cpp                           |   12 
 src/library/pc_identifier/identification_strategy.cpp |   21 +
 src/library/os/CMakeLists.txt                         |    7 
 src/library/pc_identifier/disk_strategy_test.cpp      |   10 
 src/library/pc_identifier/identification_strategy.hpp |   13 
 src/library/pc_identifier/ethernet.hpp                |   30 +
 src/library/base/EventRegistry.h                      |    4 
 src/library/os/cpu_info.hpp                           |    8 
 src/library/os/execution_environment.hpp              |    4 
 src/library/os/cpu_info_common.cpp                    |   42 ++
 test/functional/standard-license_test.cpp             |    4 
 src/library/pc_identifier/pc_identifier.cpp           |    8 
 src/library/locate/ApplicationFolder.cpp              |    2 
 src/library/pc_identifier/pc-identifiers.h            |    9 
 src/library/pc_identifier/ethernet.cpp                |   99 +++++
 src/library/pc_identifier/pc_identifier.hpp           |    8 
 src/templates/licensecc_properties.h.in               |   67 +++
 src/library/CMakeLists.txt                            |    1 
 src/library/pc_identifier/pc_identifier_facade.cpp    |   79 ++++
 test/library/LicenseLocator_test.cpp                  |   12 
 src/library/pc_identifier/pc-identifiers.c            |  101 -----
 test/functional/date_test.cpp                         |    4 
 src/library/pc_identifier/pc_identifier_facade.hpp    |    9 
 src/library/base/EventRegistry.cpp                    |    6 
 test/library/LicenseReader_test.cpp                   |    6 
 test/functional/volid_test.cpp                        |   10 
 README.md                                             |    4 
 src/library/locate/EnvironmentVarLocation.cpp         |    6 
 doc/open-license-manager.vsdx                         |    0 
 src/library/licensecc.cpp                             |   39 +
 src/library/pc_identifier/default_strategy.cpp        |   75 +++
 include/licensecc/datatypes.h                         |   64 +--
 src/library/os/linux/cpu_info.cpp                     |   12 
 src/library/pc_identifier/CMakeLists.txt              |    4 
 test/functional/crack_test.cpp                        |    2 
 include/licensecc/licensecc.h                         |   16 
 44 files changed, 734 insertions(+), 281 deletions(-)

diff --git a/README.md b/README.md
index e55936b..5408207 100644
--- a/README.md
+++ b/README.md
@@ -10,7 +10,7 @@
 [![codecov](https://codecov.io/gh/open-license-manager/open-license-manager/branch/develop/graph/badge.svg)](https://codecov.io/gh/open-license-manager/open-license-manager)
 [![Github Issues](https://img.shields.io/github/issues/open-license-manager/open-license-manager)](http://github.com/open-license-manager/open-license-manager/issues)
 
-It allows to protect the software you develop from unauthorized copies, limit the usage in time, to a specific set of 
+Protect the software you develop from unauthorized copies, limit the usage in time, to a specific set of 
 machines, or prevent the usage in  virtualized environments. It is an Open License Manager that helps to keep your 
 software closed :smirk: . Among other features if it runs on a "real hardware" it can generate a signature of that hardware and report if the signature doesn't match.
 
@@ -91,5 +91,5 @@
 
 ## How to contribute
 
-The project is not dead but we take our time to answer. The best interaction you can have with us is through the issue system. Have a look to the [contribution guidelines](CONTRIBUTING.md)
+The best interaction you can have with us is through the issue system. Have a look to the [contribution guidelines](CONTRIBUTING.md)
 We use [GitFlow](https://datasift.github.io/gitflow/IntroducingGitFlow.html) (or at least a subset of it). Remember to install the gitflow git plugin and use `develop` as default branch for your pull requests. 
diff --git a/doc/open-license-manager.vsdx b/doc/open-license-manager.vsdx
new file mode 100644
index 0000000..fd83390
--- /dev/null
+++ b/doc/open-license-manager.vsdx
Binary files differ
diff --git a/include/licensecc/datatypes.h b/include/licensecc/datatypes.h
index 3355876..0c9ea48 100644
--- a/include/licensecc/datatypes.h
+++ b/include/licensecc/datatypes.h
@@ -22,17 +22,7 @@
 #define DllExport __declspec(dllexport)
 #endif
 
-#define API_LICENSE_DATA_LENGTH 1024 * 4
-
-// define api structure sizes
-#define API_PC_IDENTIFIER_SIZE 19
-#define API_PROPRIETARY_DATA_SIZE 16
-#define API_AUDIT_EVENT_NUM 5
-#define API_AUDIT_EVENT_PARAM2 255
-#define API_VERSION_LENGTH 15
-#define API_PROJECT_NAME_SIZE 15
-#define API_EXPIRY_DATE_SIZE 10
-#define API_ERROR_BUFFER_SIZE 256
+#include <licensecc_properties.h>
 
 typedef enum {
 	LICENSE_OK = 0,  // OK
@@ -42,31 +32,31 @@
 	FILE_FORMAT_NOT_RECOGNIZED = 4,  // license file has invalid format (not .ini file)
 	LICENSE_MALFORMED = 5,  // some mandatory field are missing, or data can't be fully read.
 	PRODUCT_NOT_LICENSED = 6,  // this product was not licensed
-	PRODUCT_EXPIRED = 7,
+	PRODUCT_EXPIRED = 7,    //!< PRODUCT_EXPIRED
 	LICENSE_CORRUPTED = 8,  // License signature didn't match with current license
 	IDENTIFIERS_MISMATCH = 9,  // Calculated identifier and the one provided in license didn't match
 
 	LICENSE_SPECIFIED = 100,  // license location was specified
 	LICENSE_FOUND = 101,  // License file has been found or license data has been located
 	PRODUCT_FOUND = 102,  // License has been loaded and the declared product has been found
-	SIGNATURE_VERIFIED = 103
-} EVENT_TYPE;
+	SIGNATURE_VERIFIED = 103//!< SIGNATURE_VERIFIED
+} LCC_EVENT_TYPE;
 
 typedef enum {
-	LOCAL,
-	REMOTE  // remote licenses are not supported now.
-} LICENSE_TYPE;
+	LCC_LOCAL,
+	LCC_REMOTE  // remote licenses are not supported now.
+} LCC_LICENSE_TYPE;
 
-typedef enum { SVRT_INFO, SVRT_WARN, SVRT_ERROR } SEVERITY;
+typedef enum { SVRT_INFO, SVRT_WARN, SVRT_ERROR } LCC_SEVERITY;
 
 typedef struct {
-	SEVERITY severity;
-	EVENT_TYPE event_type;
+	LCC_SEVERITY severity;
+	LCC_EVENT_TYPE event_type;
 	/**
 	 * License file name or location where the license is stored.
 	 */
 	char license_reference[MAX_PATH];
-	char param2[API_AUDIT_EVENT_PARAM2 + 1];
+	char param2[LCC_API_AUDIT_EVENT_PARAM2 + 1];
 } AuditEvent;
 
 typedef enum {
@@ -83,7 +73,7 @@
 	 * The license is encoded
 	 */
 	LICENSE_ENCODED
-} LICENSE_DATA_TYPE;
+} LCC_LICENSE_DATA_TYPE;
 
 /**
  * This structure contains informations on the raw license data. Software authors
@@ -93,16 +83,16 @@
  * license file location on its own.
  */
 typedef struct {
-	LICENSE_DATA_TYPE license_data_type;
-	char licenseData[API_LICENSE_DATA_LENGTH];
+	LCC_LICENSE_DATA_TYPE license_data_type;
+	char licenseData[LCC_API_MAX_LICENSE_DATA_LENGTH];
 } LicenseLocation;
 
 /**
  * Informations on the software requiring the license
  */
 typedef struct {
-	char version[API_VERSION_LENGTH + 1];  // software version in format xxxx[.xxxx.xxxx] //TODO
-	char project_name[API_PROJECT_NAME_SIZE + 1];  // name of the project (must correspond to the name in the license)
+	char version[LCC_API_VERSION_LENGTH + 1];  // software version in format xxxx[.xxxx.xxxx] //TODO
+	char project_name[LCC_API_PROJECT_NAME_SIZE + 1];  // name of the project (must correspond to the name in the license)
 	/**
 	 * this number passed in by the application must correspond to the magic number used when compiling the library.
 	 * See cmake parameter -DLCC_PROJECT_MAGIC_NUM and licensecc_properties.h macro VERIFY_MAGIC
@@ -116,36 +106,22 @@
 	 * multiple (for instance, license expired and signature not verified).
 	 * Only the last AUDIT_EVENT_NUM are reported.
 	 */
-	AuditEvent status[API_AUDIT_EVENT_NUM];
+	AuditEvent status[LCC_API_AUDIT_EVENT_NUM];
 	/**
 	 * Eventual expiration date of the software,
 	 * can be '\0' if the software don't expire
 	 * */
-	char expiry_date[API_EXPIRY_DATE_SIZE + 1];
+	char expiry_date[LCC_API_EXPIRY_DATE_SIZE + 1];
 	unsigned int days_left;
 	bool has_expiry;
 	bool linked_to_pc;
-	LICENSE_TYPE license_type;  // Local or Remote
+	LCC_LICENSE_TYPE license_type;  // Local or Remote
 	/* A string of character inserted into the license understood
 	 * by the calling application.
 	 * '\0' if the application didn't specify one */
-	char proprietary_data[API_PROPRIETARY_DATA_SIZE + 1];
+	char proprietary_data[LCC_API_PROPRIETARY_DATA_SIZE + 1];
 	int license_version;  // license file version
 } LicenseInfo;
-
-/**
- * Enum to select a specific pc identification_strategy. DEFAULT Should be used
- * in most cases.
- */
-typedef enum {
-	STRATEGY_DEFAULT = -1,
-	STRATEGY_ETHERNET = 0,
-	STRATEGY_IP_ADDRESS = 1,
-	STRATEGY_DISK_NUM = 1,
-	STRATEGY_DISK_LABEL = 2,
-	STRATEGY_PLATFORM_SPECIFIC = 3,
-	STRATEGY_UNKNOWN = -2
-} IDENTIFICATION_STRATEGY;
 
 #ifdef __cplusplus
 }
diff --git a/include/licensecc/licensecc.h b/include/licensecc/licensecc.h
index 9397613..9488e75 100644
--- a/include/licensecc/licensecc.h
+++ b/include/licensecc/licensecc.h
@@ -8,20 +8,22 @@
 extern "C" {
 #endif
 
+#include <licensecc_properties.h>
+
 #include "datatypes.h"
 
-/*
+/**
  * Method used to convert the LicenseInfo into a human readable
- * representation. //not yet implemented
+ * representation.
  */
-void print_error(char out_buffer[API_ERROR_BUFFER_SIZE], LicenseInfo* licenseInfo);
+void print_error(char out_buffer[LCC_API_ERROR_BUFFER_SIZE], LicenseInfo* licenseInfo);
 
 /**
  * This method calculates the pc identifier. The string need to be shown to the user and given back to the software
  * editor when issuing a license.
  *  pc_id_method = STRATEGY_DEFAULT usually works.
  */
-bool identify_pc(IDENTIFICATION_STRATEGY pc_id_method, char* identifier_out, size_t* bufSize);
+bool identify_pc(LCC_API_IDENTIFICATION_STRATEGY pc_id_method, char* identifier_out, size_t* bufSize);
 
 /**
  * This method is used to request the use of one license for a product.
@@ -36,7 +38,7 @@
  * @param license[out] optional, can be NULL, if set it will return extra informations about the license.
  */
 
-EVENT_TYPE acquire_license(const CallerInformations* callerInformation, const LicenseLocation* licenseLocation,
+LCC_EVENT_TYPE acquire_license(const CallerInformations* callerInformation, const LicenseLocation* licenseLocation,
 						   LicenseInfo* license_out);
 
 /**
@@ -44,11 +46,11 @@
  * Should be called from time to time to confirm we're still using the
  * license.
  */
-EVENT_TYPE confirm_license(char* featureName, LicenseLocation* licenseLocation);
+LCC_EVENT_TYPE confirm_license(char* featureName, LicenseLocation* licenseLocation);
 /**
  * Do nothing for now, useful for network licenses.
  */
-EVENT_TYPE release_license(char* featureName, LicenseLocation licenseLocation);
+LCC_EVENT_TYPE release_license(char* featureName, LicenseLocation licenseLocation);
 
 #ifdef __cplusplus
 }
diff --git a/src/inspector/inspector.cpp b/src/inspector/inspector.cpp
index 9a994bf..01b90aa 100644
--- a/src/inspector/inspector.cpp
+++ b/src/inspector/inspector.cpp
@@ -6,11 +6,11 @@
 #include "../library/os/cpu_info.hpp"
 
 using namespace std;
-const map<IDENTIFICATION_STRATEGY, string> stringByStrategyId = {
+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"}};
 
-const unordered_map<EVENT_TYPE, string> stringByEventType = {
+const unordered_map<LCC_EVENT_TYPE, string> stringByEventType = {
 	{LICENSE_OK, "OK "},
 	{LICENSE_FILE_NOT_FOUND, "license file not found "},
 	{LICENSE_SERVER_NOT_FOUND, "license server can't be contacted "},
@@ -22,11 +22,11 @@
 	{LICENSE_CORRUPTED, "license signature didn't match with current license "},
 	{IDENTIFIERS_MISMATCH, "Calculated identifier and the one provided in license didn't match"}};
 
-static EVENT_TYPE verifyLicense(const string& fname) {
+static LCC_EVENT_TYPE verifyLicense(const string& fname) {
 	LicenseInfo licenseInfo;
 	LicenseLocation licLocation = {LICENSE_PATH};
 	std::copy(fname.begin(), fname.end(), licLocation.licenseData);
-	EVENT_TYPE result = acquire_license(nullptr, &licLocation, &licenseInfo);
+	LCC_EVENT_TYPE result = acquire_license(nullptr, &licLocation, &licenseInfo);
 	if (result == LICENSE_OK) {
 		cout << "license OK" << endl;
 	} else {
@@ -42,8 +42,8 @@
 	cout << "Virtual machine:" << cpu.cpu_virtual() << endl;
 	cout << "Cpu model      : 0x" << std::hex << ((long)cpu.model()) << std::dec << endl;
 
-	char pc_identifier[API_PC_IDENTIFIER_SIZE + 1];
-	size_t bufSize = API_PC_IDENTIFIER_SIZE + 1;
+	char pc_identifier[LCC_API_PC_IDENTIFIER_SIZE + 1];
+	size_t bufSize = LCC_API_PC_IDENTIFIER_SIZE + 1;
 	for (const auto& x : stringByStrategyId) {
 		if (identify_pc(x.first, pc_identifier, &bufSize)) {
 			std::cout << x.second << ':' << pc_identifier << std::endl;
diff --git a/src/library/CMakeLists.txt b/src/library/CMakeLists.txt
index ffa4a76..9a70020 100644
--- a/src/library/CMakeLists.txt
+++ b/src/library/CMakeLists.txt
@@ -8,6 +8,7 @@
     LicenseReader.cpp
     limits/license_verifier.cpp
     ini/ConvertUTF.c
+    $<TARGET_OBJECTS:pc_identifier>
     $<TARGET_OBJECTS:locate>
     $<TARGET_OBJECTS:os>
     $<TARGET_OBJECTS:base>
diff --git a/src/library/base/EventRegistry.cpp b/src/library/base/EventRegistry.cpp
index 920e735..ed0f074 100644
--- a/src/library/base/EventRegistry.cpp
+++ b/src/library/base/EventRegistry.cpp
@@ -17,7 +17,7 @@
 namespace license {
 using namespace std;
 
-const map<EVENT_TYPE, int> PROGRESS_BY_EVENT_TYPE = {
+const map<LCC_EVENT_TYPE, int> PROGRESS_BY_EVENT_TYPE = {
 	{LICENSE_SPECIFIED, 0}, {LICENSE_FOUND, 1}, {PRODUCT_FOUND, 2}, {SIGNATURE_VERIFIED, 3}, {LICENSE_OK, 4}};
 
 EventRegistry::EventRegistry() { current_validation_step = -1; }
@@ -73,11 +73,11 @@
 	return result;
 }
 
-void EventRegistry::addEvent(EVENT_TYPE event, const std::string &licenseLocationId) {
+void EventRegistry::addEvent(LCC_EVENT_TYPE event, const std::string &licenseLocationId) {
 	addEvent(event, licenseLocationId.c_str(), nullptr);
 }
 
-void EventRegistry::addEvent(EVENT_TYPE event, const char *licenseLocationId, const char *info) {
+void EventRegistry::addEvent(LCC_EVENT_TYPE event, const char *licenseLocationId, const char *info) {
 	AuditEvent audit;
 	auto eventIterator = PROGRESS_BY_EVENT_TYPE.find(event);
 	bool successEvent = (eventIterator != PROGRESS_BY_EVENT_TYPE.end());
diff --git a/src/library/base/EventRegistry.h b/src/library/base/EventRegistry.h
index 23a53a5..38b44d0 100644
--- a/src/library/base/EventRegistry.h
+++ b/src/library/base/EventRegistry.h
@@ -52,8 +52,8 @@
 	 * @return NULL if no failures are found.
 	 */
 	const AuditEvent *getLastFailure() const;
-	void addEvent(EVENT_TYPE event, const std::string &licenseLocationId);
-	void addEvent(EVENT_TYPE event, const char *licenseLocationId = nullptr, const char *info = nullptr);
+	void addEvent(LCC_EVENT_TYPE event, const std::string &licenseLocationId);
+	void addEvent(LCC_EVENT_TYPE event, const char *licenseLocationId = nullptr, const char *info = nullptr);
 	void exportLastEvents(AuditEvent *auditEvents, int nlogs);
 };
 }  // namespace license
diff --git a/src/library/licensecc.cpp b/src/library/licensecc.cpp
index 9b5f5ca..dee72dc 100644
--- a/src/library/licensecc.cpp
+++ b/src/library/licensecc.cpp
@@ -17,6 +17,7 @@
 #include <licensecc/licensecc.h>
 #include <licensecc_properties.h>
 
+#include "base/logger.h"
 #include "pc_identifier/pc_identifier_facade.hpp"
 #include "limits/license_verifier.hpp"
 #include "base/StringUtils.h"
@@ -24,16 +25,27 @@
 
 using namespace std;
 
-void print_error(char out_buffer[API_ERROR_BUFFER_SIZE], LicenseInfo* licenseInfo) {}
 
-bool identify_pc(IDENTIFICATION_STRATEGY pc_id_method, char* chbuffer, size_t* bufSize) {
-	string pc_id = license::PcIdentifierFacade::generate_user_pc_signature(pc_id_method);
-	if (*bufSize >= pc_id.size() + 1) {
-		strncpy(chbuffer, pc_id.c_str(), *bufSize);
+void print_error(char out_buffer[LCC_API_ERROR_BUFFER_SIZE], LicenseInfo* licenseInfo) {}
+
+bool identify_pc(LCC_API_IDENTIFICATION_STRATEGY pc_id_method, char* chbuffer, size_t* bufSize) {
+	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);
+			strncpy(chbuffer, pc_id.c_str(), *bufSize);
+			result = true;
+		} catch (const std::exception& ex) {
+			LOG_ERROR("Error calculating pc_identifier: %s", ex.what());
+#ifdef _DEBUG
+				cout
+				<< "Error occurred: " << ex.what() << std::endl;
+#endif
+		}
 	} else {
-		*bufSize = pc_id.size() + 1;
+		*bufSize = LCC_API_PC_IDENTIFIER_SIZE + 1;
 	}
-	return result == FUNC_RET_OK;
+	return result;
 }
 
 static void mergeLicenses(const vector<LicenseInfo>& licenses, LicenseInfo* license_out) {
@@ -52,8 +64,8 @@
 	}
 }
 
-EVENT_TYPE acquire_license(const CallerInformations* callerInformation, const LicenseLocation* licenseLocation,
-						   LicenseInfo* license_out) {
+LCC_EVENT_TYPE acquire_license(const CallerInformations* callerInformation,
+									 const LicenseLocation* licenseLocation, LicenseInfo* license_out) {
 	const license::LicenseReader lr = license::LicenseReader(licenseLocation);
 	vector<license::FullLicenseInfo> licenses;
 	string project;
@@ -65,7 +77,7 @@
 		project = string(LCC_PROJECT_NAME);
 	}
 	license::EventRegistry er = lr.readLicenses(string(project), licenses);
-	EVENT_TYPE result;
+	LCC_EVENT_TYPE result;
 	if (licenses.size() > 0) {
 		vector<LicenseInfo> licenses_with_errors;
 		vector<LicenseInfo> licenses_ok;
@@ -109,11 +121,12 @@
 #endif
 
 	if (license_out != nullptr) {
-		er.exportLastEvents(license_out->status, API_AUDIT_EVENT_NUM);
+		er.exportLastEvents(license_out->status, LCC_API_AUDIT_EVENT_NUM);
 	}
 	return result;
 }
 
-EVENT_TYPE confirm_license(char* product, LicenseLocation licenseLocation) { return LICENSE_OK; }
+LCC_EVENT_TYPE confirm_license(char* product, LicenseLocation licenseLocation) { return LICENSE_OK; }
 
-EVENT_TYPE release_license(char* product, LicenseLocation licenseLocation) { return LICENSE_OK; }
+LCC_EVENT_TYPE release_license(char* product, LicenseLocation licenseLocation) { return LICENSE_OK; }
+
diff --git a/src/library/limits/license_verifier.cpp b/src/library/limits/license_verifier.cpp
index bd2ed22..2f4a7d9 100644
--- a/src/library/limits/license_verifier.cpp
+++ b/src/library/limits/license_verifier.cpp
@@ -35,7 +35,7 @@
 
 // TODO: split in different classes
 FUNCTION_RETURN LicenseVerifier::verify_limits(const FullLicenseInfo& licInfo) {
-	bool is_valid = VERIFY_MAGIC(licInfo);
+	bool is_valid = LCC_VERIFY_MAGIC(licInfo);
 	if (!is_valid) {
 		m_event_registry.addEvent(LICENSE_CORRUPTED, licInfo.source.c_str());
 	}
@@ -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 EVENT_TYPE event = PcIdentifierFacade::validate_pc_signature(client_sig->second);
+		const LCC_EVENT_TYPE event = PcIdentifierFacade::validate_pc_signature(client_sig->second);
 		m_event_registry.addEvent(event, licInfo.source);
 		is_valid = is_valid && (event == LICENSE_OK);
 	}
@@ -89,7 +89,7 @@
 
 	const auto proprietary_data = fullLicInfo.m_limits.find(PARAM_EXTRA_DATA);
 	if (proprietary_data != fullLicInfo.m_limits.end()) {
-		strncpy(info.proprietary_data, proprietary_data->second.c_str(), API_PROPRIETARY_DATA_SIZE);
+		strncpy(info.proprietary_data, proprietary_data->second.c_str(), LCC_API_PROPRIETARY_DATA_SIZE);
 	}
 	return info;
 }
diff --git a/src/library/locate/ApplicationFolder.cpp b/src/library/locate/ApplicationFolder.cpp
index 8741988..b13fedd 100644
--- a/src/library/locate/ApplicationFolder.cpp
+++ b/src/library/locate/ApplicationFolder.cpp
@@ -33,7 +33,7 @@
 	const FUNCTION_RETURN fret = getModuleName(fname);
 	if (fret == FUNC_RET_OK) {
 		const string module_name = remove_extension(fname);
-		const string temptativeLicense = string(module_name) + LICENSE_FILE_EXTENSION;
+		const string temptativeLicense = string(module_name) + LCC_LICENSE_FILE_EXTENSION;
 		ifstream f(temptativeLicense.c_str());
 		if (f.good()) {
 			diskFiles.push_back(temptativeLicense);
diff --git a/src/library/locate/EnvironmentVarData.cpp b/src/library/locate/EnvironmentVarData.cpp
index 6e47d21..0162dbe 100644
--- a/src/library/locate/EnvironmentVarData.cpp
+++ b/src/library/locate/EnvironmentVarData.cpp
@@ -29,24 +29,24 @@
 
 const vector<string> EnvironmentVarData::license_locations(EventRegistry &eventRegistry) {
 	vector<string> diskFiles;
-	char *env_var_value = getenv(LICENSE_DATA_ENV_VAR);
+	char *env_var_value = getenv(LCC_LICENSE_DATA_ENV_VAR);
 	if (env_var_value != nullptr && env_var_value[0] != '\0') {
-		eventRegistry.addEvent(LICENSE_SPECIFIED, LICENSE_LOCATION_ENV_VAR);
+		eventRegistry.addEvent(LICENSE_SPECIFIED, LCC_LICENSE_LOCATION_ENV_VAR);
 		FILE_FORMAT licenseFormat = identify_format(env_var_value);
 		if (licenseFormat == UNKNOWN) {
-			eventRegistry.addEvent(LICENSE_MALFORMED, LICENSE_LOCATION_ENV_VAR);
+			eventRegistry.addEvent(LICENSE_MALFORMED, LCC_LICENSE_LOCATION_ENV_VAR);
 		} else {
-			diskFiles.push_back(LICENSE_LOCATION_ENV_VAR);
+			diskFiles.push_back(LCC_LICENSE_LOCATION_ENV_VAR);
 			isBase64 = (licenseFormat == BASE64);
 		}
 	} else {
-		eventRegistry.addEvent(ENVIRONMENT_VARIABLE_NOT_DEFINED, LICENSE_LOCATION_ENV_VAR);
+		eventRegistry.addEvent(ENVIRONMENT_VARIABLE_NOT_DEFINED, LCC_LICENSE_LOCATION_ENV_VAR);
 	}
 	return diskFiles;
 }
 
 const std::string EnvironmentVarData::retrieve_license_content(const std::string &licenseLocation) const {
-	string tmpVal = getenv(LICENSE_LOCATION_ENV_VAR);
+	string tmpVal = getenv(LCC_LICENSE_LOCATION_ENV_VAR);
 	if (isBase64) {
 		int flen = 0;
 		unsigned char *raw = unbase64(tmpVal.c_str(), tmpVal.length(), &flen);
diff --git a/src/library/locate/EnvironmentVarLocation.cpp b/src/library/locate/EnvironmentVarLocation.cpp
index 5615482..070ad8d 100644
--- a/src/library/locate/EnvironmentVarLocation.cpp
+++ b/src/library/locate/EnvironmentVarLocation.cpp
@@ -22,14 +22,14 @@
 const vector<string> EnvironmentVarLocation::license_locations(EventRegistry &eventRegistry) {
 	vector<string> licenseFileFoundWithEnvVariable;
 
-	const string varName(LICENSE_LOCATION_ENV_VAR);
+	const string varName(LCC_LICENSE_LOCATION_ENV_VAR);
 	if (varName.length() > 0) {
 		// var name is defined in header files.
-		char *env_var_value = getenv(LICENSE_LOCATION_ENV_VAR);
+		char *env_var_value = getenv(LCC_LICENSE_LOCATION_ENV_VAR);
 		if (env_var_value != nullptr && env_var_value[0] != '\0') {
 			const vector<string> declared_positions = license::split_string(string(env_var_value), ';');
 			licenseFileFoundWithEnvVariable =
-				license::filter_existing_files(declared_positions, eventRegistry, LICENSE_LOCATION_ENV_VAR);
+				license::filter_existing_files(declared_positions, eventRegistry, LCC_LICENSE_LOCATION_ENV_VAR);
 		} else {
 			eventRegistry.addEvent(ENVIRONMENT_VARIABLE_NOT_DEFINED);
 		}
diff --git a/src/library/locate/ExternalDefinition.cpp b/src/library/locate/ExternalDefinition.cpp
index 13ca80a..7413aeb 100644
--- a/src/library/locate/ExternalDefinition.cpp
+++ b/src/library/locate/ExternalDefinition.cpp
@@ -34,7 +34,7 @@
 		eventRegistry.addEvent(LICENSE_SPECIFIED, get_strategy_name());
 		switch (m_location->license_data_type) {
 			case LICENSE_PATH: {
-				string licData(m_location->licenseData, mstrnlen_s(m_location->licenseData, API_LICENSE_DATA_LENGTH));
+				string licData(m_location->licenseData, mstrnlen_s(m_location->licenseData, LCC_API_MAX_LICENSE_DATA_LENGTH));
 				const vector<string> declared_positions = license::split_string(licData, ';');
 				existing_pos =
 					license::filter_existing_files(declared_positions, eventRegistry, get_strategy_name().c_str());
@@ -52,7 +52,7 @@
 
 const std::string ExternalDefinition::retrieve_license_content(const std::string &licenseLocation) const {
 	if (licenseLocation == get_strategy_name()) {
-		string licData(m_location->licenseData, mstrnlen_s(m_location->licenseData, API_LICENSE_DATA_LENGTH));
+		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);
diff --git a/src/library/os/CMakeLists.txt b/src/library/os/CMakeLists.txt
index 8d95071..897adb2 100644
--- a/src/library/os/CMakeLists.txt
+++ b/src/library/os/CMakeLists.txt
@@ -3,14 +3,17 @@
 		add_library(os OBJECT
 		    openssl/signature_verifier.cpp
 		    linux/execution_environment.cpp
+		    cpu_info_common.cpp
 		    linux/cpu_info.cpp
 		    linux/os-linux.c 
 		    linux/network_id.c)
 	ELSE(UNIX)
-  	    add_library(os OBJECT openssl/signature_verifier.cpp windows/os-win.c)
+  	    add_library(os OBJECT 
+  	    cpu_info_common.cpp openssl/signature_verifier.cpp windows/os-win.c)
 	ENDIF(UNIX)
 ELSE(UNIX OR OPENSSL_FOUND)
-    target_sources(os OBJECT windows/signature_verifier.cpp windows/os-win.c)
+    target_sources(os OBJECT
+        cpu_info_common.cpp windows/signature_verifier.cpp windows/os-win.c)
 ENDIF(UNIX OR OPENSSL_FOUND)
 
 if(CODE_COVERAGE AND UNIX)
diff --git a/src/library/os/cpu_info.hpp b/src/library/os/cpu_info.hpp
index 716ca40..04da89b 100644
--- a/src/library/os/cpu_info.hpp
+++ b/src/library/os/cpu_info.hpp
@@ -10,10 +10,15 @@
 #include <string>
 namespace license {
 
+typedef enum { BARE_TO_METAL, VMWARE, VIRTUALBOX, V_XEN, KVM, HV, V_OTHER } VIRTUALIZATION_DETAIL;
+
 /**
  * Cpu informations
  */
 class CpuInfo {
+private:
+	bool is_hypervisor_set() const;
+
 public:
 	CpuInfo();
 	virtual ~CpuInfo();
@@ -22,8 +27,9 @@
 	 * @return true if the cpu is detected to be a virtual cpu
 	 */
 	bool cpu_virtual() const;
-	uint32_t model();
+	uint32_t model() const;
 	std::string vendor() const;
+	VIRTUALIZATION_DETAIL getVirtualizationDetail() const;
 };
 
 } /* namespace license */
diff --git a/src/library/os/cpu_info_common.cpp b/src/library/os/cpu_info_common.cpp
new file mode 100644
index 0000000..d75ccf1
--- /dev/null
+++ b/src/library/os/cpu_info_common.cpp
@@ -0,0 +1,42 @@
+/*
+ * cpu_info_common.cpp
+ *
+ *  Created on: Jan 19, 2020
+ *      Author: GC
+ */
+#include <unordered_map>
+#include "cpu_info.hpp"
+
+namespace license {
+using namespace std;
+
+const unordered_map<string, VIRTUALIZATION_DETAIL> virtual_cpu_names{
+	{"bhyve bhyve ", V_OTHER}, {"KVMKVMKVM", KVM},		  {"Microsoft Hv", HV},
+	{" lrpepyh vr", HV},	   {"prl hyperv  ", V_OTHER}, {"VMwareVMware", VMWARE},
+	{"XenVMMXenVMM", V_XEN},   {"ACRNACRNACRN", V_OTHER}, {"VBoxVBoxVBox", VIRTUALBOX}};
+
+/**
+ * Detect Virtual machine using hypervisor bit.
+ * @return true if the cpu hypervisor bit is set to 1
+ */
+bool CpuInfo::cpu_virtual() const {
+	bool is_virtual = is_hypervisor_set();
+	if (!is_virtual) {
+		string cpu_vendor = vendor();
+		auto it = virtual_cpu_names.find(cpu_vendor);
+		is_virtual = (it != virtual_cpu_names.end());
+	}
+	return is_virtual;
+}
+VIRTUALIZATION_DETAIL CpuInfo::getVirtualizationDetail() const {
+	string cpu_vendor = vendor();
+	auto it = virtual_cpu_names.find(cpu_vendor);
+	VIRTUALIZATION_DETAIL result = BARE_TO_METAL;
+	if (it != virtual_cpu_names.end()) {
+		result = it->second;
+	} else if (is_hypervisor_set()) {
+		result = (VIRTUALIZATION_DETAIL)V_OTHER;
+	}
+	return result;
+}
+}  // namespace license
diff --git a/src/library/os/execution_environment.hpp b/src/library/os/execution_environment.hpp
index 6fbd6c6..ce3fb63 100644
--- a/src/library/os/execution_environment.hpp
+++ b/src/library/os/execution_environment.hpp
@@ -25,13 +25,15 @@
 	ALI_CLOUD
 } CLOUD_PROVIDER;
 
-typedef enum { BARE_TO_METAL, VMWARE, VIRTUALBOX, XEN, KVM } VIRTUALIZATION_DETAIL;
 
 class ExecutionEnvironment {
 public:
 	ExecutionEnvironment(){};
 	virtual ~ExecutionEnvironment(){};
 	VIRTUALIZATION getVirtualization();
+	bool is_cloud();
+	bool is_docker();
+	CLOUD_PROVIDER getCloudProvider();
 };
 
 }  // namespace license
diff --git a/src/library/os/linux/cpu_info.cpp b/src/library/os/linux/cpu_info.cpp
index 4db4ba0..4b5ff85 100644
--- a/src/library/os/linux/cpu_info.cpp
+++ b/src/library/os/linux/cpu_info.cpp
@@ -13,9 +13,6 @@
 namespace license {
 using namespace std;
 
-const unordered_set<string> virtual_cpu_names = {"bhyve bhyve ", "KVMKVMKVM",	"Microsoft Hv",
-												 " lrpepyh vr",  "prl hyperv  ", "VMwareVMware",
-												 "XenVMMXenVMM", "ACRNACRNACRN", "VBoxVBoxVBox"};
 struct CPUVendorID {
 	unsigned int ebx;
 	unsigned int edx;
@@ -31,20 +28,15 @@
  * Detect Virtual machine using hypervisor bit.
  * @return true if the cpu hypervisor bit is set to 1
  */
-bool CpuInfo::cpu_virtual() const {
+bool CpuInfo::is_hypervisor_set() const {
 	unsigned int level = 1, eax = 0, ebx = 0, ecx = 0, edx = 0;
 	__get_cpuid(level, &eax, &ebx, &ecx, &edx);
 
 	bool is_virtual = (((ecx >> 31) & 1) == 1);  // hypervisor flag
-	if (!is_virtual) {
-		string cpu_vendor = vendor();
-		auto it = virtual_cpu_names.find(cpu_vendor);
-		is_virtual = (it != virtual_cpu_names.end());
-	}
 	return is_virtual;
 }
 
-uint32_t CpuInfo::model() {
+uint32_t CpuInfo::model() const {
 	unsigned int level = 1, eax = 0, ebx = 0, ecx = 0, edx = 0;
 	__get_cpuid(level, &eax, &ebx, &ecx, &edx);
 	// ax bits 0-3 stepping,4-7 model,8-11 family id,12-13 processor type
diff --git a/src/library/os/linux/execution_environment.cpp b/src/library/os/linux/execution_environment.cpp
index 81c5b16..a69122a 100644
--- a/src/library/os/linux/execution_environment.cpp
+++ b/src/library/os/linux/execution_environment.cpp
@@ -7,6 +7,8 @@
 #include <paths.h>
 #include <sys/stat.h>
 #include <unistd.h>
+#include <fstream>
+#include <iostream>
 #include <stdio.h>
 #include <string.h>
 #include <dirent.h>
@@ -17,6 +19,7 @@
 #include "../execution_environment.hpp"
 
 namespace license {
+using namespace std;
 
 // 0=NO 1=Docker/2=Lxc
 static int checkContainerProc() {
@@ -58,21 +61,44 @@
 	return result;
 }
 
-// 0=NO 1=Docker/Lxc
-static int checkLXC() { return (access("/var/run/systemd/container", F_OK) == 0) ? 1 : 0; }
-
-VIRTUALIZATION ExecutionEnvironment::getVirtualization() {
-	VIRTUALIZATION result = NONE;
-	CpuInfo cpuInfo;
-	int isContainer = checkContainerProc();
-	if (isContainer == 1) {
-		result = CONTAINER;
-	} else if (isContainer == 2 || checkLXC()) {
-		result = CONTAINER;
-	} else if (cpuInfo.cpu_virtual()) {
-		result = VM;
-	} else {
+// 0=NO 1=Docker/2=Lxc
+static int checkSystemdContainer() {
+	ifstream systemd_container("/var/run/systemd/container");
+	int result = 0;
+	if (systemd_container.good()) {
+		result = 1;
+		for (string line; getline(systemd_container, line);) {
+			if (line.find("docker") != string::npos) {
+				result = 1;
+				break;
+			} else if (line.find("lxc") != string::npos) {
+				result = 2;
+				break;
+			}
+		}
 	}
 	return result;
 }
+
+VIRTUALIZATION ExecutionEnvironment::getVirtualization() {
+	VIRTUALIZATION result;
+	CpuInfo cpuInfo;
+	bool isContainer = checkContainerProc() != 0 || checkSystemdContainer() != 0;
+	if (isContainer) {
+		result = CONTAINER;
+	} else if (cpuInfo.cpu_virtual() || is_cloud()) {
+		result = VM;
+	} else {
+		result = NONE;
+	}
+	return result;
+}
+
+bool ExecutionEnvironment::is_cloud() { return getCloudProvider() == NONE; }
+
+bool ExecutionEnvironment::is_docker() { return (checkContainerProc() == 1 || checkSystemdContainer() == 1); }
+
+CLOUD_PROVIDER ExecutionEnvironment::getCloudProvider() {}
+
+
 }  // namespace license
diff --git a/src/library/pc_identifier/CMakeLists.txt b/src/library/pc_identifier/CMakeLists.txt
index a330b6f..d0f581e 100644
--- a/src/library/pc_identifier/CMakeLists.txt
+++ b/src/library/pc_identifier/CMakeLists.txt
@@ -1,7 +1,11 @@
 add_library(pc_identifier OBJECT
 	pc_identifier_facade.cpp
+	identification_strategy.cpp
+	ethernet.cpp
+	disk_strategy.cpp
 	pc_identifier.cpp
 	default_strategy.cpp
+	
 	#pc-identifiers.c
 )
 
diff --git a/src/library/pc_identifier/default_strategy.cpp b/src/library/pc_identifier/default_strategy.cpp
index afa961f..2f1bd7d 100644
--- a/src/library/pc_identifier/default_strategy.cpp
+++ b/src/library/pc_identifier/default_strategy.cpp
@@ -1,33 +1,80 @@
 /*
  * default_strategy.cpp
  *
- *  Created on: Jan 2, 2020
+ *  Created on: Jan 1, 2020
  *      Author: devel
  */
 
+#include <vector>
+#include "pc_identifier_facade.hpp"
+#include "../os/execution_environment.hpp"
 #include "default_strategy.hpp"
 
+using namespace std;
 namespace license {
 
-DefaultStrategy::DefaultStrategy() {
-	// TODO Auto-generated constructor stub
+static vector<LCC_API_IDENTIFICATION_STRATEGY> available_strategies() {
+	ExecutionEnvironment exec;
+	VIRTUALIZATION virtualization = exec.getVirtualization();
+	vector<LCC_API_IDENTIFICATION_STRATEGY> strategy_to_try;
+	if (virtualization == CONTAINER) {
+		if (exec.is_docker()) {
+			strategy_to_try = LCC_DOCKER_STRATEGIES;
+		} else {
+			strategy_to_try = LCC_LXC_STRATEGIES;
+		}
+	} else if (virtualization == VM) {
+		if (exec.is_cloud()) {
+			strategy_to_try = LCC_CLOUD_STRATEGIES;
+		} else {
+			strategy_to_try = LCC_VM_STRATEGIES;
+		}
+	} else {
+		strategy_to_try = LCC_BARE_TO_METAL_STRATEGIES;
+	}
+	return strategy_to_try;
 }
 
-DefaultStrategy::~DefaultStrategy() {
-	// TODO Auto-generated destructor stub
+DefaultStrategy::DefaultStrategy() {}
+
+DefaultStrategy::~DefaultStrategy() {}
+
+LCC_API_IDENTIFICATION_STRATEGY DefaultStrategy::identification_strategy() const { return STRATEGY_DEFAULT; }
+
+FUNCTION_RETURN DefaultStrategy::identify_pc(PcIdentifier& pc_id) const {
+	vector<LCC_API_IDENTIFICATION_STRATEGY> strategy_to_try = available_strategies();
+	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);
+		if (ret == FUNC_RET_OK) {
+			break;
+		}
+	}
+	return ret;
 }
 
-DefaultStrategy::DefaultStrategy(const DefaultStrategy& other) {
-	// TODO Auto-generated constructor stub
+std::vector<PcIdentifier> DefaultStrategy::alternative_ids() const {
+	vector<LCC_API_IDENTIFICATION_STRATEGY> strategy_to_try = available_strategies();
+	vector<PcIdentifier> identifiers;
+	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);
+	}
+	return identifiers;
 }
 
-IDENTIFICATION_STRATEGY DefaultStrategy::identification_strategy() const { return STRATEGY_DEFAULT; }
-
-void DefaultStrategy::identify_pc(PcIdentifier& identifier) const {}
-
-std::vector<PcIdentifier> DefaultStrategy::alternative_ids() const {}
-
-EVENT_TYPE DefaultStrategy::validate_identifier(const PcIdentifier& identifier) const {
+LCC_EVENT_TYPE DefaultStrategy::validate_identifier(const PcIdentifier& identifier) const {
 	// default strategy should always realize itself as a concrete strategy
 	return IDENTIFIERS_MISMATCH;
 }
diff --git a/src/library/pc_identifier/default_strategy.hpp b/src/library/pc_identifier/default_strategy.hpp
index 667140d..b0cda7c 100644
--- a/src/library/pc_identifier/default_strategy.hpp
+++ b/src/library/pc_identifier/default_strategy.hpp
@@ -14,12 +14,11 @@
 class DefaultStrategy : public IdentificationStrategy {
 public:
 	DefaultStrategy();
-	DefaultStrategy(const DefaultStrategy &other);
 	virtual ~DefaultStrategy();
-	virtual IDENTIFICATION_STRATEGY identification_strategy() const;
-	virtual void identify_pc(PcIdentifier &identifier) const;
+	virtual LCC_API_IDENTIFICATION_STRATEGY identification_strategy() const;
+	virtual FUNCTION_RETURN identify_pc(PcIdentifier &pc_id) const;
 	virtual std::vector<PcIdentifier> alternative_ids() const;
-	virtual EVENT_TYPE validate_identifier(const PcIdentifier &identifier) const;
+	virtual LCC_EVENT_TYPE validate_identifier(const PcIdentifier &identifier) const;
 };
 
 } /* namespace license */
diff --git a/src/library/pc_identifier/disk_strategy.cpp b/src/library/pc_identifier/disk_strategy.cpp
new file mode 100644
index 0000000..b2e6c1f
--- /dev/null
+++ b/src/library/pc_identifier/disk_strategy.cpp
@@ -0,0 +1,94 @@
+/*
+ * disk_strategy.cpp
+ *
+ *  Created on: Jan 14, 2020
+ *      Author: devel
+ */
+#include <string.h>
+#include "../os/os.h"
+#include "disk_strategy.hpp"
+
+using namespace std;
+namespace license {
+
+static FUNCTION_RETURN generate_disk_pc_id(vector<array<uint8_t, 6>> &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);
+	if (result_diskinfos != FUNC_RET_OK && result_diskinfos != FUNC_RET_BUFFER_TOO_SMALL) {
+		return result_diskinfos;
+	}
+	if (disk_num == 0) {
+		return FUNC_RET_NOT_AVAIL;
+	}
+
+	diskInfos = (DiskInfo *)malloc(disk_num * sizeof(DiskInfo));
+	memset(diskInfos, 0, disk_num * sizeof(DiskInfo));
+	result_diskinfos = getDiskInfos(diskInfos, &disk_num);
+	if (result_diskinfos != FUNC_RET_OK) {
+		free(diskInfos);
+		return result_diskinfos;
+	}
+	for (i = 0; i < disk_num; i++) {
+		char firstChar = use_id ? diskInfos[i].label[0] : diskInfos[i].disk_sn[0];
+		available_disk_info += firstChar == 0 ? 0 : 1;
+	}
+	if (available_disk_info == 0) {
+		free(diskInfos);
+		return FUNC_RET_NOT_AVAIL;
+	}
+	v_disk_id.reserve(available_disk_info);
+	for (i = 0; i < disk_num; i++) {
+		array<uint8_t, 6> 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());
+				v_disk_id.push_back(a_disk_id);
+			}
+		} else {
+			if (diskInfos[i].label[0] != 0) {
+				a_disk_id.fill(0);
+				// strncpy((&a_disk_id[0], diskInfos[i].label, a_disk_id.size());
+				v_disk_id.push_back(a_disk_id);
+			}
+		}
+	}
+	free(diskInfos);
+	return FUNC_RET_OK;
+}
+
+DiskStrategy::DiskStrategy(bool use_id) : m_use_id(use_id) {
+}
+
+DiskStrategy::~DiskStrategy() {
+}
+
+LCC_API_IDENTIFICATION_STRATEGY DiskStrategy::identification_strategy() const {
+	return m_use_id ? STRATEGY_DISK_NUM : STRATEGY_DISK_LABEL;
+}
+
+FUNCTION_RETURN DiskStrategy::identify_pc(PcIdentifier &pc_id) const {
+	vector<array<uint8_t, 6>> data;
+	FUNCTION_RETURN result = generate_disk_pc_id(data, m_use_id);
+	if (result == FUNC_RET_OK) {
+		pc_id.set_data(data[0]);
+	}
+	return result;
+}
+
+std::vector<PcIdentifier> DiskStrategy::alternative_ids() const {}
+
+LCC_EVENT_TYPE DiskStrategy::validate_identifier(const PcIdentifier &identifier) const {
+	vector<array<uint8_t, 6>> 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);
+	}
+	return result;
+}
+
+} /* namespace license */
diff --git a/src/library/pc_identifier/disk_strategy.hpp b/src/library/pc_identifier/disk_strategy.hpp
new file mode 100644
index 0000000..5246269
--- /dev/null
+++ b/src/library/pc_identifier/disk_strategy.hpp
@@ -0,0 +1,30 @@
+/*
+ * disk_strategy.hpp
+ *
+ *  Created on: Jan 14, 2020
+ *      Author: devel
+ */
+
+#ifndef SRC_LIBRARY_PC_IDENTIFIER_DISK_STRATEGY_HPP_
+#define SRC_LIBRARY_PC_IDENTIFIER_DISK_STRATEGY_HPP_
+
+#include "identification_strategy.hpp"
+
+namespace license {
+
+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;
+	virtual LCC_EVENT_TYPE validate_identifier(const PcIdentifier &identifier) const;
+};
+
+} /* 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
new file mode 100644
index 0000000..f267dfa
--- /dev/null
+++ b/src/library/pc_identifier/disk_strategy_test.cpp
@@ -0,0 +1,10 @@
+/*
+ * 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
new file mode 100644
index 0000000..f7166a7
--- /dev/null
+++ b/src/library/pc_identifier/ethernet.cpp
@@ -0,0 +1,99 @@
+/*
+ * ethernet.cpp
+ *
+ *  Created on: Jan 11, 2020
+ *      Author: devel
+ */
+#include <array>
+
+#include "ethernet.hpp"
+#include "../os/os.h"
+
+namespace license {
+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;
+
+	FUNCTION_RETURN result_adapterInfos = getAdapterInfos(NULL, &adapters);
+	if (result_adapterInfos != FUNC_RET_BUFFER_TOO_SMALL) {
+		return result_adapterInfos;
+	}
+	if (adapters == 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;
+					}
+				}
+			}
+			identifier[6] = identifier[6] & 0x1F;
+			data.push_back(identifier);
+		}
+	}
+	free(adapterInfos);
+	return result_adapterInfos;
+}
+
+Ethernet::Ethernet(bool useIp) : use_ip(useIp) {}
+
+Ethernet::~Ethernet() {}
+
+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;
+	FUNCTION_RETURN result = generate_ethernet_pc_id(data, use_ip);
+	if (result == FUNC_RET_OK) {
+		pc_id.set_data(data[0]);
+	}
+	return result;
+}
+
+std::vector<PcIdentifier> Ethernet::alternative_ids() const {
+	vector<array<uint8_t, 6>> data;
+	FUNCTION_RETURN result = generate_ethernet_pc_id(data, use_ip);
+	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 Ethernet::validate_identifier(const PcIdentifier &identifier) const {
+	vector<array<uint8_t, 6>> 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);
+	}
+	return result;
+}
+
+} /* namespace license */
diff --git a/src/library/pc_identifier/ethernet.hpp b/src/library/pc_identifier/ethernet.hpp
new file mode 100644
index 0000000..c35e9f6
--- /dev/null
+++ b/src/library/pc_identifier/ethernet.hpp
@@ -0,0 +1,30 @@
+/*
+ * ethernet.hpp
+ *
+ *  Created on: Jan 11, 2020
+ *      Author: devel
+ */
+
+#ifndef SRC_LIBRARY_PC_IDENTIFIER_ETHERNET_HPP_
+#define SRC_LIBRARY_PC_IDENTIFIER_ETHERNET_HPP_
+
+#include "identification_strategy.hpp"
+
+namespace license {
+
+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;
+	virtual LCC_EVENT_TYPE validate_identifier(const PcIdentifier &identifier) const;
+};
+
+} /* namespace license */
+
+#endif /* SRC_LIBRARY_PC_IDENTIFIER_ETHERNET_HPP_ */
diff --git a/src/library/pc_identifier/ethernet_test.cpp b/src/library/pc_identifier/ethernet_test.cpp
new file mode 100644
index 0000000..be8bdad
--- /dev/null
+++ b/src/library/pc_identifier/ethernet_test.cpp
@@ -0,0 +1,10 @@
+/*
+ * ethernet_test.cpp
+ *
+ *  Created on: Jan 11, 2020
+ *      Author: devel
+ */
+
+#include "ethernet.hpp"
+
+namespace license {} /* namespace license */
diff --git a/src/library/pc_identifier/identification_strategy.cpp b/src/library/pc_identifier/identification_strategy.cpp
new file mode 100644
index 0000000..1248b43
--- /dev/null
+++ b/src/library/pc_identifier/identification_strategy.cpp
@@ -0,0 +1,21 @@
+#include <array>
+#include "identification_strategy.hpp"
+
+namespace license {
+using namespace std;
+LCC_EVENT_TYPE IdentificationStrategy::validate_identifier(const PcIdentifier& identifier,
+														   const vector<array<uint8_t, 6>>& available_ids) const {
+	LCC_EVENT_TYPE result = IDENTIFIERS_MISMATCH;
+
+	if (identifier.get_identification_strategy() == identification_strategy()) {
+		for (auto& it : available_ids) {
+			if (identifier.data_match(it)) {
+				result = LICENSE_OK;
+				break;
+			}
+		}
+	}
+	return result;
+}
+
+}  // namespace license
diff --git a/src/library/pc_identifier/identification_strategy.hpp b/src/library/pc_identifier/identification_strategy.hpp
index 852de7b..77ecb8f 100644
--- a/src/library/pc_identifier/identification_strategy.hpp
+++ b/src/library/pc_identifier/identification_strategy.hpp
@@ -9,18 +9,25 @@
 #define SRC_LIBRARY_PC_IDENTIFIER_IDENTIFICATION_STRATEGY_HPP_
 
 #include <licensecc/datatypes.h>
+#include <licensecc_properties.h>
+
 #include <vector>
+#include "../base/base.h"
 #include "pc_identifier.hpp"
 namespace license {
 
 class IdentificationStrategy {
+protected:
+	LCC_EVENT_TYPE validate_identifier(const PcIdentifier& identifier,
+									   const std::vector<std::array<uint8_t, 6>>& available_ids) const;
+
 public:
 	IdentificationStrategy(){};
 	virtual ~IdentificationStrategy(){};
-	virtual IDENTIFICATION_STRATEGY identification_strategy() const = 0;
-	virtual void identify_pc(PcIdentifier &identifier) const = 0;
+	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 EVENT_TYPE validate_identifier(const PcIdentifier &identifier) const = 0;
+	virtual LCC_EVENT_TYPE validate_identifier(const PcIdentifier &identifier) const = 0;
 };
 
 } /* namespace license */
diff --git a/src/library/pc_identifier/pc-identifiers.c b/src/library/pc_identifier/pc-identifiers.c
index eda22b6..55ec2ba 100644
--- a/src/library/pc_identifier/pc-identifiers.c
+++ b/src/library/pc_identifier/pc-identifiers.c
@@ -88,94 +88,7 @@
 }
 
 static FUNCTION_RETURN generate_ethernet_pc_id(PcIdentifier *identifiers, unsigned int *num_identifiers, int use_mac) {
-	FUNCTION_RETURN result_adapterInfos;
-	OsAdapterInfo *adapterInfos;
-	size_t defined_adapters, adapters = 0;
-
-	if (identifiers == NULL || *num_identifiers == 0) {
-		result_adapterInfos = getAdapterInfos(NULL, &adapters);
-		if (result_adapterInfos == FUNC_RET_OK || result_adapterInfos == FUNC_RET_BUFFER_TOO_SMALL) {
-			*num_identifiers = adapters;
-			result_adapterInfos = FUNC_RET_OK;
-		}
-	} else {
-		defined_adapters = adapters = *num_identifiers;
-		adapterInfos = (OsAdapterInfo *)malloc(adapters * sizeof(OsAdapterInfo));
-		result_adapterInfos = getAdapterInfos(adapterInfos, &adapters);
-		if (result_adapterInfos == FUNC_RET_BUFFER_TOO_SMALL || result_adapterInfos == FUNC_RET_OK) {
-			unsigned int j;
-			for (j = 0; j < adapters; j++) {
-				unsigned int k;
-				for (k = 0; k < 6; k++)
-					if (use_mac) {
-						identifiers[j][k] = adapterInfos[j].mac_address[k + 2];
-					} else {
-						// use ip
-						if (k < 4) {
-							identifiers[j][k] = adapterInfos[j].ipv4_address[k];
-						} else {
-							// padding
-							identifiers[j][k] = 42;
-						}
-					}
-			}
-			result_adapterInfos = (adapters > defined_adapters ? FUNC_RET_BUFFER_TOO_SMALL : FUNC_RET_OK);
-		}
-		free(adapterInfos);
-	}
-	return result_adapterInfos;
-}
-
-static FUNCTION_RETURN generate_disk_pc_id(PcIdentifier *identifiers, unsigned int *num_identifiers, bool use_label) {
-	size_t disk_num, available_disk_info = 0;
-	FUNCTION_RETURN result_diskinfos;
-	unsigned int i, j;
-	int defined_identifiers;
-	DiskInfo *diskInfos;
-
-	result_diskinfos = getDiskInfos(NULL, &disk_num);
-	if (result_diskinfos != FUNC_RET_OK) {
-		return result_diskinfos;
-	}
-	diskInfos = (DiskInfo *)malloc(disk_num * sizeof(DiskInfo));
-	memset(diskInfos, 0, disk_num * sizeof(DiskInfo));
-	result_diskinfos = getDiskInfos(diskInfos, &disk_num);
-	if (result_diskinfos != FUNC_RET_OK) {
-		free(diskInfos);
-		return result_diskinfos;
-	}
-	for (i = 0; i < disk_num; i++) {
-		char firstChar = use_label ? diskInfos[i].label[0] : diskInfos[i].disk_sn[0];
-		available_disk_info += firstChar == 0 ? 0 : 1;
-	}
-
-	defined_identifiers = *num_identifiers;
-	*num_identifiers = available_disk_info;
-	if (identifiers == NULL) {
-		free(diskInfos);
-		return FUNC_RET_OK;
-	} else if (available_disk_info > defined_identifiers) {
-		free(diskInfos);
-		return FUNC_RET_BUFFER_TOO_SMALL;
-	}
-
-	j = 0;
-	for (i = 0; i < disk_num; i++) {
-		if (use_label) {
-			if (diskInfos[i].label[0] != 0) {
-				memset(identifiers[j], 0, sizeof(PcIdentifier));  //!!!!!!!
-				strncpy((char *)identifiers[j], diskInfos[i].label, sizeof(PcIdentifier));
-				j++;
-			}
-		} else {
-			if (diskInfos[i].disk_sn[0] != 0) {
-				memcpy(identifiers[j], &diskInfos[i].disk_sn[2], sizeof(PcIdentifier));
-				j++;
-			}
-		}
-	}
-	free(diskInfos);
-	return FUNC_RET_OK;
+	return FUNC_RET_NOT_AVAIL;
 }
 
 /**
@@ -194,7 +107,7 @@
  * @return
  */
 
-FUNCTION_RETURN generate_pc_id(PcIdentifier *identifiers, unsigned int *array_size, IDENTIFICATION_STRATEGY strategy) {
+FUNCTION_RETURN generate_pc_id(PcIdentifier *identifiers, unsigned int *array_size, LCC_IDENTIFICATION_STRATEGY strategy) {
 	FUNCTION_RETURN result;
 	unsigned int i, j;
 	const unsigned int original_array_size = *array_size;
@@ -278,7 +191,7 @@
 
 FUNCTION_RETURN parity_check_id(PcSignature pc_identifier) { return FUNC_RET_OK; }
 
-FUNCTION_RETURN generate_user_pc_signature(PcSignature identifier_out, IDENTIFICATION_STRATEGY strategy) {
+FUNCTION_RETURN generate_user_pc_signature(PcSignature identifier_out, LCC_IDENTIFICATION_STRATEGY strategy) {
 	FUNCTION_RETURN result;
 	PcIdentifier *identifiers;
 	unsigned int req_buffer_size = 0;
@@ -336,14 +249,14 @@
 	return FUNC_RET_OK;
 }
 
-static IDENTIFICATION_STRATEGY strategy_from_pc_id(PcIdentifier identifier) {
-	return (IDENTIFICATION_STRATEGY)identifier[0] >> 5;
+static LCC_IDENTIFICATION_STRATEGY strategy_from_pc_id(PcIdentifier identifier) {
+	return (LCC_IDENTIFICATION_STRATEGY)identifier[0] >> 5;
 }
 
-EVENT_TYPE validate_pc_signature(PcSignature str_code) {
+LCC_EVENT_TYPE validate_pc_signature(PcSignature str_code) {
 	PcIdentifier user_identifiers[2];
 	FUNCTION_RETURN result;
-	IDENTIFICATION_STRATEGY previous_strategy_id, current_strategy_id;
+	LCC_IDENTIFICATION_STRATEGY previous_strategy_id, current_strategy_id;
 	PcIdentifier *calculated_identifiers = NULL;
 	unsigned int calc_identifiers_size = 0;
 	int i = 0, j = 0;
diff --git a/src/library/pc_identifier/pc-identifiers.h b/src/library/pc_identifier/pc-identifiers.h
index 4c4c86f..d7d3b14 100644
--- a/src/library/pc_identifier/pc-identifiers.h
+++ b/src/library/pc_identifier/pc-identifiers.h
@@ -15,13 +15,12 @@
 #endif
 #include "../base/base.h"
 
-typedef unsigned char PcIdentifier[6];
-typedef char PcSignature[API_PC_IDENTIFIER_SIZE + 1];
+typedef char PcSignature[LCC_API_PC_IDENTIFIER_SIZE + 1];
 
 FUNCTION_RETURN generate_pc_id(PcIdentifier * identifiers, unsigned int * array_size,
-		IDENTIFICATION_STRATEGY strategy);
+		LCC_IDENTIFICATION_STRATEGY strategy);
 
-EVENT_TYPE validate_pc_signature(PcSignature str_code);
+LCC_EVENT_TYPE validate_pc_signature(PcSignature str_code);
 
 /**
  * Generates an UserPcIdentifier.
@@ -30,7 +29,7 @@
  * @param strategy
  * @return
  */
-FUNCTION_RETURN generate_user_pc_signature(PcSignature identifier_out, IDENTIFICATION_STRATEGY strategy);
+FUNCTION_RETURN generate_user_pc_signature(PcSignature identifier_out, LCC_IDENTIFICATION_STRATEGY strategy);
 
 #ifdef __cplusplus
 }
diff --git a/src/library/pc_identifier/pc_identifier.cpp b/src/library/pc_identifier/pc_identifier.cpp
index e9dc59c..e4e5860 100644
--- a/src/library/pc_identifier/pc_identifier.cpp
+++ b/src/library/pc_identifier/pc_identifier.cpp
@@ -22,8 +22,8 @@
 
 PcIdentifier::PcIdentifier(const PcIdentifier& other) : m_data(other.m_data) {}
 
-void PcIdentifier::set_identification_strategy(IDENTIFICATION_STRATEGY strategy) {
-	if (strategy == STRATEGY_UNKNOWN || strategy == STRATEGY_DEFAULT) {
+void PcIdentifier::set_identification_strategy(LCC_API_IDENTIFICATION_STRATEGY strategy) {
+	if (strategy == STRATEGY_NONE || strategy == STRATEGY_DEFAULT) {
 		throw logic_error("Only known strategies are permitted");
 	}
 	uint8_t stratMov = (strategy << 5);
@@ -55,4 +55,8 @@
 	return result;
 }
 
+LCC_API_IDENTIFICATION_STRATEGY PcIdentifier::get_identification_strategy() const {}
+
+bool PcIdentifier::data_match(const std::array<uint8_t, 6>& data) const {}
 } /* namespace license */
+
diff --git a/src/library/pc_identifier/pc_identifier.hpp b/src/library/pc_identifier/pc_identifier.hpp
index f3587bb..01856c3 100644
--- a/src/library/pc_identifier/pc_identifier.hpp
+++ b/src/library/pc_identifier/pc_identifier.hpp
@@ -13,9 +13,10 @@
 #include <iostream>
 #include <string>
 
+#include <licensecc_properties.h>
 #include "../../../include/licensecc/datatypes.h"
 #include "../os/execution_environment.hpp"
-
+#include "../os/cpu_info.hpp"
 namespace license {
 
 /**
@@ -45,13 +46,14 @@
 	PcIdentifier(const std::string &param);
 	virtual ~PcIdentifier();
 	PcIdentifier(const PcIdentifier &other);
-	void set_identification_strategy(IDENTIFICATION_STRATEGY strategy);
-	IDENTIFICATION_STRATEGY get_identification_strategy() const;
+	void set_identification_strategy(LCC_API_IDENTIFICATION_STRATEGY strategy);
+	LCC_API_IDENTIFICATION_STRATEGY get_identification_strategy() const;
 	void set_use_environment_var(bool use_env_var);
 	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;
 	std::string print() const;
 	friend std::ostream &operator<<(std::ostream &output, const PcIdentifier &d) {
 		output << d.print();
diff --git a/src/library/pc_identifier/pc_identifier_facade.cpp b/src/library/pc_identifier/pc_identifier_facade.cpp
index 46263f6..1e0e93c 100644
--- a/src/library/pc_identifier/pc_identifier_facade.cpp
+++ b/src/library/pc_identifier/pc_identifier_facade.cpp
@@ -4,27 +4,88 @@
  *  Created on: Dec 26, 2019
  *      Author: devel
  */
-#include <unordered_map>
-#include <bits/unique_ptr.h>
 
 #include "pc_identifier_facade.hpp"
-#include "identification_strategy.hpp"
-#include "pc_identifier.hpp"
+
+#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 "pc_identifier.hpp"
+
 namespace license {
+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)));
 
-std::unordered_map<IDENTIFICATION_STRATEGY, std::unique_ptr<IdentificationStrategy>> STRATEGY_MAP;
+	return strategy_map;
+}
 
-EVENT_TYPE PcIdentifierFacade::validate_pc_signature(const std::string& str_code) {
+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);
-	IDENTIFICATION_STRATEGY id_strategy = pc_id.get_identification_strategy();
+	LCC_API_IDENTIFICATION_STRATEGY id_strategy = pc_id.get_identification_strategy();
 	auto it = STRATEGY_MAP.find(id_strategy);
-	EVENT_TYPE result = IDENTIFIERS_MISMATCH;
+	LCC_EVENT_TYPE result = IDENTIFIERS_MISMATCH;
 	if (it != STRATEGY_MAP.end()) {
 		result = it->second->validate_identifier(pc_id);
+	} else {
+		// TODO: log
 	}
 	return result;
 }
 
-std::string PcIdentifierFacade::generate_user_pc_signature(IDENTIFICATION_STRATEGY strategy) { PcIdentifier pc_id; }
+std::string PcIdentifierFacade::generate_user_pc_signature(LCC_API_IDENTIFICATION_STRATEGY strategy) {
+	bool use_env_var = false;
+	if (strategy == STRATEGY_DEFAULT) {
+		char* env_var_value = getenv(LCC_IDENTIFICATION_STRATEGY_ENV_VAR);
+		if (env_var_value != nullptr && env_var_value[0] != '\0') {
+			int strategy_int = atoi(env_var_value);
+			if (strategy_int < 0 || strategy_int > 3) {
+				LOG_WARN("unknown " LCC_IDENTIFICATION_STRATEGY_ENV_VAR " %s", env_var_value);
+			} else {
+				strategy = (LCC_API_IDENTIFICATION_STRATEGY)strategy_int;
+				use_env_var = true;
+			}
+		}
+	}
+	auto it = STRATEGY_MAP.find(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");
+	}
+	ExecutionEnvironment exec;
+	VIRTUALIZATION virtualization = exec.getVirtualization();
+	pc_id.set_virtual_environment(virtualization);
+	pc_id.set_use_environment_var(use_env_var);
+	if (virtualization != NONE) {
+		bool isCloud = exec.is_cloud();
+		if (isCloud) {
+			pc_id.set_cloud_provider(exec.getCloudProvider());
+		} else {
+			CpuInfo cpu;
+			pc_id.set_virtualization(cpu.getVirtualizationDetail());
+		}
+	}
+	return pc_id.print();
+}
 } /* namespace license */
diff --git a/src/library/pc_identifier/pc_identifier_facade.hpp b/src/library/pc_identifier/pc_identifier_facade.hpp
index 0d54332..02b2d0e 100644
--- a/src/library/pc_identifier/pc_identifier_facade.hpp
+++ b/src/library/pc_identifier/pc_identifier_facade.hpp
@@ -8,7 +8,11 @@
 #ifndef SRC_LIBRARY_PC_IDENTIFIER_PC_IDENTIFIER_FACADE_HPP_
 #define SRC_LIBRARY_PC_IDENTIFIER_PC_IDENTIFIER_FACADE_HPP_
 #include <string>
+#include <unordered_map>
+#include <bits/unique_ptr.h>
 #include <licensecc/datatypes.h>
+#include "pc_identifier_facade.hpp"
+#include "identification_strategy.hpp"
 
 namespace license {
 class PcIdentifierFacade {
@@ -16,8 +20,9 @@
 	PcIdentifierFacade(){};
 	virtual ~PcIdentifierFacade(){};
 public:
-	static EVENT_TYPE validate_pc_signature(const std::string& str_code);
-	static std::string generate_user_pc_signature(IDENTIFICATION_STRATEGY strategy);
+	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 license */
diff --git a/src/templates/licensecc_properties.h.in b/src/templates/licensecc_properties.h.in
index 6839823..402d91f 100644
--- a/src/templates/licensecc_properties.h.in
+++ b/src/templates/licensecc_properties.h.in
@@ -1,19 +1,74 @@
 #ifndef BUILD_PROPERTIES_H_
 #define BUILD_PROPERTIES_H_
 
+/**
+ * This file contains all the properties that are customizable on on a per-project basis eg:
+ * 1) api parameter sizes
+ * 2) 
+ *
+ * It is safe to place the values that your project need to customize here, since each project get its own copy of this
+ * file.
+ */
+
 #define LCC_PROJECT_NAME "@LCC_PROJECT_NAME@"
 
 //License retrieval configuration
 #define FIND_LICENSE_NEAR_MODULE true
 #define FIND_LICENSE_WITH_ENV_VAR false
 
-#define LICENSE_FILE_EXTENSION ".lic"
-#define LICENSE_LOCATION_ENV_VAR "LICENSE_LOCATION"
-#define LICENSE_DATA_ENV_VAR "LICENSE_DATA"
+/**
+ * License file name extension
+ */
+#define LCC_LICENSE_FILE_EXTENSION ".lic"
+#define LCC_LICENSE_LOCATION_ENV_VAR "LICENSE_LOCATION"
+#define LCC_LICENSE_DATA_ENV_VAR "LICENSE_DATA"
+/**
+ * Environment variable that if defined will change the identification strategy used to generate the pc identifier.
+ * If a client has an unstable pc-identifier use this variable to generate one. 
+ * Valid values are integers defined in `LCC_IDENTIFICATION_STRATEGY` enum.
+ */
+#define LCC_IDENTIFICATION_STRATEGY_ENV_VAR "IDENTIFICATION_STRATEGY"
 
-//Internal data structures limits
-#define MAX_LICENSE_LENGTH 256 * 1024
+/**
+ * Enum to select a specific pc identification_strategy. DEFAULT Should be used in most cases.
+ */
+typedef enum {
+	STRATEGY_DEFAULT = -1,
+	STRATEGY_ETHERNET = 0,
+	STRATEGY_IP_ADDRESS = 1,
+	STRATEGY_DISK_NUM = 2,
+	STRATEGY_DISK_LABEL = 3,
+	STRATEGY_MEMORY_CPU_SIZE = 4,
+	STRATEGY_HOST_NAME = 5,
+	STRATEGY_NONE = -2
+} LCC_API_IDENTIFICATION_STRATEGY;
 
-#define VERIFY_MAGIC (lic_info.m_magic == @LCC_PROJECT_MAGIC_NUM@)
+//strategies used for each virtual environment.
+#define LCC_BARE_TO_METAL_STRATEGIES { STRATEGY_ETHERNET, STRATEGY_DISK_LABEL, STRATEGY_NONE }
+#define LCC_VM_STRATEGIES { STRATEGY_ETHERNET, STRATEGY_NONE }
+#define LCC_LXC_STRATEGIES { STRATEGY_ETHERNET, STRATEGY_NONE }
+#define LCC_DOCKER_STRATEGIES { STRATEGY_NONE }
+#define LCC_CLOUD_STRATEGIES { STRATEGY_NONE }
+
+//Api structure limits
+/**
+ * Maximum size of a license file or base64 data
+ */
+#define LCC_API_MAX_LICENSE_DATA_LENGTH 1024 * 4
+
+// define api structure sizes
+#define LCC_API_PC_IDENTIFIER_SIZE 19
+#define LCC_API_PROPRIETARY_DATA_SIZE 16
+#define LCC_API_AUDIT_EVENT_NUM 5
+#define LCC_API_AUDIT_EVENT_PARAM2 255
+#define LCC_API_VERSION_LENGTH 15
+#define LCC_API_PROJECT_NAME_SIZE 15
+#define LCC_API_EXPIRY_DATE_SIZE 10
+#define LCC_API_ERROR_BUFFER_SIZE 256
+
+/**
+This definition allows to specify a custom expression to verify the magic number passed in by the api.
+*/
+#define LCC_VERIFY_MAGIC (lic_info.m_magic == @LCC_PROJECT_MAGIC_NUM@)
 
 #endif
diff --git a/test/functional/crack_test.cpp b/test/functional/crack_test.cpp
index bb437d7..fcf6143 100644
--- a/test/functional/crack_test.cpp
+++ b/test/functional/crack_test.cpp
@@ -30,7 +30,7 @@
 	std::copy(licLocation.begin(), licLocation.end(), location.licenseData);
 	// magic should be 0 for this build...
 	CallerInformations callInfo{{0}, {0}, 42};
-	const EVENT_TYPE result = acquire_license(&callInfo, &location, &license);
+	const LCC_EVENT_TYPE result = acquire_license(&callInfo, &location, &license);
 	BOOST_CHECK_EQUAL(result, LICENSE_CORRUPTED);
 }
 
diff --git a/test/functional/date_test.cpp b/test/functional/date_test.cpp
index 83462df..999331c 100644
--- a/test/functional/date_test.cpp
+++ b/test/functional/date_test.cpp
@@ -27,7 +27,7 @@
 	LicenseLocation location = {LICENSE_PATH};
 	std::copy(licLocation.begin(), licLocation.end(), location.licenseData);
 
-	const EVENT_TYPE result = acquire_license(nullptr, &location, &license);
+	const LCC_EVENT_TYPE result = acquire_license(nullptr, &location, &license);
 	BOOST_CHECK_EQUAL(result, LICENSE_OK);
 	BOOST_CHECK_EQUAL(license.has_expiry, true);
 	BOOST_CHECK_EQUAL(license.linked_to_pc, false);
@@ -44,7 +44,7 @@
 	LicenseLocation location = {LICENSE_PATH};
 	std::copy(licLocation.begin(), licLocation.end(), location.licenseData);
 	BOOST_TEST_MESSAGE("before acquire license");
-	const EVENT_TYPE result = acquire_license(nullptr, &location, &license);
+	const LCC_EVENT_TYPE result = acquire_license(nullptr, &location, &license);
 	BOOST_CHECK_EQUAL(result, PRODUCT_EXPIRED);
 	BOOST_CHECK_EQUAL(license.has_expiry, true);
 	BOOST_CHECK_EQUAL(license.linked_to_pc, false);
diff --git a/test/functional/standard-license_test.cpp b/test/functional/standard-license_test.cpp
index 6d55de8..1ef1081 100644
--- a/test/functional/standard-license_test.cpp
+++ b/test/functional/standard-license_test.cpp
@@ -27,7 +27,7 @@
 	LicenseInfo license;
 	LicenseLocation location = {LICENSE_PATH};
 	std::copy(licLocation.begin(), licLocation.end(), location.licenseData);
-	const EVENT_TYPE result = acquire_license(nullptr, &location, &license);
+	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, false);
@@ -45,7 +45,7 @@
 	LicenseInfo license;
 	LicenseLocation location = {LICENSE_PLAIN_DATA};
 	std::copy(license_data.begin(), license_data.end(), location.licenseData);
-	const EVENT_TYPE result = acquire_license(nullptr, &location, &license);
+	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, false);
diff --git a/test/functional/volid_test.cpp b/test/functional/volid_test.cpp
index b6a808a..14144df 100644
--- a/test/functional/volid_test.cpp
+++ b/test/functional/volid_test.cpp
@@ -25,7 +25,7 @@
 BOOST_AUTO_TEST_CASE(default_volid_lic_file) {
 	PcSignature identifier_out;
 
-	const IDENTIFICATION_STRATEGY strategy = IDENTIFICATION_STRATEGY::STRATEGY_ETHERNET;
+	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");
@@ -40,13 +40,13 @@
 	LicenseInfo license;
 	LicenseLocation location = {LICENSE_PATH};
 	std::copy(licLocation.begin(), licLocation.end(), location.licenseData);
-	const EVENT_TYPE result = acquire_license(nullptr, &location, &license);
+	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);
 }
 
-static void generate_reference_file(const string &idfileLocation, IDENTIFICATION_STRATEGY strategies[],
+static void generate_reference_file(const string &idfileLocation, LCC_API_IDENTIFICATION_STRATEGY strategies[],
 									int num_strategies) {
 	ofstream idfile(idfileLocation);
 	PcSignature identifier_out;
@@ -64,7 +64,7 @@
 
 BOOST_AUTO_TEST_CASE(generated_identifiers_stability) {
 	const string idfileLocation(PROJECT_TEST_TEMP_DIR "/identifiers_file");
-	std::vector<IDENTIFICATION_STRATEGY> strategies;
+	std::vector<LCC_API_IDENTIFICATION_STRATEGY> strategies;
 	size_t disk_num;
 	getDiskInfos(NULL, &disk_num);
 	if (disk_num > 0) {
@@ -122,7 +122,7 @@
 			if (reference_signatures[i] == "0000-0000-0000-0000") continue;
 			PcSignature pcsig;
 			strncpy(pcsig, reference_signatures[i].c_str(), sizeof(PcSignature) - 1);
-			EVENT_TYPE val_result = validate_pc_signature(pcsig);
+			LCC_EVENT_TYPE val_result = validate_pc_signature(pcsig);
 			BOOST_TEST_CHECKPOINT("Verifying signature: ");
 			BOOST_CHECK_EQUAL(val_result, LICENSE_OK);
 		}
diff --git a/test/library/LicenseLocator_test.cpp b/test/library/LicenseLocator_test.cpp
index 65c225a..99032a7 100644
--- a/test/library/LicenseLocator_test.cpp
+++ b/test/library/LicenseLocator_test.cpp
@@ -132,9 +132,9 @@
 	// an application can define multiple license locations separated by ';'
 	const char *environment_variable_value = MOCK_LICENSE ";/this/one/doesnt/exist";
 #ifdef _WIN32
-	_putenv_s(LICENSE_LOCATION_ENV_VAR, environment_variable_value);
+	_putenv_s(LCC_LICENSE_LOCATION_ENV_VAR, environment_variable_value);
 #else
-	setenv(LICENSE_LOCATION_ENV_VAR, environment_variable_value, 1);
+	setenv(LCC_LICENSE_LOCATION_ENV_VAR, environment_variable_value, 1);
 #endif
 	// read test license
 	std::ifstream src(MOCK_LICENSE, std::ios::binary);
@@ -149,7 +149,7 @@
 	BOOST_CHECK_MESSAGE(string(MOCK_LICENSE).compare(currentLocation) == 0, "file found at expected location");
 	string licenseRealContent = envVarLocationStrategy.retrieve_license_content(currentLocation);
 	BOOST_CHECK_MESSAGE(referenceContent.compare(licenseRealContent) == 0, "File content is same");
-	UNSETENV(LICENSE_LOCATION_ENV_VAR);
+	UNSETENV(LCC_LICENSE_LOCATION_ENV_VAR);
 }
 
 /**
@@ -157,7 +157,7 @@
  */
 BOOST_AUTO_TEST_CASE(environment_var_location_not_found) {
 	const char *environment_variable_value = PROJECT_TEST_SRC_DIR "/this/file/doesnt/exist";
-	SETENV(LICENSE_LOCATION_ENV_VAR, environment_variable_value);
+	SETENV(LCC_LICENSE_LOCATION_ENV_VAR, environment_variable_value);
 
 	license::EventRegistry registry;
 	EnvironmentVarLocation envVarLocationStrategy;
@@ -167,14 +167,14 @@
 	BOOST_REQUIRE_MESSAGE(!registry.isGood(), "Error detected");
 	BOOST_CHECK_EQUAL(0, licenseInfos.size());
 	BOOST_CHECK_MESSAGE(registry.getLastFailure()->event_type == LICENSE_FILE_NOT_FOUND, "Error detected");
-	UNSETENV(LICENSE_LOCATION_ENV_VAR);
+	UNSETENV(LCC_LICENSE_LOCATION_ENV_VAR);
 }
 
 /**
  * The license file doesn't exist. Check that the locator reports the right error
  */
 BOOST_AUTO_TEST_CASE(environment_var_location_not_defined) {
-	UNSETENV(LICENSE_LOCATION_ENV_VAR);
+	UNSETENV(LCC_LICENSE_LOCATION_ENV_VAR);
 	license::EventRegistry registry;
 	EnvironmentVarLocation environmentVarLocation;
 	vector<string> licenseInfos = environmentVarLocation.license_locations(registry);
diff --git a/test/library/LicenseReader_test.cpp b/test/library/LicenseReader_test.cpp
index 57ed1dc..f573874 100644
--- a/test/library/LicenseReader_test.cpp
+++ b/test/library/LicenseReader_test.cpp
@@ -75,7 +75,7 @@
  * Test the error code if the license default environment variable isn't specified
  */
 BOOST_AUTO_TEST_CASE(env_var_not_defined) {
-	UNSETENV(LICENSE_LOCATION_ENV_VAR);
+	UNSETENV(LCC_LICENSE_LOCATION_ENV_VAR);
 	locate::LocatorFactory::find_license_near_module(false);
 	locate::LocatorFactory::find_license_with_env_var(true);
 	LicenseReader licenseReader(nullptr);
@@ -94,7 +94,7 @@
  */
 BOOST_AUTO_TEST_CASE(env_var_point_to_wrong_file) {
 	const char *environment_variable_value = PROJECT_TEST_SRC_DIR "/this/file/doesnt/exist";
-	SETENV(LICENSE_LOCATION_ENV_VAR, environment_variable_value)
+	SETENV(LCC_LICENSE_LOCATION_ENV_VAR, environment_variable_value)
 	locate::LocatorFactory::find_license_near_module(false);
 	locate::LocatorFactory::find_license_with_env_var(true);
 
@@ -106,7 +106,7 @@
 	BOOST_CHECK_EQUAL(0, licenseInfos.size());
 	BOOST_ASSERT(registry.getLastFailure() != NULL);
 	BOOST_CHECK_EQUAL(LICENSE_FILE_NOT_FOUND, registry.getLastFailure()->event_type);
-	UNSETENV(LICENSE_LOCATION_ENV_VAR);
+	UNSETENV(LCC_LICENSE_LOCATION_ENV_VAR);
 }
 }  // namespace test
 }  // namespace license

--
Gitblit v1.9.1