Der dynamische Daten Adapter verwaltet die dynamischen Daten aller Lizenzcontainer. Bei den dynamischen Daten handelt es sich um verschlüsselte Binärdaten, die persistent gespeichert werden müssen (z.B. Flash, EEPROM, Datei). Sie enthalten unter anderem Unit Counter, Usage Period und einen aktuellen Zeitstempel.
size_t act_adapter_get_security_counter(struct ACT_ADAPTER *adapter,
uint16_t mask, uint32_t license_serial);
WibuBool act_adapter_increment_security_counter(struct ACT_ADAPTER * adapter,
uint16_t mask, uint32_t license_serial);
WibuBool act_adapter_write_dynamic_data(struct ACT_ADAPTER * adapter,
uint16_t mask,
uint32_t license_serial,
int slot, const void* data_ptr, size_t data_size);
size_t act_adapter_get_dynamic_data_size(struct ACT_ADAPTER * adapter,
uint16_t mask,
uint32_t license_serial,
int slot);
size_t act_adapter_read_dynamic_data(struct ACT_ADAPTER * adapter,
uint16_t mask,
uint32_t license_serial,
int slot,
void* dyn_data,
size_t dyn_data_size);
WibuBool act_adapter_is_dynamic_data_available(struct ACT_ADAPTER * adapter,
uint16_t mask, uint32_t serial, int slot);
Jeder Lizenzcontainer benötigt zwei Stellen an denen die Daten abwechselnd geschrieben werden (s.Toggle Mechanismus). Falls die dynamischen Daten in Dateien gespeichert werden ist es ratsam zwei Dateien pro Lizenzcontainer zu verwalten.
Toggle Mechanismus
Der Toggle Mechanismus schreibt die dynamischen Daten abwechselnd an verschiedene Stellen. Hierdurch sind immer der aktuelle und vorherige Zustand der Lizenz verfügbar. Wenn nun die aktuellen dynamischen Daten unabsichtlich oder absichtlich beschädigt werden kann auf das Backup zurückgegriffen werden. Der aktuelle Zustand ist zwar verloren, jedoch kann die Lizenz weiter genutzt werden ohne sie neu aktivieren zu müssen. Der Toggle Mechanismus basiert auf einem Zähler, dem sogenannten Security Counter, der vor unbefugten Schreibzugriffen geschützt werden muss.
Laden
Die CmActLicense Implementierung fordert nur die Ladefunktion des Adapters als feste Abhängigkeit. Die weiter Funktionalität wird per Funktionszeiger genutzt.
struct ACT_ADAPTER* act_adapter_dynamic_data_load_impl(struct ACT_ADAPTER_LOAD_DESCR const *load_descr)
{
struct ACT_ADAPTER *adapter = NULL;
/* check if there is an adapter available for firm code and plugin name combination */
if (dynamic_data_adapter_available(load_descr)) {
adapter = /* allocate dynamic or static memory for adapter object */;
if (adapter != NULL) {
adapter->type = ACT_ADAPTER_DYNAMIC_DATA;
adapter->is_dyn_allocated = /* depending on how the adapter object was allocated */;
adapter->f_init = act_adapter_generic_init;
adapter->f_deinit = act_adapter_generic_deinit;
adapter->f_unload = unload;
adapter->u.dynamic_data.f_dynamic_data_available = dynamic_data_available;
adapter->u.dynamic_data.f_get_security_counter = get_security_counter;
adapter->u.dynamic_data.f_increment_security_counter = increment_security_counter;
adapter->u.dynamic_data.f_write_dynamic_data = write_dynamic_data;
adapter->u.dynamic_data.f_get_dynamic_data_size = get_dynamic_data_size;
adapter->u.dynamic_data.f_read_dynamic_data = read_dynamic_data;
}
}
return adapter;
}
Prüfen ob die dynamischen Daten verfügbar sind
CmEmbedded prüft über die Funktion act_adapter_is_dynamic_data_available ob die dynamische Daten einer Lizenz vorhanden sind.
static WibuBool dynamic_data_available(struct ACT_ADAPTER *adapter,
uint16_t mask, uint32_t serial, int slot)
{
WibuBool ret = FALSE;
/* */
return ret;
}
Der entsprechende Funktionszeiger adapter u.dynamic_data.dynamic_data_available des Adapter Objekts muss auf die Adresse der Implementierung dynamic_data_available zeigen.
Schreiben der dynamischen Daten
Das Schreiben der dynamischen Daten wird von CmEmbedded über die Funktion act_adapter_write_dynamic_data durchgeführt.
Der entsprechende Funktionszeiger adapter u.dynamic_data.f_write_dynamic_data des Adapter Objekts muss auf die Adresse der Implementierung write_dynamic_data zeigen. Der Funktionszeiger muss in der act_adapter_dynamic_data_load_impl Funktion gesetzt werden.
static WibuBool write_dynamic_data(struct ACT_ADAPTER *adapter, uint16_t mask,
uint32_t license_serial, int slot,
const void *data_ptr, size_t data_size)
{
WibuBool ret = FALSE;
/* store dynamic data for example to flash, NVRAM or filesystem */
return ret;
}
Die Funktion bekommt ein passendes dynamische Daten Adapter Objekt, die Seriennummer und die Maske der Lizenz, die Slot Nummer (0 oder 1) und einen Zeiger auf die Daten samt der Puffergröße übergeben.
Lesen der dynamischen Daten
Das Lesen der dynamischen Daten wird von einer Funktion mit folgender Signature durchgeführt.
static size_t read_dynamic_data(struct ACT_ADAPTER *adapter, uint16_t mask,
uint32_t license_serial, int slot, void *buffer,
size_t buffer_size)
{
size_t size = 0;
/* read dynamic data for example from flash, NVRAM or filesystem */
return size;
}
Die Parameter sind identisch zur Schreibefunktion nur dass hier die dynamischen Daten in den übergebenen Puffer geschrieben werden müssen.
Um unnötige Lesezugriffe auf die dynamischen Datei zu vermeiden verwendet CmEmbedded bei der Größenermittlung der dynamischen Daten nicht die Lesefunktion sondern setzt die Implementierung der folgenden Funktion vorraus.
static size_t get_dynamic_data_size(struct ACT_ADAPTER *adapter, uint16_t mask,
uint32_t license_serial, int slot)
{
size_t size = 0;
/* determine dynamic data size for a specific license in slot */
return return size;
}
Die entsprechende Funktionszeiger u.dynamic_data.read_dynamic_data und u.dynamic_data.get_dynamic_data_size des Adapter Objekts müssen auf die Adresse der read_dynamic_data und get_dynamic_data_size Implementierungen gesetzt werden.
Schreiben und Lesen des Security Counter
Über den Security Counter Wert wird festgelegt, in welchem Slot sich die aktuellen dynamischen Daten befinden (s. Toggle Mechanismus). CmEmbedded nutzt die Funktion act_adapter_get_security_counter um den aktuellen Stand auszulesen und die Funktion act_adapter_increment_security_counter um den Security Counter Wert um eins zu erhöhen.
Beim Einlesen der dynamischen Daten muss vorher der Security Counter Wert ausgelesen werden, um den aktuellen Slot zu ermitteln. Nach einer Aktualisierung der dynamischen Daten wird der Security Counter Wert um eins erhöht.
static size_t get_security_counter(struct ACT_ADAPTER * adapter, uint16_t mask,
uint32_t license_serial)
{
size_t cnt = 0;
/* lookup security counter for specified license and return it */
return cnt;
}
static WibuBool increment_security_counter(struct ACT_ADAPTER * adapter,
uint16_t mask, uint32_t license_serial)
{
WibuBool ret = FALSE;
/* lookup and increment the security counter of one specific license */
return ret;
}
Die entsprechende Funktionszeiger u.dynamic_data.f_get_security_counter und u.dynamic_data.f_increment_security_counter des Adapter Objekts müssen auf die Adresse der beiden obigen Implementierungen gesetzt werden.