mux: overhaul by using TAI library framework

Signed-off-by: Wataru Ishida <ishida@nel-america.com>
This commit is contained in:
Wataru Ishida
2020-01-04 17:43:04 +00:00
committed by Wataru Ishida
parent 9c7351a0f1
commit 45f93cee42
11 changed files with 902 additions and 1209 deletions

View File

@@ -1,25 +1,43 @@
CC := g++
CFLAGS := -std=c++11 -fPIC
INCLUDES := -I ./oopt-tai/inc -I ./oopt-tai/meta/
PROG := libtai.so
ifndef TAI_DIR
TAI_DIR := oopt-tai
endif
ifndef TAI_LIB_DIR
TAI_LIB_DIR := $(TAI_DIR)/tools/framework
endif
ifndef TAI_META_LIBRARY
TAI_META_LIBRARY := $(TAI_DIR)/meta/libmetatai.so
endif
CFLAGS := -std=c++17 -g3 -shared -fPIC -DTAI_EXPOSE_PLATFORM -fno-gnu-unique
INCLUDES := -I $(TAI_DIR)/inc -I $(TAI_DIR)/meta -I $(TAI_LIB_DIR) -include mux.hpp
BUILDDIR := build
SRCDIR := .
SRCEXT := cpp
SOURCES := $(shell ls $(SRCDIR)/*.cpp)
OBJECTS := $(patsubst $(SRCDIR)/%,$(BUILDDIR)/%,$(SOURCES:.$(SRCEXT)=.o))
SOURCES := $(wildcard *.cpp) $(wildcard $(TAI_LIB_DIR)/*.cpp)
HEADERS := $(wildcard *.hpp) $(wildcard $(TAI_LIB_DIR)/*.hpp)
OBJECTS := $(addprefix build/,$(SOURCES:%.cpp=%.o))
DEPS := $(addprefix build/,$(SOURCES:%.cpp=%.d))
TARGET := libtai-mux.so
all: $(PROG)
all: $(TARGET)
$(PROG): $(TAI_META_LIBRARY) $(OBJECTS) $(HEADERS)
$(CXX) $(CFLAGS) $(INCLUDES) -shared $(OBJECTS) -o $@ -ldl -lpthread -L $(dir $(TAI_META_LIBRARY)) -lmetatai
oopt-tai/meta/taimetadata.h:
$(MAKE) -C ./oopt-tai/meta
$(TAI_META_LIBRARY):
$(MAKE) -C $(@D)
$(TARGET): oopt-tai/meta/taimetadata.h $(OBJECTS)
$(CC) $(CFLAGS) $(INCLUDES) -shared $^ -o $@ -ldl -lpthread -L ./oopt-tai/meta -lmetatai
$(BUILDDIR)/%.o: %.cpp Makefile
mkdir -p $(@D)
$(CXX) $(CFLAGS) $(INCLUDES) -c $< -MMD -MP -MF build/$*.d -o $@
$(BUILDDIR)/%.o: $(SRCDIR)/%.$(SRCEXT)
@mkdir -p $(BUILDDIR)
$(CC) $(CFLAGS) $(INCLUDES) -c -o $@ $<
-include $(DEPS)
clean:
-rm -r $(BUILDDIR) $(TARGET)
$(RM) -r $(BUILDDIR) $(TARGET)
bash:
TAI_DOCKER_RUN_OPTION="--privileged --net=host -it --rm" TAI_DOCKER_MOUNT="`pwd`:/data" $(MAKE) -C $(TAI_DIR) $@

View File

@@ -1,9 +1,7 @@
#include "module_adapter.hpp"
#include "exception.hpp"
#include <dlfcn.h>
#include <map>
#include <exception>
#include <sstream>
#include <iostream>
#define LOAD_TAI_API(name) \
m_ ## name = (name ## _fn) dlsym(m_dl, #name); \
@@ -11,49 +9,47 @@
throw std::runtime_error( #name " undefined");\
}
ModuleAdapter::ModuleAdapter(const std::string& name, uint64_t flags, const tai_service_method_table_t* services) : m_name(name) {
m_dl = dlopen(name.c_str(), RTLD_NOW);
if ( m_dl == nullptr ) {
throw std::runtime_error(dlerror());
}
LOAD_TAI_API(tai_api_initialize)
LOAD_TAI_API(tai_api_uninitialize)
LOAD_TAI_API(tai_api_query)
LOAD_TAI_API(tai_log_set)
LOAD_TAI_API(tai_object_type_query)
LOAD_TAI_API(tai_module_id_query)
namespace tai::mux {
std::stringstream ss;
ModuleAdapter::ModuleAdapter(const std::string& name, uint64_t flags, const tai_service_method_table_t* services) : m_name(name) {
m_dl = dlopen(name.c_str(), RTLD_NOW | RTLD_DEEPBIND);
if ( m_dl == nullptr ) {
throw std::runtime_error(dlerror());
}
LOAD_TAI_API(tai_api_initialize)
LOAD_TAI_API(tai_api_uninitialize)
LOAD_TAI_API(tai_api_query)
LOAD_TAI_API(tai_log_set)
LOAD_TAI_API(tai_object_type_query)
LOAD_TAI_API(tai_module_id_query)
auto status = tai_api_initialize(flags, services);
if ( status != TAI_STATUS_SUCCESS ) {
ss << "failed to initialize " << name << ":" << status;
throw std::runtime_error(ss.str());
auto status = tai_api_initialize(flags, services);
if ( status != TAI_STATUS_SUCCESS ) {
throw Exception(status);
}
status = tai_api_query(TAI_API_MODULE, (void **)(&m_module_api));
if ( status != TAI_STATUS_SUCCESS ) {
throw Exception(status);
}
status = tai_api_query(TAI_API_NETWORKIF, (void **)(&m_netif_api));
if ( status != TAI_STATUS_SUCCESS ) {
throw Exception(status);
}
status = tai_api_query(TAI_API_HOSTIF, (void **)(&m_hostif_api));
if ( status != TAI_STATUS_SUCCESS ) {
throw Exception(status);
}
}
status = tai_api_query(TAI_API_MODULE, (void **)(&m_module_api));
if ( status != TAI_STATUS_SUCCESS ) {
ss << "failed to query TAI_API_MODULE :" << status;
throw std::runtime_error(ss.str());
ModuleAdapter::~ModuleAdapter() {
dlclose(m_dl);
}
status = tai_api_query(TAI_API_NETWORKIF, (void **)(&m_netif_api));
if ( status != TAI_STATUS_SUCCESS ) {
ss << "failed to query TAI_API_NETWORKIF:" << status;
throw std::runtime_error(ss.str());
uint64_t ModuleAdapter::dl_address(const std::string& name) {
return (uint64_t)dlopen(name.c_str(), RTLD_NOW | RTLD_NOLOAD);
}
status = tai_api_query(TAI_API_HOSTIF, (void **)(&m_hostif_api));
if ( status != TAI_STATUS_SUCCESS ) {
ss << "failed to query TAI_API_HOSTIF:" << status;
throw std::runtime_error(ss.str());
}
}
ModuleAdapter::~ModuleAdapter() {
dlclose(m_dl);
}
uint64_t ModuleAdapter::dl_address(const std::string& name) {
return (uint64_t)dlopen(name.c_str(), RTLD_NOW | RTLD_NOLOAD);
}

View File

@@ -1,181 +1,211 @@
#ifndef __MODULE_ADAPTER_HPP__
#define __MODULE_ADAPTER_HPP__
#include <string>
#include "tai.h"
#include <string>
#include <memory>
typedef tai_status_t (*tai_api_initialize_fn) (uint64_t, const tai_service_method_table_t *);
typedef tai_status_t (*tai_api_uninitialize_fn) (void);
typedef tai_status_t (*tai_api_query_fn) (tai_api_t, void**);
typedef tai_status_t (*tai_log_set_fn) (tai_api_t, tai_log_level_t, tai_log_fn);
typedef tai_object_type_t (*tai_object_type_query_fn) (tai_object_id_t);
typedef tai_object_id_t (*tai_module_id_query_fn) (tai_object_id_t);
namespace tai::mux {
// corresponds to one dynamic library
class ModuleAdapter {
public:
ModuleAdapter(const std::string& name, uint64_t flags, const tai_service_method_table_t* services);
~ModuleAdapter();
static uint64_t dl_address(const std::string& name);
typedef tai_status_t (*tai_api_initialize_fn) (uint64_t, const tai_service_method_table_t *);
typedef tai_status_t (*tai_api_uninitialize_fn) (void);
typedef tai_status_t (*tai_api_query_fn) (tai_api_t, void**);
typedef tai_status_t (*tai_log_set_fn) (tai_api_t, tai_log_level_t, tai_log_fn);
typedef tai_object_type_t (*tai_object_type_query_fn) (tai_object_id_t);
typedef tai_object_id_t (*tai_module_id_query_fn) (tai_object_id_t);
tai_status_t tai_api_initialize(uint64_t flags, const tai_service_method_table_t* services) {
return m_tai_api_initialize(flags, services);
}
tai_status_t tai_api_query(tai_api_t tai_api_id, void** api_method_table) {
return m_tai_api_query(tai_api_id, api_method_table);
}
tai_status_t tai_api_uninitialize(void) {
return m_tai_api_uninitialize();
}
tai_status_t tai_log_set(tai_api_t tai_api_id, tai_log_level_t log_level, tai_log_fn log_fn) {
return m_tai_log_set(tai_api_id, log_level, log_fn);
}
tai_object_type_t tai_object_type_query(tai_object_id_t tai_object_id) {
return m_tai_object_type_query(tai_object_id);
}
tai_object_id_t tai_module_id_query(tai_object_id_t tai_object_id) {
return m_tai_module_id_query(tai_object_id);
}
// corresponds to one dynamic library
class ModuleAdapter {
public:
ModuleAdapter(const std::string& name, uint64_t flags, const tai_service_method_table_t* services);
~ModuleAdapter();
static uint64_t dl_address(const std::string& name);
tai_status_t create_module(
_Out_ tai_object_id_t *module_id,
_In_ uint32_t attr_count,
_In_ const tai_attribute_t *attr_list) {
if ( m_module_api == nullptr || m_module_api->create_module == nullptr ) {
return TAI_STATUS_FAILURE;
tai_status_t tai_api_initialize(uint64_t flags, const tai_service_method_table_t* services) {
return m_tai_api_initialize(flags, services);
}
return m_module_api->create_module(module_id, attr_count, attr_list);
}
tai_status_t remove_module(
_In_ tai_object_id_t module_id) {
if ( m_module_api == nullptr || m_module_api->remove_module == nullptr ) {
return TAI_STATUS_FAILURE;
tai_status_t tai_api_query(tai_api_t tai_api_id, void** api_method_table) {
return m_tai_api_query(tai_api_id, api_method_table);
}
return m_module_api->remove_module(module_id);
}
tai_status_t set_module_attributes(
_In_ tai_object_id_t module_id,
_In_ uint32_t attr_count,
_In_ const tai_attribute_t *attr_list) {
if ( m_module_api == nullptr || m_module_api->set_module_attributes == nullptr ) {
return TAI_STATUS_FAILURE;
tai_status_t tai_api_uninitialize(void) {
return m_tai_api_uninitialize();
}
return m_module_api->set_module_attributes(module_id, attr_count, attr_list);
}
tai_status_t get_module_attributes(
_In_ tai_object_id_t module_id,
_In_ uint32_t attr_count,
_In_ tai_attribute_t *attr_list) {
if ( m_module_api == nullptr || m_module_api->get_module_attributes == nullptr ) {
return TAI_STATUS_FAILURE;
tai_status_t tai_log_set(tai_api_t tai_api_id, tai_log_level_t log_level, tai_log_fn log_fn) {
return m_tai_log_set(tai_api_id, log_level, log_fn);
}
return m_module_api->get_module_attributes(module_id, attr_count, attr_list);
}
tai_status_t create_network_interface(
_Out_ tai_object_id_t *network_interface_id,
_In_ tai_object_id_t module_id,
_In_ uint32_t attr_count,
_In_ const tai_attribute_t *attr_list) {
if ( m_netif_api == nullptr || m_netif_api->create_network_interface == nullptr ) {
return TAI_STATUS_FAILURE;
tai_object_type_t tai_object_type_query(tai_object_id_t tai_object_id) {
return m_tai_object_type_query(tai_object_id);
}
return m_netif_api->create_network_interface(network_interface_id, module_id, attr_count, attr_list);
}
tai_status_t remove_network_interface(
_In_ tai_object_id_t network_interface_id) {
if ( m_netif_api == nullptr || m_netif_api->remove_network_interface == nullptr ) {
return TAI_STATUS_FAILURE;
tai_object_id_t tai_module_id_query(tai_object_id_t tai_object_id) {
return m_tai_module_id_query(tai_object_id);
}
return m_netif_api->remove_network_interface(network_interface_id);
}
tai_status_t set_network_interface_attributes(
_In_ tai_object_id_t network_interface_id,
_In_ uint32_t attr_count,
_In_ const tai_attribute_t *attr_list) {
if ( m_netif_api == nullptr || m_netif_api->set_network_interface_attributes == nullptr ) {
return TAI_STATUS_FAILURE;
tai_status_t set_attributes(tai_object_type_t type, tai_object_id_t oid, uint32_t count, const tai_attribute_t *list) {
switch (type) {
case TAI_OBJECT_TYPE_MODULE:
return set_module_attributes(oid, count, list);
case TAI_OBJECT_TYPE_NETWORKIF:
return set_network_interface_attributes(oid, count, list);
case TAI_OBJECT_TYPE_HOSTIF:
return set_host_interface_attributes(oid, count, list);
}
return TAI_STATUS_NOT_SUPPORTED;
}
return m_netif_api->set_network_interface_attributes(network_interface_id, attr_count, attr_list);
}
tai_status_t get_network_interface_attributes(
_In_ tai_object_id_t network_interface_id,
_In_ uint32_t attr_count,
_In_ tai_attribute_t *attr_list) {
if ( m_netif_api == nullptr || m_netif_api->get_network_interface_attributes == nullptr ) {
return TAI_STATUS_FAILURE;
tai_status_t get_attributes(tai_object_type_t type, tai_object_id_t oid, uint32_t count, tai_attribute_t *list) {
switch (type) {
case TAI_OBJECT_TYPE_MODULE:
return get_module_attributes(oid, count, list);
case TAI_OBJECT_TYPE_NETWORKIF:
return get_network_interface_attributes(oid, count, list);
case TAI_OBJECT_TYPE_HOSTIF:
return get_host_interface_attributes(oid, count, list);
}
return TAI_STATUS_NOT_SUPPORTED;
}
return m_netif_api->get_network_interface_attributes(network_interface_id, attr_count, attr_list);
}
tai_status_t create_host_interface(
_Out_ tai_object_id_t *host_interface_id,
_In_ tai_object_id_t module_id,
_In_ uint32_t attr_count,
_In_ const tai_attribute_t *attr_list) {
if ( m_hostif_api == nullptr || m_hostif_api->create_host_interface == nullptr ) {
return TAI_STATUS_FAILURE;
tai_status_t create_module(
_Out_ tai_object_id_t *module_id,
_In_ uint32_t attr_count,
_In_ const tai_attribute_t *attr_list) {
if ( m_module_api == nullptr || m_module_api->create_module == nullptr ) {
return TAI_STATUS_FAILURE;
}
return m_module_api->create_module(module_id, attr_count, attr_list);
}
return m_hostif_api->create_host_interface(host_interface_id, module_id, attr_count, attr_list);
}
tai_status_t remove_host_interface(
_In_ tai_object_id_t host_interface_id) {
if ( m_hostif_api == nullptr || m_hostif_api->remove_host_interface == nullptr ) {
return TAI_STATUS_FAILURE;
tai_status_t remove_module(
_In_ tai_object_id_t module_id) {
if ( m_module_api == nullptr || m_module_api->remove_module == nullptr ) {
return TAI_STATUS_FAILURE;
}
return m_module_api->remove_module(module_id);
}
return m_hostif_api->remove_host_interface(host_interface_id);
}
tai_status_t set_host_interface_attributes(
_In_ tai_object_id_t host_interface_id,
_In_ uint32_t attr_count,
_In_ const tai_attribute_t *attr_list) {
if ( m_hostif_api == nullptr || m_hostif_api->set_host_interface_attributes == nullptr ) {
return TAI_STATUS_FAILURE;
tai_status_t set_module_attributes(
_In_ tai_object_id_t module_id,
_In_ uint32_t attr_count,
_In_ const tai_attribute_t *attr_list) {
if ( m_module_api == nullptr || m_module_api->set_module_attributes == nullptr ) {
return TAI_STATUS_FAILURE;
}
return m_module_api->set_module_attributes(module_id, attr_count, attr_list);
}
return m_hostif_api->set_host_interface_attributes(host_interface_id, attr_count, attr_list);
}
tai_status_t get_host_interface_attributes(
_In_ tai_object_id_t host_interface_id,
_In_ uint32_t attr_count,
_In_ tai_attribute_t *attr_list) {
if ( m_hostif_api == nullptr || m_hostif_api->get_host_interface_attributes == nullptr ) {
return TAI_STATUS_FAILURE;
tai_status_t get_module_attributes(
_In_ tai_object_id_t module_id,
_In_ uint32_t attr_count,
_In_ tai_attribute_t *attr_list) {
if ( m_module_api == nullptr || m_module_api->get_module_attributes == nullptr ) {
return TAI_STATUS_FAILURE;
}
return m_module_api->get_module_attributes(module_id, attr_count, attr_list);
}
return m_hostif_api->get_host_interface_attributes(host_interface_id, attr_count, attr_list);
}
tai_status_t clear_host_interface_attributes(
_In_ tai_object_id_t host_interface_id,
_In_ uint32_t attr_count,
_In_ tai_attr_id_t *attr_list) {
if ( m_hostif_api == nullptr || m_hostif_api->clear_host_interface_attributes == nullptr ) {
return TAI_STATUS_FAILURE;
tai_status_t create_network_interface(
_Out_ tai_object_id_t *network_interface_id,
_In_ tai_object_id_t module_id,
_In_ uint32_t attr_count,
_In_ const tai_attribute_t *attr_list) {
if ( m_netif_api == nullptr || m_netif_api->create_network_interface == nullptr ) {
return TAI_STATUS_FAILURE;
}
return m_netif_api->create_network_interface(network_interface_id, module_id, attr_count, attr_list);
}
return m_hostif_api->clear_host_interface_attributes(host_interface_id, attr_count, attr_list);
}
private:
void* m_dl;
const std::string& m_name;
tai_api_initialize_fn m_tai_api_initialize;
tai_api_uninitialize_fn m_tai_api_uninitialize;
tai_api_query_fn m_tai_api_query;
tai_log_set_fn m_tai_log_set;
tai_object_type_query_fn m_tai_object_type_query;
tai_module_id_query_fn m_tai_module_id_query;
tai_status_t remove_network_interface(
_In_ tai_object_id_t network_interface_id) {
if ( m_netif_api == nullptr || m_netif_api->remove_network_interface == nullptr ) {
return TAI_STATUS_FAILURE;
}
return m_netif_api->remove_network_interface(network_interface_id);
}
tai_status_t set_network_interface_attributes(
_In_ tai_object_id_t network_interface_id,
_In_ uint32_t attr_count,
_In_ const tai_attribute_t *attr_list) {
if ( m_netif_api == nullptr || m_netif_api->set_network_interface_attributes == nullptr ) {
return TAI_STATUS_FAILURE;
}
return m_netif_api->set_network_interface_attributes(network_interface_id, attr_count, attr_list);
}
tai_status_t get_network_interface_attributes(
_In_ tai_object_id_t network_interface_id,
_In_ uint32_t attr_count,
_In_ tai_attribute_t *attr_list) {
if ( m_netif_api == nullptr || m_netif_api->get_network_interface_attributes == nullptr ) {
return TAI_STATUS_FAILURE;
}
return m_netif_api->get_network_interface_attributes(network_interface_id, attr_count, attr_list);
}
tai_status_t create_host_interface(
_Out_ tai_object_id_t *host_interface_id,
_In_ tai_object_id_t module_id,
_In_ uint32_t attr_count,
_In_ const tai_attribute_t *attr_list) {
if ( m_hostif_api == nullptr || m_hostif_api->create_host_interface == nullptr ) {
return TAI_STATUS_FAILURE;
}
return m_hostif_api->create_host_interface(host_interface_id, module_id, attr_count, attr_list);
}
tai_status_t remove_host_interface(
_In_ tai_object_id_t host_interface_id) {
if ( m_hostif_api == nullptr || m_hostif_api->remove_host_interface == nullptr ) {
return TAI_STATUS_FAILURE;
}
return m_hostif_api->remove_host_interface(host_interface_id);
}
tai_status_t set_host_interface_attributes(
_In_ tai_object_id_t host_interface_id,
_In_ uint32_t attr_count,
_In_ const tai_attribute_t *attr_list) {
if ( m_hostif_api == nullptr || m_hostif_api->set_host_interface_attributes == nullptr ) {
return TAI_STATUS_FAILURE;
}
return m_hostif_api->set_host_interface_attributes(host_interface_id, attr_count, attr_list);
}
tai_status_t get_host_interface_attributes(
_In_ tai_object_id_t host_interface_id,
_In_ uint32_t attr_count,
_In_ tai_attribute_t *attr_list) {
if ( m_hostif_api == nullptr || m_hostif_api->get_host_interface_attributes == nullptr ) {
return TAI_STATUS_FAILURE;
}
return m_hostif_api->get_host_interface_attributes(host_interface_id, attr_count, attr_list);
}
tai_status_t clear_host_interface_attributes(
_In_ tai_object_id_t host_interface_id,
_In_ uint32_t attr_count,
_In_ tai_attr_id_t *attr_list) {
if ( m_hostif_api == nullptr || m_hostif_api->clear_host_interface_attributes == nullptr ) {
return TAI_STATUS_FAILURE;
}
return m_hostif_api->clear_host_interface_attributes(host_interface_id, attr_count, attr_list);
}
private:
void* m_dl;
const std::string& m_name;
tai_api_initialize_fn m_tai_api_initialize;
tai_api_uninitialize_fn m_tai_api_uninitialize;
tai_api_query_fn m_tai_api_query;
tai_log_set_fn m_tai_log_set;
tai_object_type_query_fn m_tai_object_type_query;
tai_module_id_query_fn m_tai_module_id_query;
tai_module_api_t* m_module_api;
tai_host_interface_api_t* m_hostif_api;
tai_network_interface_api_t* m_netif_api;
};
using S_ModuleAdapter = std::shared_ptr<ModuleAdapter>;
tai_module_api_t* m_module_api;
tai_host_interface_api_t* m_hostif_api;
tai_network_interface_api_t* m_netif_api;
};
#endif

View File

@@ -2,499 +2,227 @@
#include <iostream>
#include "taimetadata.h"
Multiplexier *g_mux;
namespace tai::mux {
static const tai_attribute_value_t * find_attribute_in_list(
_In_ tai_attr_id_t attr_id,
_In_ uint32_t attr_count,
_In_ const tai_attribute_t *attr_list)
{
while (attr_count--) {
if (attr_list->id == attr_id) {
return &attr_list->value;
}
attr_list++;
}
return nullptr;
}
tai_status_t Multiplexier::create_host_interface(
_Out_ tai_object_id_t *host_interface_id,
_In_ tai_object_id_t module_id,
_In_ uint32_t attr_count,
_In_ const tai_attribute_t *attr_list) {
tai_object_id_t m_id;
ModuleAdapter *m_adapter;
if ( g_mux == nullptr ) {
return TAI_STATUS_UNINITIALIZED;
}
if ( g_mux->get_mapping(module_id, &m_adapter, &m_id) != 0 ) {
return TAI_STATUS_FAILURE;
}
tai_object_id_t id;
auto ret = m_adapter->create_host_interface(&id, m_id, attr_count, attr_list);
if ( ret != TAI_STATUS_SUCCESS ) {
return ret;
}
if ( g_mux->create_mapping(host_interface_id, m_adapter, id) != 0 ) {
return TAI_STATUS_FAILURE;
}
return TAI_STATUS_SUCCESS;
}
tai_status_t Multiplexier::remove_host_interface(
_In_ tai_object_id_t host_interface_id) {
tai_object_id_t id;
ModuleAdapter *m_adapter;
if ( g_mux == nullptr ) {
return TAI_STATUS_UNINITIALIZED;
}
if ( g_mux->get_mapping(host_interface_id, &m_adapter, &id) != 0 ) {
return TAI_STATUS_FAILURE;
}
auto ret = m_adapter->remove_host_interface(id);
if ( ret != TAI_STATUS_SUCCESS ) {
return ret;
}
if ( g_mux->remove_mapping(host_interface_id) != 0 ) {
return TAI_STATUS_FAILURE;
}
return TAI_STATUS_SUCCESS;
}
tai_status_t Multiplexier::set_host_interface_attributes(_In_ tai_object_id_t host_interface_id,
_In_ uint32_t attr_count,
_In_ const tai_attribute_t *attr_list) {
return set_attributes(&ModuleAdapter::set_host_interface_attributes, host_interface_id, attr_count, attr_list);
}
tai_status_t Multiplexier::get_host_interface_attributes(_In_ tai_object_id_t host_interface_id,
_In_ uint32_t attr_count,
_Out_ tai_attribute_t *attr_list) {
return get_attributes(&ModuleAdapter::get_host_interface_attributes, host_interface_id, attr_count, attr_list);
}
tai_status_t Multiplexier::clear_host_interface_attributes(_In_ tai_object_id_t host_interface_id,
_In_ uint32_t attr_count,
_Out_ tai_attr_id_t *attr_list) {
tai_object_id_t id;
ModuleAdapter *m_adapter;
if ( g_mux == nullptr ) {
return TAI_STATUS_UNINITIALIZED;
}
if ( g_mux->get_mapping(host_interface_id, &m_adapter, &id) != 0 ) {
return TAI_STATUS_FAILURE;
}
return m_adapter->clear_host_interface_attributes(id, attr_count, attr_list);
}
tai_status_t Multiplexier::create_network_interface(
_Out_ tai_object_id_t *network_interface_id,
_In_ tai_object_id_t module_id,
_In_ uint32_t attr_count,
_In_ const tai_attribute_t *attr_list) {
tai_object_id_t m_id;
ModuleAdapter *m_adapter;
if ( g_mux == nullptr ) {
return TAI_STATUS_UNINITIALIZED;
}
if ( g_mux->get_mapping(module_id, &m_adapter, &m_id) != 0 ) {
return TAI_STATUS_FAILURE;
}
tai_object_id_t id;
auto ret = m_adapter->create_network_interface(&id, m_id, attr_count, attr_list);
if ( ret != TAI_STATUS_SUCCESS ) {
return ret;
}
if ( g_mux->create_mapping(network_interface_id, m_adapter, id) != 0 ) {
return TAI_STATUS_FAILURE;
}
return TAI_STATUS_SUCCESS;
}
tai_status_t Multiplexier::remove_network_interface(
_In_ tai_object_id_t network_interface_id) {
tai_object_id_t id;
ModuleAdapter *m_adapter;
if ( g_mux == nullptr ) {
return TAI_STATUS_UNINITIALIZED;
}
if ( g_mux->get_mapping(network_interface_id, &m_adapter, &id) != 0 ) {
return TAI_STATUS_FAILURE;
}
auto ret = m_adapter->remove_network_interface(id);
if ( ret != TAI_STATUS_SUCCESS ) {
return ret;
}
if ( g_mux->remove_mapping(network_interface_id) != 0 ) {
return TAI_STATUS_FAILURE;
}
return TAI_STATUS_SUCCESS;
}
tai_status_t Multiplexier::set_network_interface_attributes(_In_ tai_object_id_t network_interface_id,
_In_ uint32_t attr_count,
_In_ const tai_attribute_t *attr_list) {
return set_attributes(&ModuleAdapter::set_network_interface_attributes, network_interface_id, attr_count, attr_list);
}
tai_status_t Multiplexier::get_network_interface_attributes(_In_ tai_object_id_t network_interface_id,
_In_ uint32_t attr_count,
_Out_ tai_attribute_t *attr_list) {
return get_attributes(&ModuleAdapter::get_network_interface_attributes, network_interface_id, attr_count, attr_list);
}
tai_status_t Multiplexier::create_module(
_Out_ tai_object_id_t *module_id,
_In_ uint32_t attr_count,
_In_ const tai_attribute_t *attr_list) {
if ( g_mux == nullptr ) {
return TAI_STATUS_UNINITIALIZED;
}
auto mod_addr = find_attribute_in_list(TAI_MODULE_ATTR_LOCATION, attr_count, attr_list);
if ( mod_addr == nullptr ) {
return TAI_STATUS_MANDATORY_ATTRIBUTE_MISSING;
}
const std::string location(mod_addr->charlist.list);
auto m_adapter = g_mux->get_module_adapter(location);
if ( m_adapter == nullptr ) {
return TAI_STATUS_FAILURE;
}
tai_object_id_t id;
auto ret = m_adapter->create_module(&id, attr_count, attr_list);
if ( ret != TAI_STATUS_SUCCESS ) {
return ret;
}
if ( g_mux->create_mapping(module_id, m_adapter, id) != 0 ) {
return TAI_STATUS_FAILURE;
}
return TAI_STATUS_SUCCESS;
}
tai_status_t Multiplexier::remove_module(_In_ tai_object_id_t module_id) {
tai_object_id_t id;
ModuleAdapter *m_adapter;
if ( g_mux == nullptr ) {
return TAI_STATUS_UNINITIALIZED;
}
if ( g_mux->get_mapping(module_id, &m_adapter, &id) != 0 ) {
return TAI_STATUS_FAILURE;
}
auto ret = m_adapter->remove_module(id);
if ( ret != TAI_STATUS_SUCCESS ) {
return ret;
}
if ( g_mux->remove_mapping(module_id) != 0 ) {
return TAI_STATUS_FAILURE;
}
return TAI_STATUS_SUCCESS;
}
tai_status_t Multiplexier::set_module_attributes(_In_ tai_object_id_t module_id,
_In_ uint32_t attr_count,
_In_ const tai_attribute_t *attr_list) {
return set_attributes(&ModuleAdapter::set_module_attributes, module_id, attr_count, attr_list);
}
tai_status_t Multiplexier::get_module_attributes(_In_ tai_object_id_t module_id,
_In_ uint32_t attr_count,
_Out_ tai_attribute_t *attr_list) {
return get_attributes(&ModuleAdapter::get_module_attributes, module_id, attr_count, attr_list);
}
tai_object_type_t Multiplexier::object_type_query(_In_ tai_object_id_t id) {
tai_object_id_t realid;
ModuleAdapter *m_adapter;
if ( g_mux == nullptr ) {
return TAI_OBJECT_TYPE_NULL;
}
if ( g_mux->get_mapping(id, &m_adapter, &realid) != 0 ) {
return TAI_OBJECT_TYPE_NULL;
}
return m_adapter->tai_object_type_query(realid);
}
tai_object_id_t Multiplexier::module_id_query(_In_ tai_object_id_t id) {
tai_object_id_t realid;
ModuleAdapter *m_adapter;
if ( g_mux == nullptr ) {
return TAI_NULL_OBJECT_ID;
}
if ( g_mux->get_mapping(id, &m_adapter, &realid) != 0 ) {
return TAI_NULL_OBJECT_ID;
}
return g_mux->get_reverse_mapping(m_adapter->tai_module_id_query(realid), m_adapter);
}
tai_status_t Multiplexier::tai_log_set(_In_ tai_api_t api, _In_ tai_log_level_t level, _In_ tai_log_fn log_fn) {
if ( g_mux == nullptr ) {
return TAI_STATUS_UNINITIALIZED;
}
auto set = m_pa->list_module_adapters();
for ( const auto& a : set ) {
auto ret = a->tai_log_set(api, level, log_fn);
if ( ret != TAI_STATUS_SUCCESS ) {
return ret;
}
}
return TAI_STATUS_SUCCESS;
}
void notification_callback(void* context, tai_object_id_t oid, uint32_t attr_count, tai_attribute_t const * const attr_list) {
if ( context == nullptr || attr_list == nullptr ) {
return;
}
auto ctx = static_cast<notification_context*>(context);
ctx->mux->notify(ctx, oid, attr_count, attr_list);
}
void Multiplexier::notify(notification_context* ctx, tai_object_id_t real_oid, uint32_t attr_count, tai_attribute_t const * const attr_list) {
auto oid = get_reverse_mapping(real_oid, ctx->adapter);
if ( oid == TAI_NULL_OBJECT_ID ) {
return;
}
auto t = object_type_query(oid);
std::vector<tai_attribute_t> attrs;
tai_attribute_t dst;
const tai_attr_metadata_t *meta;
for ( int i = 0; i < attr_count; i++ ) {
auto src = attr_list[i];
meta = tai_metadata_get_attr_metadata(t, src.id);
if ( meta == nullptr ) {
continue;
}
tai_alloc_info_t info;
info.reference = &src;
dst.id = src.id;
if ( tai_metadata_alloc_attr_value(meta, &dst, &info) != 0 ) {
return;
}
if ( tai_metadata_deepcopy_attr_value(meta, &src, &dst) != 0 ) {
goto err;
}
if ( convert_oid(oid, &dst, &dst, true) != TAI_STATUS_SUCCESS ) {
goto err;
}
attrs.emplace_back(dst);
}
static const std::string PLATFORM_ADAPTER = "TAI_MUX_PLATFORM_ADAPTER";
static const tai_attribute_value_t * find_attribute_in_list(
_In_ tai_attr_id_t attr_id,
_In_ uint32_t attr_count,
_In_ const tai_attribute_t *attr_list)
{
std::unique_lock<std::mutex> lk(ctx->mutex);
ctx->handler.notify(ctx->handler.context, oid, attrs.size(), attrs.data());
}
for ( auto a : attrs ) {
auto meta = tai_metadata_get_attr_metadata(t, a.id);
tai_metadata_free_attr_value(meta, &a, nullptr);
}
return;
err:
tai_metadata_free_attr_value(meta, &dst, nullptr);
for ( auto a : attrs ) {
meta = tai_metadata_get_attr_metadata(t, a.id);
tai_metadata_free_attr_value(meta, &a, nullptr);
}
}
tai_status_t Multiplexier::set_attributes( std::function<tai_status_t(ModuleAdapter*, tai_object_id_t, uint32_t, const tai_attribute_t*)> f, tai_object_id_t oid, uint32_t attr_count, const tai_attribute_t *attr_list) {
tai_object_id_t id;
ModuleAdapter *m_adapter;
tai_status_t ret;
if ( g_mux == nullptr ) {
return TAI_STATUS_UNINITIALIZED;
}
if ( g_mux->get_mapping(oid, &m_adapter, &id) != 0 ) {
return TAI_STATUS_FAILURE;
}
std::vector<tai_attribute_t> attrs;
tai_alloc_info_t info;
auto t = object_type_query(oid);
std::vector<notification_key> n_to_clear;
for ( auto i = 0; i < attr_count; i++ ) {
auto meta = tai_metadata_get_attr_metadata(t, attr_list[i].id);
if ( meta == nullptr ) {
goto err;
}
tai_attribute_t attr;
attr.id = attr_list[i].id;
info.reference = &attr_list[i];
if ( tai_metadata_alloc_attr_value(meta, &attr, &info) != 0 ) {
goto err;
}
if ( tai_metadata_deepcopy_attr_value(meta, &attr_list[i], &attr) != 0 ) {
goto err;
}
ret = convert_oid(oid, &attr, &attr, false);
if ( ret != TAI_STATUS_SUCCESS ) {
goto err;
}
attrs.emplace_back(attr);
// we can't delete m_notification_map[key] before calling f() since
// the adapter can still call the notification callback.
// store the keys to be removed into n_to_clear and delete them after calling f()
if ( meta->attrvaluetype == TAI_ATTR_VALUE_TYPE_NOTIFICATION && attr.value.notification.notify == nullptr ) {
n_to_clear.emplace_back(notification_key(oid, attr.id));
}
}
ret = f(m_adapter, id, attrs.size(), attrs.data());
for ( auto& key : n_to_clear ) {
delete m_notification_map[key];
m_notification_map.erase(key);
}
err:
if ( free_attributes(t, attrs) < 0 ) {
return TAI_STATUS_FAILURE;
}
return ret;
}
tai_status_t Multiplexier::get_attributes( std::function<tai_status_t(ModuleAdapter*, tai_object_id_t, uint32_t, tai_attribute_t*)> f, tai_object_id_t oid, uint32_t attr_count, tai_attribute_t *attr_list) {
tai_object_id_t id;
ModuleAdapter *m_adapter;
if ( g_mux == nullptr ) {
return TAI_STATUS_UNINITIALIZED;
}
if ( g_mux->get_mapping(oid, &m_adapter, &id) != 0 ) {
return TAI_STATUS_FAILURE;
}
auto ret = f(m_adapter, id, attr_count, attr_list);
if ( ret != TAI_STATUS_SUCCESS ) {
return ret;
}
auto t = object_type_query(oid);
for ( auto i = 0; i < attr_count; i++ ) {
ret = convert_oid(oid, &attr_list[i], &attr_list[i], true);
if ( ret != TAI_STATUS_SUCCESS ) {
return ret;
}
}
return TAI_STATUS_SUCCESS;
}
tai_status_t Multiplexier::convert_oid(tai_object_id_t oid, const tai_attribute_t *src, tai_attribute_t *dst, bool reversed) {
ModuleAdapter* adapter;
auto t = object_type_query(oid);
if ( g_mux->get_mapping(oid, &adapter, nullptr) != 0 ) {
return TAI_STATUS_FAILURE;
}
auto meta = tai_metadata_get_attr_metadata(t, src->id);
const tai_object_map_list_t *oml;
auto convert = [&](tai_object_id_t s) -> tai_object_id_t {
if ( reversed ) {
return g_mux->get_reverse_mapping(s, adapter);
}
tai_object_id_t oid;
if ( g_mux->get_mapping(s, nullptr, &oid) < 0 ) {
return TAI_NULL_OBJECT_ID;
}
return oid;
};
auto key = notification_key(oid, src->id);
switch (meta->attrvaluetype) {
case TAI_ATTR_VALUE_TYPE_OID:
dst->value.oid = convert(src->value.oid);
if ( dst->value.oid == TAI_NULL_OBJECT_ID ) {
return TAI_STATUS_FAILURE;
}
break;
case TAI_ATTR_VALUE_TYPE_OBJLIST:
for ( auto i = 0 ; i < src->value.objlist.count; i++ ) {
dst->value.objlist.list[i] = convert(src->value.objlist.list[i]);
if ( dst->value.objlist.list[i] == TAI_NULL_OBJECT_ID ) {
return TAI_STATUS_FAILURE;
while (attr_count--) {
if (attr_list->id == attr_id) {
return &attr_list->value;
}
attr_list++;
}
break;
case TAI_ATTR_VALUE_TYPE_OBJMAPLIST:
oml = &src->value.objmaplist;
for ( auto i = 0 ; i < oml->count; i++ ) {
dst->value.objmaplist.list[i].key = convert(oml->list[i].key);
if ( dst->value.objmaplist.list[i].key == TAI_NULL_OBJECT_ID ) {
return TAI_STATUS_FAILURE;
}
for ( auto j = 0; j < oml->list[i].value.count; j++ ) {
dst->value.objmaplist.list[i].value.list[j] = convert(oml->list[i].value.list[j]);
if ( dst->value.objmaplist.list[i].value.list[j] == TAI_NULL_OBJECT_ID ) {
return TAI_STATUS_FAILURE;
}
}
}
break;
case TAI_ATTR_VALUE_TYPE_NOTIFICATION:
if ( reversed ) {
if ( m_notification_map.find(key) != m_notification_map.end() ) {
auto n = m_notification_map[key];
dst->value.notification.context = n->handler.context;
dst->value.notification.notify = n->handler.notify;
}
} else {
if ( src->value.notification.notify != nullptr ) {
if ( m_notification_map.find(key) == m_notification_map.end() ) {
m_notification_map[key] = new notification_context();
}
auto n = m_notification_map[key];
std::unique_lock<std::mutex> lk(n->mutex);
n->mux = this;
n->adapter = adapter;
n->handler = src->value.notification;
n->notify_id = src->id;
dst->value.notification.context = n;
dst->value.notification.notify = notification_callback;
}
}
}
return TAI_STATUS_SUCCESS;
}
int Multiplexier::free_attributes(tai_object_type_t t, std::vector<tai_attribute_t>& attributes) {
for ( auto a : attributes ) {
auto meta = tai_metadata_get_attr_metadata(t, a.id);
tai_metadata_free_attr_value(meta, &a, nullptr);
}
return 0;
}
Multiplexier* create_mux(platform_adapter_t pa_kind, uint64_t flags, const tai_service_method_table_t* services) {
try {
return new Multiplexier(pa_kind, flags, services);
} catch (const std::runtime_error& e) {
std::cerr << e.what() << std::endl;
return nullptr;
}
}
#ifndef DEFAULT_PLATFORM_ADAPTER
#define DEFAULT_PLATFORM_ADAPTER "static"
#endif
Platform::Platform(const tai_service_method_table_t * services) : tai::Platform(services) {
auto pa = std::getenv(PLATFORM_ADAPTER.c_str());
std::string pa_name;
if ( pa == nullptr ) {
pa_name = DEFAULT_PLATFORM_ADAPTER;
} else {
pa_name = std::string(pa);
}
platform_adapter_t pa_kind;
if ( pa_name == "static" ) {
pa_kind = PLATFORM_ADAPTER_STATIC;
}
switch ( pa_kind ) {
case PLATFORM_ADAPTER_STATIC:
m_pa = std::make_shared<StaticPlatformAdapter>(0, services);
break;
default:
ERROR("unsupported platform_adapter: %s", pa_name.c_str());
throw Exception(TAI_STATUS_NOT_SUPPORTED);
}
}
tai_status_t Platform::create(tai_object_type_t type, tai_object_id_t module_id, uint32_t count, const tai_attribute_t * const list, tai_object_id_t *id) {
std::shared_ptr<tai::BaseObject> obj;
try {
switch (type) {
case TAI_OBJECT_TYPE_MODULE:
obj = std::make_shared<Module>(count, list, m_pa);
break;
case TAI_OBJECT_TYPE_NETWORKIF:
case TAI_OBJECT_TYPE_HOSTIF:
{
auto it = m_objects.find(module_id);
if ( it == m_objects.end() ) {
return TAI_STATUS_UNINITIALIZED;
}
if ( it->second->type() != TAI_OBJECT_TYPE_MODULE ) {
return TAI_STATUS_INVALID_OBJECT_ID;
}
auto module = std::dynamic_pointer_cast<Module>(it->second);
if ( type == TAI_OBJECT_TYPE_NETWORKIF ) {
obj = std::make_shared<NetIf>(module, count, list, m_pa);
} else {
obj = std::make_shared<HostIf>(module, count, list, m_pa);
}
}
break;
default:
return TAI_STATUS_NOT_SUPPORTED;
}
} catch (Exception& e) {
return e.err();
} catch (...) {
return TAI_STATUS_FAILURE;
}
auto oid = obj->id();
auto it = m_objects.find(oid);
if ( it != m_objects.end() ) {
return TAI_STATUS_ITEM_ALREADY_EXISTS;
}
m_objects[oid] = obj;
*id = oid;
return TAI_STATUS_SUCCESS;
}
tai_status_t Platform::remove(tai_object_id_t id) {
auto it = m_objects.find(id);
if ( it == m_objects.end() ) {
return TAI_STATUS_ITEM_NOT_FOUND;
}
auto type = get_object_type(id);
tai_status_t ret;
switch (type) {
case TAI_OBJECT_TYPE_MODULE:
{
auto m = std::dynamic_pointer_cast<Module>(it->second);
ret = m->remove();
}
break;
case TAI_OBJECT_TYPE_NETWORKIF:
{
auto m = std::dynamic_pointer_cast<NetIf>(it->second);
ret = m->remove();
}
break;
case TAI_OBJECT_TYPE_HOSTIF:
{
auto m = std::dynamic_pointer_cast<HostIf>(it->second);
ret = m->remove();
}
break;
default:
ret = TAI_STATUS_INVALID_OBJECT_ID;
}
if ( ret != TAI_STATUS_SUCCESS ) {
return ret;
}
m_objects.erase(it);
m_pa->remove_mapping(id);
return TAI_STATUS_SUCCESS;
}
tai_object_type_t Platform::get_object_type(tai_object_id_t id) {
auto it = m_objects.find(id);
if ( it == m_objects.end() ) {
return TAI_OBJECT_TYPE_NULL;
}
return it->second->type();
}
tai_object_id_t Platform::get_module_id(tai_object_id_t id) {
auto it = m_objects.find(id);
if ( it == m_objects.end() ) {
return TAI_NULL_OBJECT_ID;
}
switch (it->second->type()) {
case TAI_OBJECT_TYPE_MODULE:
{
auto m = std::dynamic_pointer_cast<Module>(it->second);
return m->id();
}
case TAI_OBJECT_TYPE_NETWORKIF:
{
auto m = std::dynamic_pointer_cast<NetIf>(it->second);
return m->module_id();
}
case TAI_OBJECT_TYPE_HOSTIF:
{
auto m = std::dynamic_pointer_cast<HostIf>(it->second);
return m->module_id();
}
}
return TAI_NULL_OBJECT_ID;
}
tai_status_t Platform::set_log(tai_api_t api, tai_log_level_t level, tai_log_fn log_fn) {
auto set = m_pa->list_module_adapters();
for ( const auto& a : set ) {
auto ret = a->tai_log_set(api, level, log_fn);
if ( ret != TAI_STATUS_SUCCESS ) {
return ret;
}
}
return TAI_STATUS_SUCCESS;
}
template <> const tai::AttributeInfoMap<TAI_OBJECT_TYPE_MODULE> tai::Config<TAI_OBJECT_TYPE_MODULE>::m_info {};
Module::Module(uint32_t count, const tai_attribute_t *list, S_PlatformAdapter platform) : Object(platform) {
auto mod_addr = find_attribute_in_list(TAI_MODULE_ATTR_LOCATION, count, list);
if ( mod_addr == nullptr ) {
throw Exception(TAI_STATUS_MANDATORY_ATTRIBUTE_MISSING);
}
const std::string location(mod_addr->charlist.list, mod_addr->charlist.count);
auto adapter = m_pa->get_module_adapter(location);
if ( adapter == nullptr ) {
throw Exception(TAI_STATUS_FAILURE);
}
m_adapter = adapter;
auto ret = m_adapter->create_module(&m_real_id, count, list);
if ( ret != TAI_STATUS_SUCCESS ) {
throw Exception(ret);
}
if ( platform->create_mapping(&m_id, m_adapter, m_real_id) != 0 ) {
throw Exception(TAI_STATUS_FAILURE);
}
}
template <> const tai::AttributeInfoMap<TAI_OBJECT_TYPE_NETWORKIF> tai::Config<TAI_OBJECT_TYPE_NETWORKIF>::m_info {};
NetIf::NetIf(S_Module module, uint32_t count, const tai_attribute_t *list, S_PlatformAdapter platform) : m_module(module), Object(platform) {
m_adapter = module->adapter();
if ( m_adapter == nullptr ) {
throw Exception(TAI_STATUS_FAILURE);
}
auto ret = m_adapter->create_network_interface(&m_real_id, module->real_id(), count, list);
if ( ret != TAI_STATUS_SUCCESS ) {
throw Exception(ret);
}
if ( platform->create_mapping(&m_id, m_adapter, m_real_id) != 0 ) {
throw Exception(TAI_STATUS_FAILURE);
}
}
template <> const tai::AttributeInfoMap<TAI_OBJECT_TYPE_HOSTIF> tai::Config<TAI_OBJECT_TYPE_HOSTIF>::m_info {};
HostIf::HostIf(S_Module module, uint32_t count, const tai_attribute_t *list, S_PlatformAdapter platform) : m_module(module), Object(platform) {
m_adapter = module->adapter();
if ( m_adapter == nullptr ) {
throw Exception(TAI_STATUS_FAILURE);
}
auto ret = m_adapter->create_host_interface(&m_real_id, module->real_id(), count, list);
if ( ret != TAI_STATUS_SUCCESS ) {
throw Exception(ret);
}
if ( platform->create_mapping(&m_id, m_adapter, m_real_id) != 0 ) {
throw Exception(TAI_STATUS_FAILURE);
}
}
};

View File

@@ -2,202 +2,112 @@
#define __MUX_HPP__
#include <string>
#include <exception>
#include "platform_adapter.hpp"
#include "static_platform_adapter.hpp"
#include "module_adapter.hpp"
#include "tai.h"
#include <sstream>
#include <bitset>
#include <mutex>
class OIDAllocator {
public:
tai_object_id_t next() {
// TAI_NULL_OBJECT_ID == 0, start from i = 1
for (int i = 1; i < 256; i++) {
if ( !m_bitset.test(i) ) {
m_bitset.set(i);
return tai_object_id_t(i);
#include "platform.hpp"
namespace tai::mux {
class Platform : public tai::Platform {
public:
Platform(const tai_service_method_table_t * services);
tai_status_t create(tai_object_type_t type, tai_object_id_t module_id, uint32_t count, const tai_attribute_t * const list, tai_object_id_t *id);
tai_status_t remove(tai_object_id_t id);
tai_object_type_t get_object_type(tai_object_id_t id);
tai_object_id_t get_module_id(tai_object_id_t id);
tai_status_t set_log(tai_api_t tai_api_id, tai_log_level_t log_level, tai_log_fn log_fn);
private:
S_PlatformAdapter m_pa;
};
class Module;
class NetIf;
class HostIf;
using S_Module = std::shared_ptr<Module>;
using S_NetIf = std::shared_ptr<NetIf>;
using S_HostIf = std::shared_ptr<HostIf>;
using S_ConstModule = std::shared_ptr<const Module>;
using S_ConstNetIf = std::shared_ptr<const NetIf>;
using S_ConstHostIf = std::shared_ptr<const HostIf>;
template<tai_object_type_t T>
class Object : public tai::Object<T> {
public:
Object(S_PlatformAdapter pa) : m_pa(pa), tai::Object<T>(0, nullptr, std::make_shared<tai::FSM>(), nullptr, std::bind(&Object::setter, this, std::placeholders::_1, std::placeholders::_2, std::placeholders::_3), std::bind(&Object::getter, this, std::placeholders::_1, std::placeholders::_2)) {}
tai_object_id_t id() const {
return m_id;
}
tai_object_id_t real_id() const {
return m_real_id;
}
protected:
tai_object_id_t m_id, m_real_id;
S_PlatformAdapter m_pa;
S_ModuleAdapter m_adapter;
private:
tai_status_t setter(const tai_attribute_t* const attribute, FSMState* fsm, void* const user) {
return m_pa->set(T, id(), attribute);
}
tai_status_t getter(tai_attribute_t* const attribute, void* const user) {
auto ret = m_adapter->get_attributes(T, m_real_id, 1, attribute);
if ( ret != TAI_STATUS_SUCCESS ) {
return ret;
}
return m_pa->convert_oid(T, id(), attribute, attribute, true);
}
throw std::runtime_error("OID max reach");
}
void free(tai_object_id_t oid) {
m_bitset.reset(oid);
}
private:
std::bitset<256> m_bitset;
};
class Module : public Object<TAI_OBJECT_TYPE_MODULE> {
public:
Module(uint32_t count, const tai_attribute_t *list, S_PlatformAdapter platform);
S_ModuleAdapter adapter() const {
return m_adapter;
}
tai_status_t remove() {
return m_adapter->remove_module(m_real_id);
}
};
class NetIf : public Object<TAI_OBJECT_TYPE_NETWORKIF> {
public:
NetIf(S_Module Module, uint32_t count, const tai_attribute_t *list, S_PlatformAdapter platform);
tai_status_t remove() {
return m_adapter->remove_network_interface(m_real_id);
}
tai_object_id_t module_id() {
return m_module->id();
}
private:
const S_ConstModule m_module;
};
class HostIf : public Object<TAI_OBJECT_TYPE_HOSTIF> {
public:
HostIf(S_Module Module, uint32_t count, const tai_attribute_t *list, S_PlatformAdapter platform);
tai_status_t remove() {
return m_adapter->remove_host_interface(m_real_id);
}
tai_object_id_t module_id() {
return m_module->id();
}
private:
const S_ConstModule m_module;
};
};
class Multiplexier;
struct notification_context {
Multiplexier* mux;
ModuleAdapter* adapter;
tai_notification_handler_t handler;
tai_attr_id_t notify_id;
std::mutex mutex;
};
using notification_key = std::pair<tai_object_id_t, tai_attr_id_t>;
// singleton
class Multiplexier {
public:
Multiplexier(platform_adapter_t pa_kind, uint64_t flags, const tai_service_method_table_t* services) {
switch ( pa_kind ) {
case PLATFORM_ADAPTER_STATIC:
m_pa = new StaticPlatformAdapter(flags, services);
break;
default:
std::stringstream ss;
ss << "unsupported platform_adapter :" << pa_kind;
throw std::runtime_error(ss.str());
}
}
~Multiplexier(){
if ( m_pa != nullptr ) {
delete m_pa;
}
for ( auto& n : m_notification_map ) {
delete n.second;
}
}
ModuleAdapter * get_module_adapter(const std::string& location) {
return m_pa->get_module_adapter(location);
}
void notify(notification_context* ctx, tai_object_id_t real_oid, uint32_t attr_count, tai_attribute_t const * const attr_list);
tai_status_t create_module(
_Out_ tai_object_id_t *module_id,
_In_ uint32_t attr_count,
_In_ const tai_attribute_t *attr_list);
tai_status_t remove_module(
_In_ tai_object_id_t module_id);
tai_status_t set_module_attributes(
_In_ tai_object_id_t module_id,
_In_ uint32_t attr_count,
_In_ const tai_attribute_t *attr_list);
tai_status_t get_module_attributes(
_In_ tai_object_id_t module_id,
_In_ uint32_t attr_count,
_Out_ tai_attribute_t *attr_list);
tai_status_t create_network_interface(
_Out_ tai_object_id_t *network_interface_id,
_In_ tai_object_id_t module_id,
_In_ uint32_t attr_count,
_In_ const tai_attribute_t *attr_list);
tai_status_t remove_network_interface(
_In_ tai_object_id_t network_interface_id);
tai_status_t set_network_interface_attributes(
_In_ tai_object_id_t network_interface_id,
_In_ uint32_t attr_count,
_In_ const tai_attribute_t *attr_list);
tai_status_t get_network_interface_attributes(
_In_ tai_object_id_t network_interface_id,
_In_ uint32_t attr_count,
_Out_ tai_attribute_t *attr_list);
tai_status_t create_host_interface(
_Out_ tai_object_id_t *host_interface_id,
_In_ tai_object_id_t module_id,
_In_ uint32_t attr_count,
_In_ const tai_attribute_t *attr_list);
tai_status_t remove_host_interface(
_In_ tai_object_id_t host_interface_id);
tai_status_t set_host_interface_attributes(
_In_ tai_object_id_t host_interface_id,
_In_ uint32_t attr_count,
_In_ const tai_attribute_t *attr_list);
tai_status_t get_host_interface_attributes(
_In_ tai_object_id_t host_interface_id,
_In_ uint32_t attr_count,
_Out_ tai_attribute_t *attr_list);
tai_status_t clear_host_interface_attributes(
_In_ tai_object_id_t host_interface_id,
_In_ uint32_t attr_count,
_Out_ tai_attr_id_t *attr_list);
tai_object_type_t object_type_query(
_In_ tai_object_id_t id);
tai_object_id_t module_id_query(
_In_ tai_object_id_t id);
tai_status_t tai_log_set(
_In_ tai_api_t tai_api_id,
_In_ tai_log_level_t log_level,
_In_ tai_log_fn log_fn);
private:
Multiplexier(const Multiplexier&){}
void operator = (const Multiplexier&){}
PlatformAdapter *m_pa;
std::map<tai_object_id_t, std::pair<tai_object_id_t, ModuleAdapter* >> m_map;
std::map<notification_key, notification_context*> m_notification_map;
OIDAllocator m_oid_allocator;
tai_status_t set_attributes( std::function<tai_status_t(ModuleAdapter*, tai_object_id_t, uint32_t, const tai_attribute_t*)> f, tai_object_id_t oid, uint32_t attr_count, const tai_attribute_t *attr_list);
tai_status_t get_attributes( std::function<tai_status_t(ModuleAdapter*, tai_object_id_t, uint32_t, tai_attribute_t*)> f, tai_object_id_t oid, uint32_t attr_count, tai_attribute_t *attr_list);
int get_mapping(const tai_object_id_t& id, ModuleAdapter **adapter, tai_object_id_t *real_id) {
if ( m_map.find(id) == m_map.end() ) {
return -1;
}
auto pair = m_map[id];
if ( adapter != nullptr ) {
*adapter = pair.second;
}
if ( real_id != nullptr ) {
*real_id = pair.first;
}
return 0;
};
tai_object_id_t get_reverse_mapping(const tai_object_id_t real_id, ModuleAdapter *adapter) {
for ( auto p : m_map ) {
if ( p.second.first == real_id && p.second.second == adapter ) {
return p.first;
}
}
return TAI_NULL_OBJECT_ID;
}
int create_mapping(tai_object_id_t *id, ModuleAdapter* adapter, const tai_object_id_t& real_id) {
auto value = std::pair<tai_object_id_t, ModuleAdapter*>(real_id, adapter);
*id = m_oid_allocator.next();
m_map[*id] = value;
return 0;
}
int remove_mapping(tai_object_id_t id) {
if ( m_map.find(id) == m_map.end() ) {
return 0;
}
m_map.erase(id);
m_oid_allocator.free(id);
return 0;
}
tai_status_t convert_oid(tai_object_id_t oid, const tai_attribute_t *src, tai_attribute_t *dst, bool reversed);
int free_attributes(tai_object_type_t t, std::vector<tai_attribute_t>& attributes);
};
Multiplexier* create_mux(platform_adapter_t pa_kind, uint64_t flags, const tai_service_method_table_t* services);
#ifdef TAI_EXPOSE_PLATFORM
using tai::mux::Platform;
#endif
#endif

View File

@@ -0,0 +1,152 @@
#include "platform_adapter.hpp"
#include <algorithm>
namespace tai::mux {
static void notification_callback(void* context, tai_object_id_t oid, uint32_t attr_count, tai_attribute_t const * const attr_list) {
if ( context == nullptr || attr_list == nullptr ) {
return;
}
auto ctx = static_cast<NotificationContext*>(context);
if ( ctx->pa != nullptr ) {
ctx->pa->notify(ctx, oid, attr_count, attr_list);
}
}
void PlatformAdapter::notify(NotificationContext* ctx, tai_object_id_t real_oid, uint32_t attr_count, tai_attribute_t const * const attr_list) {
auto oid = ctx->muxed_oid;
std::vector<S_Attribute> attrs;
for ( int i = 0; i < attr_count; i++ ) {
auto src = attr_list[i];
auto meta = tai_metadata_get_attr_metadata(ctx->object_type, src.id);
if ( meta == nullptr ) {
continue;
}
auto dst = std::make_shared<Attribute>(meta, src);
auto ret = convert_oid(ctx->object_type, oid, dst, dst, true);
if ( ret != TAI_STATUS_SUCCESS ) {
ERROR("failed to convert oid of attribute: %d", src.id);
continue;
}
attrs.emplace_back(dst);
}
{
std::vector<tai_attribute_t> raw_attrs;
std::transform(attrs.begin(), attrs.end(), std::back_inserter(raw_attrs), [](S_Attribute a) { return *a->raw(); });
std::unique_lock<std::mutex> lk(ctx->mutex);
ctx->real_handler.notify(ctx->real_handler.context, oid, raw_attrs.size(), raw_attrs.data());
}
}
tai_status_t PlatformAdapter::convert_oid(const tai_object_type_t& type, const tai_object_id_t& id, const S_ConstAttribute src, const S_Attribute dst, bool reversed) {
return convert_oid(type, id, src->raw(), const_cast<tai_attribute_t* const>(dst->raw()), reversed);
}
tai_status_t PlatformAdapter::convert_oid(const tai_object_type_t& type, const tai_object_id_t& id, const tai_attribute_t * const src, tai_attribute_t * const dst, bool reversed) {
auto meta = tai_metadata_get_attr_metadata(type, src->id);
const tai_object_map_list_t *oml;
S_ModuleAdapter adapter;
if ( get_mapping(id, &adapter, nullptr) != 0 ) {
return TAI_STATUS_FAILURE;
}
auto convert = [&](tai_object_id_t s) -> tai_object_id_t {
if ( reversed ) {
return get_reverse_mapping(s, adapter);
}
tai_object_id_t oid;
if ( get_mapping(s, nullptr, &oid) < 0 ) {
return TAI_NULL_OBJECT_ID;
}
return oid;
};
switch (meta->attrvaluetype) {
case TAI_ATTR_VALUE_TYPE_OID:
dst->value.oid = convert(src->value.oid);
if ( dst->value.oid == TAI_NULL_OBJECT_ID ) {
return TAI_STATUS_FAILURE;
}
break;
case TAI_ATTR_VALUE_TYPE_OBJLIST:
for ( auto i = 0 ; i < src->value.objlist.count; i++ ) {
dst->value.objlist.list[i] = convert(src->value.objlist.list[i]);
if ( dst->value.objlist.list[i] == TAI_NULL_OBJECT_ID ) {
return TAI_STATUS_FAILURE;
}
}
break;
case TAI_ATTR_VALUE_TYPE_OBJMAPLIST:
oml = &src->value.objmaplist;
for ( auto i = 0 ; i < oml->count; i++ ) {
dst->value.objmaplist.list[i].key = convert(oml->list[i].key);
if ( dst->value.objmaplist.list[i].key == TAI_NULL_OBJECT_ID ) {
return TAI_STATUS_FAILURE;
}
for ( auto j = 0; j < oml->list[i].value.count; j++ ) {
dst->value.objmaplist.list[i].value.list[j] = convert(oml->list[i].value.list[j]);
if ( dst->value.objmaplist.list[i].value.list[j] == TAI_NULL_OBJECT_ID ) {
return TAI_STATUS_FAILURE;
}
}
}
break;
case TAI_ATTR_VALUE_TYPE_NOTIFICATION:
{
auto key = notification_key(id, src->id);
if ( reversed ) {
if ( m_notification_map.find(key) != m_notification_map.end() ) {
auto n = m_notification_map[key];
dst->value.notification.context = n->real_handler.context;
dst->value.notification.notify = n->real_handler.notify;
}
break;
}
if ( src->value.notification.notify != nullptr ) {
if ( m_notification_map.find(key) == m_notification_map.end() ) {
m_notification_map[key] = std::make_shared<NotificationContext>();
}
auto n = m_notification_map[key];
std::unique_lock<std::mutex> lk(n->mutex);
n->pa = this;
n->real_handler = src->value.notification;
n->muxed_oid = id;
n->object_type = type;
dst->value.notification.context = static_cast<void*>(n.get());
dst->value.notification.notify = notification_callback;
} else {
// notification context cleanup can't be handled here since the callback can still get
// called by the underneath TAI library.
// we'll clean the context after disabling the callback
}
}
}
return TAI_STATUS_SUCCESS;
}
tai_status_t PlatformAdapter::set(const tai_object_type_t& type, const tai_object_id_t& id, const tai_attribute_t* const attribute) {
S_ModuleAdapter adapter;
tai_object_id_t real_id;
if ( get_mapping(id, &adapter, &real_id) != 0 ) {
return TAI_STATUS_FAILURE;
}
auto meta = tai_metadata_get_attr_metadata(type, attribute->id);
if ( meta == nullptr ) {
return TAI_STATUS_FAILURE;
}
auto attr = std::make_shared<Attribute>(meta, attribute);
auto ret = convert_oid(type, id, attribute, const_cast<tai_attribute_t* const>(attr->raw()), false);
if ( ret != TAI_STATUS_SUCCESS ) {
return ret;
}
ret = adapter->set_attributes(type, real_id, 1, attr->raw());
if ( ret != TAI_STATUS_SUCCESS ) {
return ret;
}
if ( meta->attrvaluetype == TAI_ATTR_VALUE_TYPE_NOTIFICATION && attribute->value.notification.notify == nullptr ) {
auto key = notification_key(id, attribute->id);
m_notification_map.erase(key);
}
return TAI_STATUS_SUCCESS;
}
}

View File

@@ -3,24 +3,126 @@
#include <string>
#include <unordered_set>
#include <memory>
#include <bitset>
#include <map>
#include <mutex>
class ModuleAdapter;
#include "tai.h"
#include "attribute.hpp"
#include "logger.hpp"
enum platform_adapter_t {
PLATFORM_ADAPTER_UNKNOWN,
PLATFORM_ADAPTER_STATIC,
};
namespace tai::mux {
class PlatformAdapter {
public:
virtual ModuleAdapter* get_module_adapter(const std::string& location) = 0;
class ModuleAdapter;
using S_ModuleAdapter = std::shared_ptr<ModuleAdapter>;
class PlatformAdapter;
using S_PlatformAdapter = std::shared_ptr<PlatformAdapter>;
using notification_key = std::pair<tai_object_id_t, tai_attr_id_t>;
struct NotificationContext {
PlatformAdapter *pa;
tai_notification_handler_t real_handler;
tai_object_id_t muxed_oid;
tai_object_type_t object_type;
std::mutex mutex;
};
using S_NotificationContext = std::shared_ptr<NotificationContext>;
enum platform_adapter_t {
PLATFORM_ADAPTER_UNKNOWN,
PLATFORM_ADAPTER_STATIC,
};
static const int TAI_MUX_NUM_MAX_OBJECT = 256;
class OIDAllocator {
public:
tai_object_id_t next() {
// TAI_NULL_OBJECT_ID == 0, start from i = 1
for (int i = 1; i < TAI_MUX_NUM_MAX_OBJECT; i++) {
if ( !m_bitset.test(i) ) {
m_bitset.set(i);
return tai_object_id_t(i);
}
}
throw std::runtime_error("OID max reach");
}
void free(tai_object_id_t oid) {
m_bitset.reset(oid);
}
private:
std::bitset<TAI_MUX_NUM_MAX_OBJECT> m_bitset;
};
class PlatformAdapter {
public:
virtual S_ModuleAdapter get_module_adapter(const std::string& location) = 0;
/** @brief return the set of loaded module adapters. */
virtual const std::unordered_set<S_ModuleAdapter> list_module_adapters() = 0;
PlatformAdapter(){}
virtual ~PlatformAdapter(){}
int get_mapping(const tai_object_id_t& id, S_ModuleAdapter *adapter, tai_object_id_t *real_id) {
if ( m_map.find(id) == m_map.end() ) {
return -1;
}
auto pair = m_map[id];
if ( adapter != nullptr ) {
*adapter = pair.second;
}
if ( real_id != nullptr ) {
*real_id = pair.first;
}
return 0;
};
tai_object_id_t get_reverse_mapping(const tai_object_id_t real_id, S_ModuleAdapter adapter) {
for ( auto p : m_map ) {
if ( p.second.first == real_id && p.second.second == adapter ) {
return p.first;
}
}
return TAI_NULL_OBJECT_ID;
}
int create_mapping(tai_object_id_t *id, S_ModuleAdapter adapter, const tai_object_id_t& real_id) {
auto value = std::pair<tai_object_id_t, S_ModuleAdapter>(real_id, adapter);
*id = m_oid_allocator.next();
m_map[*id] = value;
return 0;
}
virtual int remove_mapping(tai_object_id_t id) {
if ( m_map.find(id) == m_map.end() ) {
return 0;
}
m_map.erase(id);
m_oid_allocator.free(id);
return 0;
}
void notify(NotificationContext* ctx, tai_object_id_t real_oid, uint32_t attr_count, tai_attribute_t const * const attr_list);
tai_status_t convert_oid(const tai_object_type_t& type, const tai_object_id_t& id, const S_ConstAttribute src, const S_Attribute dst, bool reversed);
tai_status_t convert_oid(const tai_object_type_t& type, const tai_object_id_t& id, const tai_attribute_t * const src, tai_attribute_t * const dst, bool reversed);
tai_status_t set(const tai_object_type_t& type, const tai_object_id_t& id, const tai_attribute_t* const attribute);
private:
PlatformAdapter(const PlatformAdapter&){}
void operator = (const PlatformAdapter&){}
OIDAllocator m_oid_allocator;
std::map<tai_object_id_t, std::pair<tai_object_id_t, S_ModuleAdapter>> m_map;
std::map<notification_key, S_NotificationContext> m_notification_map;
};
using S_PlatformAdapter = std::shared_ptr<PlatformAdapter>;
/** @brief return the set of loaded module adapters. */
virtual const std::unordered_set<ModuleAdapter * > list_module_adapters() = 0;
PlatformAdapter(){}
private:
PlatformAdapter(const PlatformAdapter&){}
void operator = (const PlatformAdapter&){}
};
#endif

View File

@@ -1,46 +1,49 @@
#include "static_platform_adapter.hpp"
StaticPlatformAdapter::StaticPlatformAdapter(uint64_t flags, const tai_service_method_table_t* services) {
std::string config_file = TAI_MUX_STATIC_DEFAULT_CONFIG;
auto e = std::getenv(TAI_MUX_STATIC_CONFIG_FILE.c_str());
if ( e != nullptr ) {
config_file = e;
}
namespace tai::mux {
std::ifstream ifs(config_file);
if ( !ifs ) {
return;
}
std::istreambuf_iterator<char> it(ifs), last;
std::string config(it, last);
std::map<uint64_t, ModuleAdapter*> map;
auto c = json::parse(config);
m_services.module_presence = nullptr;
for ( json::iterator it = c.begin(); it != c.end(); ++it ) {
auto location = it.key();
auto lib = it.value().get<std::string>();
auto dl = ModuleAdapter::dl_address(lib);
ModuleAdapter *ma = nullptr;
if ( dl == 0 ) {
ma = new ModuleAdapter(lib, flags, &m_services);
dl = ModuleAdapter::dl_address(lib);
map[dl] = ma;
} else {
ma = map[dl];
StaticPlatformAdapter::StaticPlatformAdapter(uint64_t flags, const tai_service_method_table_t* services) {
std::string config_file = TAI_MUX_STATIC_DEFAULT_CONFIG;
auto e = std::getenv(TAI_MUX_STATIC_CONFIG_FILE.c_str());
if ( e != nullptr ) {
config_file = e;
}
m_ma_map[location] = ma;
if ( services != nullptr && services->module_presence != nullptr ) {
services->module_presence(true, const_cast<char*>(location.c_str()));
std::ifstream ifs(config_file);
if ( !ifs ) {
return;
}
std::istreambuf_iterator<char> it(ifs), last;
std::string config(it, last);
std::map<uint64_t, S_ModuleAdapter> map;
auto c = json::parse(config);
m_services.module_presence = nullptr;
for ( json::iterator it = c.begin(); it != c.end(); ++it ) {
auto location = it.key();
auto lib = it.value().get<std::string>();
auto dl = ModuleAdapter::dl_address(lib);
S_ModuleAdapter ma;
if ( dl == 0 ) {
ma = std::make_shared<ModuleAdapter>(lib, flags, &m_services);
dl = ModuleAdapter::dl_address(lib);
map[dl] = ma;
} else {
ma = map[dl];
}
m_ma_map[location] = ma;
if ( services != nullptr && services->module_presence != nullptr ) {
services->module_presence(true, const_cast<char*>(location.c_str()));
}
}
}
StaticPlatformAdapter::~StaticPlatformAdapter() {
for ( auto& m : m_ma_map ) {
m.second->tai_api_uninitialize();
}
}
}
StaticPlatformAdapter::~StaticPlatformAdapter() {
for ( auto& pair : m_ma_map ) {
delete pair.second;
}
}

View File

@@ -12,29 +12,33 @@
#include "tai.h"
#include "json.hpp"
using json = nlohmann::json;
namespace tai::mux {
const std::string TAI_MUX_STATIC_CONFIG_FILE = "TAI_MUX_STATIC_CONFIG_FILE";
const std::string TAI_MUX_STATIC_DEFAULT_CONFIG = "/etc/tai/mux/static.json";
using json = nlohmann::json;
const std::string TAI_MUX_STATIC_CONFIG_FILE = "TAI_MUX_STATIC_CONFIG_FILE";
const std::string TAI_MUX_STATIC_DEFAULT_CONFIG = "/etc/tai/mux/static.json";
class StaticPlatformAdapter : public PlatformAdapter {
public:
StaticPlatformAdapter(uint64_t flags, const tai_service_method_table_t* services);
~StaticPlatformAdapter();
S_ModuleAdapter get_module_adapter(const std::string& location) {
return m_ma_map[location];
};
const std::unordered_set<S_ModuleAdapter> list_module_adapters() {
std::unordered_set<S_ModuleAdapter> set;
for ( auto m : m_ma_map ) {
set.emplace(m.second);
}
return set;
};
private:
std::map<std::string, S_ModuleAdapter> m_ma_map;
std::thread m_th;
tai_service_method_table_t m_services;
};
class StaticPlatformAdapter : public PlatformAdapter {
public:
StaticPlatformAdapter(uint64_t flags, const tai_service_method_table_t* services);
~StaticPlatformAdapter();
ModuleAdapter* get_module_adapter(const std::string& location) {
return m_ma_map[location];
};
const std::unordered_set<ModuleAdapter*> list_module_adapters() {
std::unordered_set<ModuleAdapter*> set;
for ( auto m : m_ma_map ) {
set.emplace(m.second);
}
return set;
};
private:
std::map<std::string, ModuleAdapter*> m_ma_map;
std::thread m_th;
tai_service_method_table_t m_services;
};
#endif

View File

@@ -1,250 +0,0 @@
#include "mux.hpp"
#include <cstdlib>
#include <iostream>
extern Multiplexier *g_mux;
const std::string PLATFORM_ADAPTER = "TAI_MUX_PLATFORM_ADAPTER";
#ifndef DEFAULT_PLATFORM_ADAPTER
#define DEFAULT_PLATFORM_ADAPTER "static"
#endif
tai_status_t tai_api_initialize(_In_ uint64_t flags,
_In_ const tai_service_method_table_t* services)
{
if ( g_mux != nullptr ) {
return TAI_STATUS_SUCCESS;
}
auto pa = std::getenv(PLATFORM_ADAPTER.c_str());
std::string pa_name;
if ( pa == nullptr ) {
pa_name = DEFAULT_PLATFORM_ADAPTER;
} else {
pa_name = std::string(pa);
}
platform_adapter_t pa_kind;
if ( pa_name == "static" ) {
pa_kind = PLATFORM_ADAPTER_STATIC;
}
g_mux = create_mux(pa_kind, flags, services);
if ( g_mux == nullptr ) {
return TAI_STATUS_FAILURE;
}
return TAI_STATUS_SUCCESS;
}
tai_status_t tai_api_uninitialize(void) {
if ( g_mux != nullptr ) {
delete g_mux;
g_mux = nullptr;
}
return TAI_STATUS_SUCCESS;
}
static tai_status_t mux_create_host_interface(
_Out_ tai_object_id_t *host_interface_id,
_In_ tai_object_id_t module_id,
_In_ uint32_t attr_count,
_In_ const tai_attribute_t *attr_list) {
return g_mux->create_host_interface(host_interface_id, module_id, attr_count, attr_list);
}
static tai_status_t mux_remove_host_interface(_In_ tai_object_id_t host_interface_id)
{
return g_mux->remove_host_interface(host_interface_id);
}
static tai_status_t mux_set_host_interface_attributes(
_In_ tai_object_id_t host_interface_id,
_In_ uint32_t attr_count,
_In_ const tai_attribute_t *attr_list)
{
return g_mux->set_host_interface_attributes(host_interface_id, attr_count, attr_list);
}
static tai_status_t mux_set_host_interface_attribute(
_In_ tai_object_id_t host_interface_id,
_In_ const tai_attribute_t *attr)
{
return g_mux->set_host_interface_attributes(host_interface_id, 1, attr);
}
static tai_status_t mux_get_host_interface_attributes(
_In_ tai_object_id_t host_interface_id,
_In_ uint32_t attr_count,
_Out_ tai_attribute_t *attr_list)
{
return g_mux->get_host_interface_attributes(host_interface_id, attr_count, attr_list);
}
static tai_status_t mux_get_host_interface_attribute(
_In_ tai_object_id_t host_interface_id,
_Out_ tai_attribute_t *attr)
{
return g_mux->get_host_interface_attributes(host_interface_id, 1, attr);
}
static tai_status_t mux_clear_host_interface_attributes(
_In_ tai_object_id_t host_interface_id,
_In_ uint32_t attr_count,
_Out_ tai_attr_id_t *attr_list)
{
return g_mux->clear_host_interface_attributes(host_interface_id, attr_count, attr_list);
}
static tai_status_t mux_clear_host_interface_attribute(
_In_ tai_object_id_t host_interface_id,
_Out_ tai_attr_id_t attr_id)
{
return g_mux->clear_host_interface_attributes(host_interface_id, 1, &attr_id);
}
tai_host_interface_api_t mux_host_interface_api = {
.create_host_interface = mux_create_host_interface,
.remove_host_interface = mux_remove_host_interface,
.set_host_interface_attribute = mux_set_host_interface_attribute,
.set_host_interface_attributes = mux_set_host_interface_attributes,
.get_host_interface_attribute = mux_get_host_interface_attribute,
.get_host_interface_attributes = mux_get_host_interface_attributes,
.clear_host_interface_attribute = mux_clear_host_interface_attribute,
.clear_host_interface_attributes = mux_clear_host_interface_attributes
};
static tai_status_t mux_create_network_interface(
_Out_ tai_object_id_t *network_interface_id,
_In_ tai_object_id_t module_id,
_In_ uint32_t attr_count,
_In_ const tai_attribute_t *attr_list) {
return g_mux->create_network_interface(network_interface_id, module_id, attr_count, attr_list);
}
static tai_status_t mux_remove_network_interface(_In_ tai_object_id_t network_interface_id)
{
return g_mux->remove_network_interface(network_interface_id);
}
static tai_status_t mux_set_network_interface_attributes(
_In_ tai_object_id_t network_interface_id,
_In_ uint32_t attr_count,
_In_ const tai_attribute_t *attr_list)
{
return g_mux->set_network_interface_attributes(network_interface_id, attr_count, attr_list);
}
static tai_status_t mux_set_network_interface_attribute(
_In_ tai_object_id_t network_interface_id,
_In_ const tai_attribute_t *attr)
{
return g_mux->set_network_interface_attributes(network_interface_id, 1, attr);
}
static tai_status_t mux_get_network_interface_attributes(
_In_ tai_object_id_t network_interface_id,
_In_ uint32_t attr_count,
_Out_ tai_attribute_t *attr_list)
{
return g_mux->get_network_interface_attributes(network_interface_id, attr_count, attr_list);
}
static tai_status_t mux_get_network_interface_attribute(
_In_ tai_object_id_t network_interface_id,
_Out_ tai_attribute_t *attr)
{
return g_mux->get_network_interface_attributes(network_interface_id, 1, attr);
}
tai_network_interface_api_t mux_network_interface_api = {
.create_network_interface = mux_create_network_interface,
.remove_network_interface = mux_remove_network_interface,
.set_network_interface_attribute = mux_set_network_interface_attribute,
.set_network_interface_attributes = mux_set_network_interface_attributes,
.get_network_interface_attribute = mux_get_network_interface_attribute,
.get_network_interface_attributes = mux_get_network_interface_attributes
};
static tai_status_t mux_create_module(
_Out_ tai_object_id_t *module_id,
_In_ uint32_t attr_count,
_In_ const tai_attribute_t *attr_list)
{
return g_mux->create_module(module_id, attr_count, attr_list);
}
static tai_status_t mux_remove_module(_In_ tai_object_id_t module_id)
{
return g_mux->remove_module(module_id);
}
static tai_status_t mux_set_module_attributes(
_In_ tai_object_id_t module_id,
_In_ uint32_t attr_count,
_In_ const tai_attribute_t *attr_list)
{
return g_mux->set_module_attributes(module_id, attr_count, attr_list);
}
static tai_status_t mux_set_module_attribute(
_In_ tai_object_id_t module_id,
_In_ const tai_attribute_t *attr)
{
return mux_set_module_attributes(module_id, 1, attr);
}
static tai_status_t mux_get_module_attributes(
_In_ tai_object_id_t module_id,
_In_ uint32_t attr_count,
_Out_ tai_attribute_t *attr_list)
{
return g_mux->get_module_attributes(module_id, attr_count, attr_list);
}
static tai_status_t mux_get_module_attribute(
_In_ tai_object_id_t module_id,
_Out_ tai_attribute_t *attr)
{
return mux_get_module_attributes(module_id, 1, attr);
}
tai_module_api_t mux_module_api = {
.create_module = mux_create_module,
.remove_module = mux_remove_module,
.set_module_attribute = mux_set_module_attribute,
.set_module_attributes = mux_set_module_attributes,
.get_module_attribute = mux_get_module_attribute,
.get_module_attributes = mux_get_module_attributes
};
tai_status_t tai_api_query(_In_ tai_api_t tai_api_id,
_Out_ void** api_method_table)
{
if ( api_method_table == nullptr ) {
return TAI_STATUS_INVALID_PARAMETER;
}
switch (tai_api_id) {
case TAI_API_MODULE:
*api_method_table = &mux_module_api;
break;
case TAI_API_HOSTIF:
*api_method_table = &mux_host_interface_api;
break;
case TAI_API_NETWORKIF:
*api_method_table = &mux_network_interface_api;
break;
default:
return TAI_STATUS_INVALID_PARAMETER;
}
return TAI_STATUS_SUCCESS;
}
tai_status_t tai_log_set(tai_api_t tai_api_id, tai_log_level_t log_level, tai_log_fn log_fn) {
return g_mux->tai_log_set(tai_api_id, log_level, log_fn);
}
tai_object_type_t tai_object_type_query(tai_object_id_t id) {
return g_mux->object_type_query(id);
}
tai_object_id_t tai_module_id_query(tai_object_id_t id) {
return g_mux->module_id_query(id);
}