Files
strongswan-ext/src/libpts/pts/components/pts_component_manager.c
T

316 lines
7.4 KiB
C

/*
* Copyright (C) 2011 Andreas Steffen
*
* HSR Hochschule fuer Technik Rapperswil
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the
* Free Software Foundation; either version 2 of the License, or (at your
* option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
*
* This program is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
*/
#include "pts/components/pts_component_manager.h"
#include <utils/linked_list.h>
#include <debug.h>
typedef struct private_pts_component_manager_t private_pts_component_manager_t;
typedef struct vendor_entry_t vendor_entry_t;
typedef struct component_entry_t component_entry_t;
#define PTS_QUALIFIER_SIZE 6
/**
* Vendor-specific namespace information and list of registered components
*/
struct vendor_entry_t {
/**
* Vendor ID
*/
pen_t vendor_id;
/**
* Vendor-specific Component Functional names
*/
enum_name_t *comp_func_names;
/**
* Vendor-specific Qualifier Type names
*/
enum_name_t *qualifier_type_names;
/**
* Vendor-specific Qualifier Flag names
*/
char *qualifier_flag_names;
/**
* Vendor-specific size of Qualfiier Type field
*/
int qualifier_type_size;
/**
* List of vendor-specific registered Functional Components
*/
linked_list_t *components;
};
/**
* Destroy a vendor_entry_t object
*/
static void vendor_entry_destroy(vendor_entry_t *entry)
{
entry->components->destroy_function(entry->components, free);
free(entry);
}
/**
* Creation method for a vendor-specific Functional Component
*/
struct component_entry_t {
/**
* Vendor-Specific Component Functional Name
*/
u_int32_t name;
/**
* Functional Component creation method
*/
pts_component_create_t create;
};
/**
* Private data of a pts_component_manager_t object.
*
*/
struct private_pts_component_manager_t {
/**
* Public pts_component_manager_t interface.
*/
pts_component_manager_t public;
/**
* List of vendor-specific namespaces and registered components
*/
linked_list_t *list;
};
METHOD(pts_component_manager_t, add_vendor, void,
private_pts_component_manager_t *this, pen_t vendor_id,
enum_name_t *comp_func_names, int qualifier_type_size,
char *qualifier_flag_names, enum_name_t *qualifier_type_names)
{
vendor_entry_t *entry;
entry = malloc_thing(vendor_entry_t);
entry->vendor_id = vendor_id;
entry->comp_func_names = comp_func_names;
entry->qualifier_type_size = qualifier_type_size;
entry->qualifier_flag_names = qualifier_flag_names;
entry->qualifier_type_names = qualifier_type_names;
entry->components = linked_list_create();
this->list->insert_last(this->list, entry);
DBG2(DBG_TNC, "added %N functional component namespace",
pen_names, vendor_id);
}
METHOD(pts_component_manager_t, get_comp_func_names, enum_name_t*,
private_pts_component_manager_t *this, pen_t vendor_id)
{
enumerator_t *enumerator;
vendor_entry_t *entry;
enum_name_t *names = NULL;
enumerator = this->list->create_enumerator(this->list);
while (enumerator->enumerate(enumerator, &entry))
{
if (entry->vendor_id == vendor_id)
{
names = entry->comp_func_names;
break;
}
}
enumerator->destroy(enumerator);
return names;
}
METHOD(pts_component_manager_t, get_qualifier_type_names, enum_name_t*,
private_pts_component_manager_t *this, pen_t vendor_id)
{
enumerator_t *enumerator;
vendor_entry_t *entry;
enum_name_t *names = NULL;
enumerator = this->list->create_enumerator(this->list);
while (enumerator->enumerate(enumerator, &entry))
{
if (entry->vendor_id == vendor_id)
{
names = entry->qualifier_type_names;
break;
}
}
enumerator->destroy(enumerator);
return names;
}
METHOD(pts_component_manager_t, add_component, void,
private_pts_component_manager_t *this, pen_t vendor_id, u_int32_t name,
pts_component_create_t create)
{
enumerator_t *enumerator;
vendor_entry_t *entry;
component_entry_t *component;
enumerator = this->list->create_enumerator(this->list);
while (enumerator->enumerate(enumerator, &entry))
{
if (entry->vendor_id == vendor_id)
{
component = malloc_thing(component_entry_t);
component->name = name;
component->create = create;
entry->components->insert_last(entry->components, component);
DBG2(DBG_TNC, "added %N functional component \"%N\"",
pen_names, vendor_id,
get_comp_func_names(this, vendor_id), name);
}
}
enumerator->destroy(enumerator);
}
METHOD(pts_component_manager_t, remove_vendor, void,
private_pts_component_manager_t *this, pen_t vendor_id)
{
enumerator_t *enumerator;
vendor_entry_t *entry;
enumerator = this->list->create_enumerator(this->list);
while (enumerator->enumerate(enumerator, &entry))
{
if (entry->vendor_id == vendor_id)
{
this->list->remove_at(this->list, enumerator);
vendor_entry_destroy(entry);
DBG2(DBG_TNC, "removed %N functional component namespace",
pen_names, vendor_id);
}
}
enumerator->destroy(enumerator);
}
METHOD(pts_component_manager_t, get_qualifier, u_int8_t,
private_pts_component_manager_t *this, pts_comp_func_name_t *name,
char *flags)
{
enumerator_t *enumerator;
vendor_entry_t *entry;
u_int8_t qualifier, size, flag, type = 0;
int i;
enumerator = this->list->create_enumerator(this->list);
while (enumerator->enumerate(enumerator, &entry))
{
if (entry->vendor_id == name->get_vendor_id(name))
{
qualifier = name->get_qualifier(name);
size = entry->qualifier_type_size;
flag = (1 << size);
/* mask qualifier type field */
type = qualifier & (flag - 1);
/* determine flags */
size = PTS_QUALIFIER_SIZE - size;
if (flags)
{
for (i = 0 ; i < size; i++)
{
flags[size-i-1] = (qualifier & flag) ?
entry->qualifier_flag_names[i] : '.';
flag <<= 1;
}
flags[size] = '\0';
}
}
}
enumerator->destroy(enumerator);
return type;
}
METHOD(pts_component_manager_t, create, pts_component_t*,
private_pts_component_manager_t *this, pts_comp_func_name_t *name)
{
enumerator_t *enumerator, *e2;
vendor_entry_t *entry;
component_entry_t *entry2;
pts_component_t *component = NULL;
enumerator = this->list->create_enumerator(this->list);
while (enumerator->enumerate(enumerator, &entry))
{
if (entry->vendor_id == name->get_vendor_id(name))
{
e2 = entry->components->create_enumerator(entry->components);
while (e2->enumerate(e2, &entry2))
{
if (entry2->name == name->get_name(name) && entry2->create)
{
component = entry2->create(name->get_qualifier(name));
break;
}
}
e2->destroy(e2);
break;
}
}
enumerator->destroy(enumerator);
return component;
}
METHOD(pts_component_manager_t, destroy, void,
private_pts_component_manager_t *this)
{
this->list->destroy_function(this->list, (void *)vendor_entry_destroy);
free(this);
}
/**
* See header
*/
pts_component_manager_t *pts_component_manager_create(void)
{
private_pts_component_manager_t *this;
INIT(this,
.public = {
.add_vendor = _add_vendor,
.add_component = _add_component,
.remove_vendor = _remove_vendor,
.get_comp_func_names = _get_comp_func_names,
.get_qualifier_type_names = _get_qualifier_type_names,
.get_qualifier = _get_qualifier,
.create = _create,
.destroy = _destroy,
},
.list = linked_list_create(),
);
return &this->public;
}