mirror of
https://github.com/Telecominfraproject/oopt-tai-implementations.git
synced 2025-10-29 17:22:39 +00:00
mux: overhaul by using TAI library framework
Signed-off-by: Wataru Ishida <ishida@nel-america.com>
This commit is contained in:
committed by
Wataru Ishida
parent
9c7351a0f1
commit
45f93cee42
@@ -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) $@
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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
|
||||
|
||||
706
tai_mux/mux.cpp
706
tai_mux/mux.cpp
@@ -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);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
286
tai_mux/mux.hpp
286
tai_mux/mux.hpp
@@ -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
|
||||
|
||||
Submodule tai_mux/oopt-tai updated: a4e6d90f77...e2c0bbeabc
152
tai_mux/platform_adapter.cpp
Normal file
152
tai_mux/platform_adapter.cpp
Normal 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;
|
||||
}
|
||||
}
|
||||
@@ -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
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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
|
||||
|
||||
250
tai_mux/tai.cpp
250
tai_mux/tai.cpp
@@ -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);
|
||||
}
|
||||
Reference in New Issue
Block a user