Plugin Management support C plugin

This commit is contained in:
luwenpeng
2022-07-27 18:32:22 +08:00
parent 649d29e538
commit 50111e7cd0
35 changed files with 4220 additions and 193 deletions

View File

@@ -17,6 +17,7 @@ include_directories(${CMAKE_SOURCE_DIR}/sdk/include)
#add vendor and source directory #add vendor and source directory
add_subdirectory(vendor) add_subdirectory(vendor)
add_subdirectory(deps/toml)
add_subdirectory(src) add_subdirectory(src)
add_subdirectory(sdk/example) add_subdirectory(sdk/example)

3
deps/toml/CMakeLists.txt vendored Normal file
View File

@@ -0,0 +1,3 @@
set(CMAKE_C_FLAGS "-std=c99")
add_definitions(-fPIC)
add_library(toml STATIC toml.c)

2379
deps/toml/toml.c vendored Normal file

File diff suppressed because it is too large Load Diff

175
deps/toml/toml.h vendored Normal file
View File

@@ -0,0 +1,175 @@
/*
MIT License
Copyright (c) CK Tan
https://github.com/cktan/tomlc99
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
*/
#ifndef TOML_H
#define TOML_H
#ifdef _MSC_VER
#pragma warning(disable: 4996)
#endif
#include <stdint.h>
#include <stdio.h>
#ifdef __cplusplus
#define TOML_EXTERN extern "C"
#else
#define TOML_EXTERN extern
#endif
typedef struct toml_timestamp_t toml_timestamp_t;
typedef struct toml_table_t toml_table_t;
typedef struct toml_array_t toml_array_t;
typedef struct toml_datum_t toml_datum_t;
/* Parse a file. Return a table on success, or 0 otherwise.
* Caller must toml_free(the-return-value) after use.
*/
TOML_EXTERN toml_table_t *toml_parse_file(FILE *fp, char *errbuf, int errbufsz);
/* Parse a string containing the full config.
* Return a table on success, or 0 otherwise.
* Caller must toml_free(the-return-value) after use.
*/
TOML_EXTERN toml_table_t *toml_parse(char *conf, /* NUL terminated, please. */
char *errbuf, int errbufsz);
/* Free the table returned by toml_parse() or toml_parse_file(). Once
* this function is called, any handles accessed through this tab
* directly or indirectly are no longer valid.
*/
TOML_EXTERN void toml_free(toml_table_t *tab);
/* Timestamp types. The year, month, day, hour, minute, second, z
* fields may be NULL if they are not relevant. e.g. In a DATE
* type, the hour, minute, second and z fields will be NULLs.
*/
struct toml_timestamp_t {
struct { /* internal. do not use. */
int year, month, day;
int hour, minute, second, millisec;
char z[10];
} __buffer;
int *year, *month, *day;
int *hour, *minute, *second, *millisec;
char *z;
};
/*-----------------------------------------------------------------
* Enhanced access methods
*/
struct toml_datum_t {
int ok;
union {
toml_timestamp_t *ts; /* ts must be freed after use */
char *s; /* string value. s must be freed after use */
int b; /* bool value */
int64_t i; /* int value */
double d; /* double value */
} u;
};
/* on arrays: */
/* ... retrieve size of array. */
TOML_EXTERN int toml_array_nelem(const toml_array_t *arr);
/* ... retrieve values using index. */
TOML_EXTERN toml_datum_t toml_string_at(const toml_array_t *arr, int idx);
TOML_EXTERN toml_datum_t toml_bool_at(const toml_array_t *arr, int idx);
TOML_EXTERN toml_datum_t toml_int_at(const toml_array_t *arr, int idx);
TOML_EXTERN toml_datum_t toml_double_at(const toml_array_t *arr, int idx);
TOML_EXTERN toml_datum_t toml_timestamp_at(const toml_array_t *arr, int idx);
/* ... retrieve array or table using index. */
TOML_EXTERN toml_array_t *toml_array_at(const toml_array_t *arr, int idx);
TOML_EXTERN toml_table_t *toml_table_at(const toml_array_t *arr, int idx);
/* on tables: */
/* ... retrieve the key in table at keyidx. Return 0 if out of range. */
TOML_EXTERN const char *toml_key_in(const toml_table_t *tab, int keyidx);
/* ... returns 1 if key exists in tab, 0 otherwise */
TOML_EXTERN int toml_key_exists(const toml_table_t *tab, const char *key);
/* ... retrieve values using key. */
TOML_EXTERN toml_datum_t toml_string_in(const toml_table_t *arr,
const char *key);
TOML_EXTERN toml_datum_t toml_bool_in(const toml_table_t *arr, const char *key);
TOML_EXTERN toml_datum_t toml_int_in(const toml_table_t *arr, const char *key);
TOML_EXTERN toml_datum_t toml_double_in(const toml_table_t *arr,
const char *key);
TOML_EXTERN toml_datum_t toml_timestamp_in(const toml_table_t *arr,
const char *key);
/* .. retrieve array or table using key. */
TOML_EXTERN toml_array_t *toml_array_in(const toml_table_t *tab,
const char *key);
TOML_EXTERN toml_table_t *toml_table_in(const toml_table_t *tab,
const char *key);
/*-----------------------------------------------------------------
* lesser used
*/
/* Return the array kind: 't'able, 'a'rray, 'v'alue, 'm'ixed */
TOML_EXTERN char toml_array_kind(const toml_array_t *arr);
/* For array kind 'v'alue, return the type of values
i:int, d:double, b:bool, s:string, t:time, D:date, T:timestamp, 'm'ixed
0 if unknown
*/
TOML_EXTERN char toml_array_type(const toml_array_t *arr);
/* Return the key of an array */
TOML_EXTERN const char *toml_array_key(const toml_array_t *arr);
/* Return the number of key-values in a table */
TOML_EXTERN int toml_table_nkval(const toml_table_t *tab);
/* Return the number of arrays in a table */
TOML_EXTERN int toml_table_narr(const toml_table_t *tab);
/* Return the number of sub-tables in a table */
TOML_EXTERN int toml_table_ntab(const toml_table_t *tab);
/* Return the key of a table*/
TOML_EXTERN const char *toml_table_key(const toml_table_t *tab);
/*--------------------------------------------------------------
* misc
*/
TOML_EXTERN int toml_utf8_to_ucs(const char *orig, int len, int64_t *ret);
TOML_EXTERN int toml_ucs_to_utf8(int64_t code, char buf[6]);
TOML_EXTERN void toml_set_memutil(void *(*xxmalloc)(size_t),
void (*xxfree)(void *));
/*--------------------------------------------------------------
* deprecated
*/
/* A raw value, must be processed by toml_rto* before using. */
typedef const char *toml_raw_t;
TOML_EXTERN toml_raw_t toml_raw_in(const toml_table_t *tab, const char *key);
TOML_EXTERN toml_raw_t toml_raw_at(const toml_array_t *arr, int idx);
TOML_EXTERN int toml_rtos(toml_raw_t s, char **ret);
TOML_EXTERN int toml_rtob(toml_raw_t s, int *ret);
TOML_EXTERN int toml_rtoi(toml_raw_t s, int64_t *ret);
TOML_EXTERN int toml_rtod(toml_raw_t s, double *ret);
TOML_EXTERN int toml_rtod_ex(toml_raw_t s, double *ret, char *buf, int buflen);
TOML_EXTERN int toml_rtots(toml_raw_t s, toml_timestamp_t *ret);
#endif /* TOML_H */

View File

@@ -1,12 +1,9 @@
add_library(custom_event_plugin SHARED
add_definitions(-fPIC)
add_library(custom_event_plugin
custom_event_plugin.cpp custom_event_plugin.cpp
) )
set_target_properties(custom_event_plugin PROPERTIES PREFIX "") set_target_properties(custom_event_plugin PROPERTIES PREFIX "")
add_library(http_event_plugin add_library(http_event_plugin SHARED
http_event_plugin.cpp http_event_plugin.cpp
) )
set_target_properties(http_event_plugin PROPERTIES PREFIX "") set_target_properties(http_event_plugin PROPERTIES PREFIX "")

View File

@@ -2,37 +2,57 @@
#include "packet.h" #include "packet.h"
#include "plugin.h" #include "plugin.h"
struct custom_session_event *_event = nullptr; #include <stddef.h>
#include <stdlib.h>
#include <stdio.h>
void *custom_decode(const char *payload, uint32_t len, void **pme) static char *g_handler = NULL;
static void *custom_decode(const char *payload, uint16_t len, void **pme)
{ {
return nullptr; return NULL;
} }
int custom_plugin_entry(const struct stellar_session *s, int what, struct stellar_packet *p, const char *payload, uint32_t len, void **pme) extern "C" void custom_plugin_tcp_entry(const struct stellar_session *s, enum session_event_type event, struct stellar_packet *p, const char *payload, uint16_t len, void **pme)
{ {
struct stellar_session_event_extras *info= (struct stellar_session_event_extras *)custom_decode(payload, len, pme); char **per_session_pme = (char **)pme;
struct stellar_session *new_session=session_manager_session_derive(s, "CUSTOM_A");
printf("RUN custom_plugin_tcp_entry, event: %d\n", event);
struct stellar_session_event_extras *info = (struct stellar_session_event_extras *)custom_decode(payload, len, pme);
struct stellar_session *new_session = session_manager_session_derive(s, "CUSTOM");
session_manager_trigger_event(new_session, SESSION_EVENT_OPENING, info); session_manager_trigger_event(new_session, SESSION_EVENT_OPENING, info);
session_manager_trigger_event(new_session, SESSION_EVENT_META, info); session_manager_trigger_event(new_session, SESSION_EVENT_META, info);
return 0;
} }
int custom_event_plugin_entry(const struct stellar_session *s, int what, struct stellar_packet *p, const char *payload, uint32_t len, void **pme) extern "C" void custom_plugin_custom_entry(const struct stellar_session *s, enum session_event_type event, struct stellar_packet *p, const char *payload, uint16_t len, void **pme)
{ {
return 0; char **per_session_pme = (char **)pme;
printf("RUN custom_plugin_custom_entry, event: %d\n", event);
} }
int custom_plugin_init() extern "C" int custom_plugin_init(void)
{ {
//plugin_manager_event_register("TCP", custom_plugin_entry, nullptr); printf("RUN custom_plugin_init\n");
//plugin_manager_event_register("CUSTOM_A", custom_event_plugin_entry, nullptr);
if (g_handler == NULL)
{
g_handler = (char *)malloc(1024);
snprintf(g_handler, 1024, "222222");
}
return 0; return 0;
} }
void custom_plugin_destroy() extern "C" void custom_plugin_exit(void)
{ {
return ; printf("RUN custom_plugin_exit\n");
if (g_handler)
{
free(g_handler);
g_handler = NULL;
}
} }

View File

@@ -1,22 +1,82 @@
#include "session.h" #include "session.h"
#include "packet.h" #include "packet.h"
#include "plugin.h" #include "plugin.h"
#include "http.h"
#include <stdlib.h>
#include <stdio.h>
static char *g_handler = NULL;
int http_event_plugin_entry(const struct stellar_session *s, int what, struct stellar_packet *p, const char *payload, uint32_t len, void **pme) struct per_session_pme_info
{ {
int flag;
char data[16];
};
extern "C" void http_event_plugin_entry(const struct stellar_session *s, enum session_event_type event, struct stellar_packet *p, const char *payload, uint16_t len, void **pme)
{
struct per_session_pme_info **per_session_pme = (struct per_session_pme_info **)pme;
printf("RUN http_event_plugin_entry, event: %d\n", event);
if (event & SESSION_EVENT_OPENING)
{
if (*per_session_pme == NULL)
{
struct per_session_pme_info *cur_ctx = (struct per_session_pme_info *)malloc(sizeof(struct per_session_pme_info));
snprintf(cur_ctx->data, 6, "******");
*per_session_pme = *&cur_ctx;
printf("http_event_plugin_entry->opening_handler\n");
}
}
if (event & SESSION_EVENT_RAWPKT)
{
printf("http_event_plugin_entry->rawpkt_handler\n");
}
if (event & SESSION_EVENT_ORDPKT)
{
printf("http_event_plugin_entry->ordpkt_handler\n");
}
if (event & SESSION_EVENT_META)
{
printf("http_event_plugin_entry->meta_handler\n");
}
if (event & SESSION_EVENT_CLOSING)
{
if (*per_session_pme)
{
printf("http_event_plugin_entry->closing_hanler\n");
free(*per_session_pme);
*per_session_pme = NULL;
}
}
}
extern "C" int http_event_plugin_init(void)
{
printf("RUN http_event_plugin_init\n");
if (g_handler == NULL)
{
g_handler = (char *)malloc(1024);
snprintf(g_handler, 1024, "111111");
}
return 0; return 0;
} }
int http_event_plugin_init() extern "C" void http_event_plugin_exit(void)
{ {
//plugin_manager_event_register("HTTP", http_event_plugin_entry, nullptr); printf("RUN http_event_plugin_exit\n");
return 0;
}
void http_event_plugin_destroy() if (g_handler)
{ {
return ; free(g_handler);
g_handler = NULL;
}
} }

View File

@@ -1,16 +1,14 @@
[PLUGINFO] [PLUGINFO]
INIT_FUNC=custom_plugin_init INIT_FUNC="custom_plugin_init"
EXIT_FUNC=custom_plugin_exit EXIT_FUNC="custom_plugin_exit"
LIBRARY_PATH=./plugins/custom_event_plugin/custom_event_plugin.so LIBRARY_PATH="./plugins/custom_event_plugin/custom_event_plugin.so"
# Support SESSION_EVENT_TYPE: "SESSION_EVENT_OPENING", "SESSION_EVENT_RAWPKT", "SESSION_EVENT_ORDPKT", "SESSION_EVENT_META", "SESSION_EVENT_CLOSING", "SESSION_EVENT_ALL"
# Support SESSION_EVENT_TYPE [SESSION_NAME.TCP]
# OPENING,RAWPKT,ORDPKT,META,CLOSING,ALL SESSION_EVENT_TYPE=["SESSION_EVENT_ALL"]
SESSION_EVENT_CALLBACK="custom_plugin_tcp_entry"
[SESSION_TYPE.TCP] [SESSION_NAME.CUSTOM]
SESSION_EVENT_TYPE=ALL SESSION_EVENT_TYPE=["SESSION_EVENT_OPENING","SESSION_EVENT_ORDPKT","SESSION_EVENT_CLOSING"]
SESSION_EVENT_CALLBACK=custom_plugin_entry SESSION_EVENT_CALLBACK="custom_plugin_custom_entry"
[SESSION_TYPE.CUSTOM_A]
SESSION_EVENT_TYPE=OPENING,ORDPKT,CLOSING
SESSION_EVENT_CALLBACK=custom_event_plugin_entry

View File

@@ -1,8 +1,10 @@
[PLUGINFO] [PLUGINFO]
INIT_FUNC=http_event_plugin_init INIT_FUNC="http_event_plugin_init"
EXIT_FUNC=http_event_plugin_exit EXIT_FUNC="http_event_plugin_exit"
LIBRARY_PATH=./plugins/http_event_plugin/http_event_plugin.so LIBRARY_PATH="./plugins/http_event_plugin/http_event_plugin.so"
[SESSION_TYPE.HTTP] # Support SESSION_EVENT_TYPE: "SESSION_EVENT_OPENING", "SESSION_EVENT_RAWPKT", "SESSION_EVENT_ORDPKT", "SESSION_EVENT_META", "SESSION_EVENT_CLOSING", "SESSION_EVENT_ALL"
SESSION_EVENT_TYPE=ALL
SESSION_EVENT_CALLBACK=http_event_plugin_entry [SESSION_NAME.HTTP]
SESSION_EVENT_TYPE=["SESSION_EVENT_ALL"]
SESSION_EVENT_CALLBACK="http_event_plugin_entry"

View File

@@ -1,2 +1,4 @@
./http_event_plugin/http_event_plugin.inf # Relative path, relative to the installation path of stellar
./custom_event_plugin/custom_event_plugin.inf
./plugins/http_event_plugin/http_event_plugin.inf
./plugins/custom_event_plugin/custom_event_plugin.inf

View File

@@ -1,6 +1,5 @@
#pragma once #pragma once
#include "packet.h"
#include "session.h" #include "session.h"
void http_decoder(const struct stellar_session *s, int what, struct stellar_packet *p, const char *payload, uint16_t len, void **pme); void http_decoder(const struct stellar_session *s, enum session_event_type event, struct stellar_packet *p, const char *payload, uint16_t len, void **pme);

View File

@@ -2,8 +2,14 @@
#include "session.h" #include "session.h"
typedef int plugin_init_callback(void **pme); typedef int plugin_init_callback(void);
typedef void plugin_exit_callback(void *pme); typedef void plugin_exit_callback(void);
void plugin_remove_from_session_event(struct stellar_event *ev, void plugin_remove_from_session_event(struct stellar_event *ev, struct stellar_session *s);
struct stellar_session *s);
/******************************************************************************
* Public API: between plugin and plugin_manager
******************************************************************************/
// TODO
// TODO

View File

@@ -25,6 +25,7 @@ enum stellar_session_type
enum session_event_type enum session_event_type
{ {
SESSION_EVENT_UNKNOWN = (0x00),
SESSION_EVENT_OPENING = (0x01 << 1), SESSION_EVENT_OPENING = (0x01 << 1),
SESSION_EVENT_RAWPKT = (0x01 << 2), SESSION_EVENT_RAWPKT = (0x01 << 2),
SESSION_EVENT_ORDPKT = (0x01 << 3), SESSION_EVENT_ORDPKT = (0x01 << 3),
@@ -35,11 +36,7 @@ enum session_event_type
struct stellar_session_event_extras; struct stellar_session_event_extras;
typedef void (fn_session_event_callback)(const struct stellar_session *s, int what, struct stellar_packet *p, const char *payload, uint16_t len, void **pme); typedef void(fn_session_event_callback)(const struct stellar_session *s, enum session_event_type event, struct stellar_packet *p, const char *payload, uint16_t len, void **pme);
void session_manager_trigger_event(struct stellar_session *s, void session_manager_trigger_event(struct stellar_session *s, enum session_event_type type, struct stellar_session_event_extras *info);
enum session_event_type type, struct stellar_session *session_manager_session_derive(const struct stellar_session *this_session, const char *session_name);
struct stellar_session_event_extras *info);
struct stellar_session *session_manager_session_derive(const struct stellar_session *this_session,
const char *new_session_type_name);

View File

@@ -1,11 +1,9 @@
include_directories(${CMAKE_SOURCE_DIR}/sdk/include) include_directories(${CMAKE_SOURCE_DIR}/sdk/include)
include_directories(${CMAKE_SOURCE_DIR}/deps/) include_directories(${CMAKE_SOURCE_DIR}/deps/)
include_directories(${CMAKE_SOURCE_DIR}/src/packet_io/) include_directories(${CMAKE_SOURCE_DIR}/src/packet_io/)
include_directories(${CMAKE_SOURCE_DIR}/src/session_manager/) include_directories(${CMAKE_SOURCE_DIR}/src/session_manager/)
include_directories(${CMAKE_SOURCE_DIR}/src/plugin_manager/) include_directories(${CMAKE_SOURCE_DIR}/src/plugin_manager/)
enable_testing() enable_testing()
add_subdirectory(packet_io) add_subdirectory(packet_io)
add_subdirectory(session_manager) add_subdirectory(session_manager)
@@ -16,4 +14,13 @@ add_executable(stellar
main.cpp main.cpp
) )
target_link_libraries(stellar pthread packet_io plugin_manager session_manager http) target_link_libraries(
stellar
pthread
packet_io
plugin_manager
session_manager
http
toml
dl
)

View File

@@ -59,11 +59,12 @@ int main(int argc, char ** argv)
struct plugin_manager *plug_mgr = plugin_manager_create(); struct plugin_manager *plug_mgr = plugin_manager_create();
// register build-in plugin // register build-in plugin
plugin_manager_register(plug_mgr, "HTTP", http_decoder); plugin_manager_register(plug_mgr, "HTTP", SESSION_EVENT_ALL, http_decoder);
// load external plugins // load external plugins
char absolute_plugin_file[] = "/op/tsg/sapp/plug/plugins.inf"; char prefix_path[] = "/op/tsg/stellar/";
plugin_manager_load(plug_mgr, absolute_plugin_file); char file_path[] = "./plugs/plugins.inf";
plugin_manager_load(plug_mgr, prefix_path, file_path);
//packet_io_init //packet_io_init
struct packet_io_device *dev = packet_io_init(1, "stellar", "cap0"); struct packet_io_device *dev = packet_io_init(1, "stellar", "cap0");
@@ -78,6 +79,7 @@ int main(int argc, char ** argv)
usleep(1); usleep(1);
} }
plugin_manager_unload(plug_mgr);
plugin_manager_destory(plug_mgr); plugin_manager_destory(plug_mgr);
return 0; return 0;

View File

@@ -1,4 +1,10 @@
add_library(plugin_manager add_library(plugin_manager
plugin_manager.cpp plugin_manager_config.cpp
plugin_manager_module.cpp
plugin_manager_util.cpp
plugin_manager.cpp
) )
target_include_directories(plugin_manager PUBLIC ${CMAKE_SOURCE_DIR}) target_include_directories(plugin_manager PUBLIC ${CMAKE_SOURCE_DIR})
add_subdirectory(test)

View File

@@ -1,106 +1,313 @@
#include "deps/uthash/uthash.h" #include "deps/uthash/uthash.h"
#include "sdk/include/session.h"
#include "sdk/include/plugin.h"
#include "session_manager.h" #include "session_manager.h"
#include "plugin_manager.h" #include "plugin_manager_util.h"
#include "plugin_manager_config.h"
#include "plugin_manager_module.h"
#include <sys/queue.h>
#include <assert.h> #include <assert.h>
#include <errno.h>
/****************************************************************************** /******************************************************************************
* CallBack Static Hash Table (For Global) * CallBack Runtime (For Per Session)
******************************************************************************/ ******************************************************************************/
struct session_event_callback_static struct eventcb_runtime
{ {
enum session_event_type event; int skip;
fn_session_event_callback *callback; void *cb_args;
};
/*
* Hast table
*
* key: string -> session_type
* val: array -> event_cbs
*/
struct managed_session_event_callback
{
char session_type[16];
struct session_event_callback_static event_cbs[0]; // dynamic array
// Record the number of callback functions that want to process the current session
int event_cbs_num;
UT_hash_handle hh;
};
/******************************************************************************
* CallBack Runtime Array (For Per Session)
******************************************************************************/
struct session_event_callback_runtime
{
int skip; // for skip this plugin callback
void *callback_args;
enum session_event_type event; enum session_event_type event;
fn_session_event_callback *callback; fn_session_event_callback *cb;
}; };
struct session_plugin_ctx struct session_plugin_ctx
{ {
int event_cbs_num; int current_plugin_index;
struct session_event_callback_runtime event_cbs[0]; // dynamic array int eventcb_num;
struct eventcb_runtime *eventcbs;
}; };
/****************************************************************************** /******************************************************************************
* struct plugin_manager * CallBack Static (For Per Plugin Manager)
******************************************************************************/ ******************************************************************************/
/* struct eventcb_static
* Each plugin has an init_cb and an exit_cb, but may have multiple entry_cb.
* entry_cb is stored in the global_session_callback_ctx.
*/
struct plugin_ctx
{ {
char *name; enum session_event_type event;
char *library; fn_session_event_callback *cb;
/*
* Stores the context generated by the plugin initialization,
* which is used to release resources when the plugin ends.
*/
void *pme;
plugin_init_callback *init_cb;
plugin_exit_callback *exit_cb;
}; };
struct plugin_manager_eventcb
{
char session_name[MAX_SESSION_NAME_LENGTH]; // key
int eventcb_num; // val size
struct eventcb_static *eventcbs; // val: dynamic array
UT_hash_handle hh;
};
/******************************************************************************
* Struct plugin_manager
******************************************************************************/
struct plugin_manager struct plugin_manager
{ {
struct managed_session_event_callback *cb_table; int used_module_num;
struct plugin_ctx plugins[MAX_PLUGIN_NUM]; int used_config_num;
int used_evencb_num; // only plugin register eventcb numbers
struct plugin_manager_module *modules[MAX_PLUGIN_NUM];
struct plugin_manager_config *configs[MAX_PLUGIN_NUM];
struct plugin_manager_eventcb *evcb_htable;
}; };
/****************************************************************************** /******************************************************************************
* Private API * Create/Destory plugin ctx (per session)
******************************************************************************/ ******************************************************************************/
static void plugin_manager_handle_opening_event(struct plugin_manager *plug_mgr, struct stellar_event *event) static struct session_plugin_ctx *plugin_manager_create_plugin_ctx(struct plugin_manager *plug_mgr, const char *session_name)
{ {
if (session_name == NULL || strlen(session_name) == 0)
{
plugin_manager_log(ERROR, "invalid parameter, session name is empty");
return NULL;
}
struct plugin_manager_eventcb *elem;
HASH_FIND_STR(plug_mgr->evcb_htable, session_name, elem);
if (elem == NULL)
{
plugin_manager_log(ERROR, "can't find event callback for session name '%s'", session_name);
return NULL;
}
else
{
struct session_plugin_ctx *plug_ctx = safe_alloc(struct session_plugin_ctx, 1);
plug_ctx->eventcb_num = elem->eventcb_num;
plug_ctx->eventcbs = safe_alloc(struct eventcb_runtime, plug_ctx->eventcb_num);
for (int i = 0; i < plug_ctx->eventcb_num; i++)
{
plug_ctx->eventcbs[i].skip = 0;
plug_ctx->eventcbs[i].event = elem->eventcbs[i].event;
plug_ctx->eventcbs[i].cb = elem->eventcbs[i].cb;
plug_ctx->eventcbs[i].cb_args = NULL;
}
return plug_ctx;
}
} }
static void plugin_manager_handle_data_event(struct plugin_manager *plug_mgr, struct stellar_event *event) static void plugin_manager_destory_plugin_ctx(struct session_plugin_ctx *plug_ctx)
{
}
static void plugin_manager_handle_closing_event(struct plugin_manager *plug_mgr, struct stellar_event *event)
{ {
if (plug_ctx)
{
safe_free(plug_ctx->eventcbs);
safe_free(plug_ctx);
}
} }
/****************************************************************************** /******************************************************************************
* Public API * Tools for managing plugins
******************************************************************************/ ******************************************************************************/
static int plugin_manager_parse_plugins(struct plugin_manager *plug_mgr, const char *prefix, const char *file)
{
char plugin_inf[4096] = {0};
char line_buffer[4096] = {0};
if (strlen(prefix) <= 0)
{
plugin_manager_log(ERROR, "Invalid parameter, plugin config file prefix cannot be empty");
return -1;
}
if (strlen(file) <= 0)
{
plugin_manager_log(ERROR, "Invalid parameter, plugin config file name cannot be empty");
return -1;
}
strcat_prefix_and_file(prefix, file, plugin_inf, sizeof(plugin_inf));
FILE *fp = fopen(plugin_inf, "r");
if (fp == NULL)
{
plugin_manager_log(ERROR, "can't open %s, %s", plugin_inf, strerror(errno));
return -1;
}
while (fgets(line_buffer, sizeof(line_buffer), fp))
{
if ('#' == line_buffer[0] || '\n' == line_buffer[0])
{
memset(line_buffer, 0, sizeof(line_buffer));
continue;
}
if (plug_mgr->used_config_num >= MAX_PLUGIN_NUM)
{
plugin_manager_log(ERROR, "the number of registered plugins exceeds the limit and cannot exceed %d", MAX_PLUGIN_NUM);
goto err;
}
struct plugin_manager_config *config = plugin_mangager_config_create();
if (plugin_mangager_config_parse(config, prefix, line_buffer) == -1)
{
plugin_mangager_config_destory(config);
goto err;
}
plug_mgr->configs[plug_mgr->used_config_num] = config;
plug_mgr->used_config_num++;
memset(line_buffer, 0, sizeof(line_buffer));
}
fclose(fp);
return 0;
err:
if (fp)
{
fclose(fp);
fp = NULL;
}
return -1;
}
static int plugin_manager_open_plugins(struct plugin_manager *plug_mgr)
{
for (int i = 0; i < plug_mgr->used_config_num; i++)
{
struct plugin_manager_config *config = plug_mgr->configs[i];
struct plugin_manager_module *module = plugin_manager_module_open(config);
if (module == NULL)
{
return -1;
}
plug_mgr->modules[plug_mgr->used_module_num] = module;
plug_mgr->used_module_num++;
}
return 0;
}
static int plugin_manager_register_plugins(struct plugin_manager *plug_mgr)
{
for (int i = 0; i < plug_mgr->used_module_num; i++)
{
struct plugin_manager_module *module = plug_mgr->modules[i];
if (plugin_manager_module_register(plug_mgr, module) == -1)
{
return -1;
}
plug_mgr->used_evencb_num++;
}
return 0;
}
static int plugin_manager_init_plugins(struct plugin_manager *plug_mgr)
{
for (int i = 0; i < plug_mgr->used_module_num; i++)
{
struct plugin_manager_module *module = plug_mgr->modules[i];
if (plugin_manager_module_init(module) == -1)
{
return -1;
}
double percentage = ((double)(i + 1)) / ((double)plug_mgr->used_module_num) * ((double)100);
plugin_manager_log(INFO, "Plugin initialization progress: [%.2f%]", percentage);
}
return 0;
}
static void plugin_manager_exit_plugins(struct plugin_manager *plug_mgr)
{
if (plug_mgr && plug_mgr->used_module_num)
{
for (int i = 0; i < plug_mgr->used_module_num; i++)
{
struct plugin_manager_module *module = plug_mgr->modules[i];
plugin_manager_module_exit(module);
}
}
}
static void plugin_manager_close_plugins(struct plugin_manager *plug_mgr)
{
if (plug_mgr && plug_mgr->used_module_num)
{
for (int i = 0; i < plug_mgr->used_module_num; i++)
{
struct plugin_manager_module *module = plug_mgr->modules[i];
plugin_manager_module_close(module);
}
plug_mgr->used_module_num = 0;
}
}
// deparse for destory parse
static void plugin_manager_deparse_plugins(struct plugin_manager *plug_mgr)
{
if (plug_mgr && plug_mgr->used_config_num)
{
for (int i = 0; i < plug_mgr->used_config_num; i++)
{
struct plugin_manager_config *config = plug_mgr->configs[i];
plugin_mangager_config_destory(config);
}
plug_mgr->used_config_num = 0;
}
}
/******************************************************************************
* Public API for managing plugins
******************************************************************************/
int plugin_manager_load(struct plugin_manager *plug_mgr, const char *prefix, const char *file)
{
if (plugin_manager_parse_plugins(plug_mgr, prefix, file) == -1)
{
return -1;
}
if (plugin_manager_open_plugins(plug_mgr) == -1)
{
return -1;
}
if (plugin_manager_register_plugins(plug_mgr) == -1)
{
return -1;
}
if (plugin_manager_init_plugins(plug_mgr) == -1)
{
return -1;
}
return 0;
}
void plugin_manager_unload(struct plugin_manager *plug_mgr)
{
plugin_manager_exit_plugins(plug_mgr);
plugin_manager_close_plugins(plug_mgr);
plugin_manager_deparse_plugins(plug_mgr);
}
struct plugin_manager *plugin_manager_create() struct plugin_manager *plugin_manager_create()
{ {
struct plugin_manager *plug_mgr = NULL; struct plugin_manager *plug_mgr = safe_alloc(struct plugin_manager, 1);
plug_mgr->used_module_num = 0;
plug_mgr->used_config_num = 0;
plug_mgr->used_evencb_num = 0;
plug_mgr->evcb_htable = NULL;
return plug_mgr; return plug_mgr;
} }
@@ -109,45 +316,138 @@ void plugin_manager_destory(struct plugin_manager *plug_mgr)
{ {
if (plug_mgr) if (plug_mgr)
{ {
if (plug_mgr->evcb_htable)
{
struct plugin_manager_eventcb *elem;
struct plugin_manager_eventcb *tmp;
HASH_ITER(hh, plug_mgr->evcb_htable, elem, tmp)
{
HASH_DEL(plug_mgr->evcb_htable, elem);
safe_free(elem->eventcbs);
safe_free(elem);
}
plug_mgr->evcb_htable = NULL;
plug_mgr->used_evencb_num = 0;
}
plugin_manager_unload(plug_mgr);
safe_free(plug_mgr);
} }
} }
int plugin_manager_load(struct plugin_manager *plug_mgr, const char *plugin_file) int plugin_manager_register(struct plugin_manager *plug_mgr, const char *session_name, enum session_event_type event, fn_session_event_callback *cb)
{ {
return 0; if (strlen(session_name) <= 0)
} {
plugin_manager_log(ERROR, "invalid parameter, session name is empty");
return -1;
}
void plugin_manager_unload(struct plugin_manager *plug_mgr) if (strlen(session_name) > MAX_SESSION_NAME_LENGTH)
{ {
} plugin_manager_log(ERROR, "invalid parameter, session name '%s' is too long and exceeds '%d' bytes", session_name, MAX_SESSION_NAME_LENGTH);
return -1;
}
if (cb == NULL)
{
plugin_manager_log(ERROR, "invalid parameter, the callback corresponding to the session name '%s' is null", session_name);
return -1;
}
struct plugin_manager_eventcb *elem;
HASH_FIND_STR(plug_mgr->evcb_htable, session_name, elem);
// session_name exists, add a new cb to the end of the eventcbs dynamic array
if (elem)
{
elem->eventcbs = (struct eventcb_static *)realloc(elem->eventcbs, (elem->eventcb_num + 1) * sizeof(struct eventcb_static));
elem->eventcbs[elem->eventcb_num].event = event;
elem->eventcbs[elem->eventcb_num].cb = cb;
elem->eventcb_num++;
}
// session_name does not exist, allocate a new node elem, and add elem to the hash table
else
{
elem = safe_alloc(struct plugin_manager_eventcb, 1);
memcpy(elem->session_name, session_name, strlen(session_name));
elem->eventcbs = (struct eventcb_static *)realloc(elem->eventcbs, (elem->eventcb_num + 1) * sizeof(struct eventcb_static));
elem->eventcbs[elem->eventcb_num].event = event;
elem->eventcbs[elem->eventcb_num].cb = cb;
elem->eventcb_num++;
HASH_ADD_STR(plug_mgr->evcb_htable, session_name, elem);
}
int plugin_manager_register(struct plugin_manager *plug_mgr, const char *session_type, fn_session_event_callback *callback)
{
return 0; return 0;
} }
void plugin_manager_dispatch(struct plugin_manager *plug_mgr, struct stellar_event *event) void plugin_manager_dispatch(struct plugin_manager *plug_mgr, struct stellar_event *event)
{ {
assert(event); const struct stellar_session *seesion = stellar_event_get_session(event);
struct stellar_session_event_data *event_data = event->session_event_data; struct session_plugin_ctx *plug_ctx = stellar_event_get_plugin_ctx(event);
assert(event_data); enum session_event_type event_type = stellar_event_get_type(event);
session_event_type type = event_data->type; const char *session_name = stellar_event_get_session_name(event);
struct stellar_packet *packet = stellar_event_get_packet(event);
uint16_t payload_len = stellar_event_get_payload_length(event);
const char *payload = stellar_event_get_payload(event);
switch (type) assert(seesion);
assert(session_name);
// the same session may trigger multi times opening events
if (event_type & SESSION_EVENT_OPENING)
{ {
case SESSION_EVENT_OPENING: if (plug_ctx == NULL)
plugin_manager_handle_opening_event(plug_mgr, event); {
break; plug_ctx = plugin_manager_create_plugin_ctx(plug_mgr, session_name);
case SESSION_EVENT_RAWPKT: /* fall through */ if (plug_ctx == NULL)
case SESSION_EVENT_ORDPKT: /* fall through */ {
case SESSION_EVENT_META: /* fall through */ plugin_manager_log(ERROR, "can't create runtime plugin ctx for session '%s', Please check whether the callback is registered in the current session");
plugin_manager_handle_data_event(plug_mgr, event); return;
break; }
case SESSION_EVENT_CLOSING: stellar_event_set_plugin_ctx(event, plug_ctx);
plugin_manager_handle_closing_event(plug_mgr, event); }
break; }
default:
// TODO log error if (plug_ctx)
break; {
for (int i = 0; i < plug_ctx->eventcb_num; i++)
{
plug_ctx->current_plugin_index = i;
struct eventcb_runtime *runtime = &plug_ctx->eventcbs[i];
if (runtime->skip)
{
continue;
}
if (runtime->event & event_type)
{
runtime->cb(seesion, event_type, packet, payload, payload_len, &runtime->cb_args);
}
}
}
else
{
plugin_manager_log(ERROR, "session '%s' runtime plugin ctx is null when running event callback", session_name);
abort();
}
if (event_type & SESSION_EVENT_CLOSING)
{
plugin_manager_destory_plugin_ctx(plug_ctx);
stellar_event_set_plugin_ctx(event, NULL);
} }
} }
/******************************************************************************
* Suppport LUA plugins
******************************************************************************/
// TODO

View File

@@ -1,11 +1,7 @@
#pragma once #pragma once
#include "sdk/include/session.h" #include "sdk/include/session.h"
#define MAX_PLUGIN_NUM 256
struct per_session_event_cbs;
struct plugin_manager; struct plugin_manager;
struct plugin_manager *plugin_manager_create(); struct plugin_manager *plugin_manager_create();
@@ -13,8 +9,8 @@ void plugin_manager_destory(struct plugin_manager *plug_mgr);
// return 0: success // return 0: success
// return -1: error // return -1: error
int plugin_manager_load(struct plugin_manager *plug_mgr, const char *plugin_file); int plugin_manager_load(struct plugin_manager *plug_mgr, const char *prefix, const char *file);
void plugin_manager_unload(struct plugin_manager *plug_mgr); void plugin_manager_unload(struct plugin_manager *plug_mgr);
int plugin_manager_register(struct plugin_manager *plug_mgr, const char *session_type, fn_session_event_callback *callback); int plugin_manager_register(struct plugin_manager *plug_mgr, const char *session_name, enum session_event_type event, fn_session_event_callback *callback);
void plugin_manager_dispatch(struct plugin_manager *plug_mgr, struct stellar_event *event); void plugin_manager_dispatch(struct plugin_manager *plug_mgr, struct stellar_event *event);

View File

@@ -0,0 +1,358 @@
#include <errno.h>
#include <stdlib.h>
#include <string.h>
#include "toml/toml.h"
#include "sdk/include/session.h"
#include "plugin_manager_util.h"
#include "plugin_manager_config.h"
struct event_type_map
{
const char *type_str;
enum session_event_type type_int;
};
static struct event_type_map evtype_map[] =
{
{"SESSION_EVENT_OPENING", SESSION_EVENT_OPENING},
{"SESSION_EVENT_RAWPKT", SESSION_EVENT_RAWPKT},
{"SESSION_EVENT_ORDPKT", SESSION_EVENT_ORDPKT},
{"SESSION_EVENT_META", SESSION_EVENT_META},
{"SESSION_EVENT_CLOSING", SESSION_EVENT_CLOSING},
{"SESSION_EVENT_ALL", SESSION_EVENT_ALL},
};
/******************************************************************************
* Private API (For Event Type)
******************************************************************************/
static enum session_event_type event_type_str2int(const char *evtype_str)
{
int num = sizeof(evtype_map) / sizeof(evtype_map[0]);
for (int i = 0; i < num; i++)
{
if (strcmp(evtype_str, evtype_map[i].type_str) == 0)
{
return evtype_map[i].type_int;
}
}
return SESSION_EVENT_UNKNOWN;
}
static void event_type_int2str(enum session_event_type evtype_int, char *buffer, int size)
{
int used = 0;
int num = sizeof(evtype_map) / sizeof(evtype_map[0]);
for (int i = 0; i < num; i++)
{
if (evtype_map[i].type_int & evtype_int)
{
if (evtype_map[i].type_int == SESSION_EVENT_ALL && evtype_int != SESSION_EVENT_ALL)
{
continue;
}
used += snprintf(buffer + used, size - used, "%s ", evtype_map[i].type_str);
}
}
}
/******************************************************************************
* Private API (For Parse)
******************************************************************************/
static int toml_parse_string(toml_table_t *table, const char *string_key, const char *file, char **out)
{
toml_datum_t string_val = toml_string_in(table, string_key);
if (!string_val.ok)
{
plugin_manager_log(ERROR, "can't find '%s' configuration iterm in %s", string_key, file);
return -1;
}
if (strlen(string_val.u.s) <= 0)
{
plugin_manager_log(ERROR, "invalid value for '%s' configuration item in %s", string_key, file);
safe_free(string_val.u.s);
return -1;
}
*out = safe_dup(string_val.u.s);
safe_free(string_val.u.s);
return 0;
}
static int toml_parse_table(toml_table_t *table, const char *string_key, const char *file, toml_table_t **out)
{
*out = toml_table_in(table, string_key);
if (*out == NULL)
{
plugin_manager_log(ERROR, "can't find '%s' section in %s", string_key, file);
return -1;
}
return 0;
}
static int toml_parse_plugin_section(toml_table_t *root, struct plugin_manager_config *config, const char *file)
{
toml_table_t *plugin_section = NULL;
if (toml_parse_table(root, "PLUGINFO", file, &plugin_section) == -1)
{
return -1;
}
if (toml_parse_string(plugin_section, "INIT_FUNC", file, &config->plugin_section.init_func_name) == -1)
{
return -1;
}
if (toml_parse_string(plugin_section, "EXIT_FUNC", file, &config->plugin_section.exit_func_name) == -1)
{
return -1;
}
if (toml_parse_string(plugin_section, "LIBRARY_PATH", file, &config->plugin_section.lib_path) == -1)
{
return -1;
}
return 0;
}
static int toml_parse_session_section(toml_table_t *root, struct plugin_manager_config *config, const char *file)
{
toml_table_t *session_section = NULL;
toml_table_t *sub_session_section = NULL;
const char *session_name = NULL;
toml_array_t *event_type_array = NULL;
toml_datum_t type_str;
enum session_event_type type_int;
if (toml_parse_table(root, "SESSION_NAME", file, &session_section) == -1)
{
return -1;
}
for (int i = 0; i < toml_table_ntab(session_section); i++)
{
session_name = NULL;
sub_session_section = NULL;
event_type_array = NULL;
config->session_section = (struct session_section_config *)realloc(config->session_section, sizeof(struct session_section_config) * (config->session_section_num + 1));
config->session_section[config->session_section_num].event = SESSION_EVENT_UNKNOWN;
config->session_section[config->session_section_num].cb_func_name = NULL;
memset(config->session_section[config->session_section_num].session_name, 0, MAX_SESSION_NAME_LENGTH);
// parse session name
session_name = toml_key_in(session_section, i);
int session_name_len = strlen(session_name);
if (session_name_len <= 0)
{
plugin_manager_log(ERROR, "invalid value for 'SESSION_NAME' configuration item in %s", file);
return -1;
}
if (session_name_len > MAX_SESSION_NAME_LENGTH)
{
plugin_manager_log(ERROR, "invalid value for 'SESSION_NAME' configuration item in %s, '%s' is too long and exceeds %d bytes", file, session_name, MAX_SESSION_NAME_LENGTH);
return -1;
}
if (toml_parse_table(session_section, session_name, file, &sub_session_section) == -1)
{
return -1;
}
strncpy(config->session_section[config->session_section_num].session_name, session_name, session_name_len);
// parse session event callback
if (toml_parse_string(sub_session_section, "SESSION_EVENT_CALLBACK", file, &config->session_section[config->session_section_num].cb_func_name) == -1)
{
return -1;
}
event_type_array = toml_array_in(sub_session_section, "SESSION_EVENT_TYPE");
if (event_type_array == NULL)
{
plugin_manager_log(ERROR, "can't find 'SESSION_EVENT_TYPE' configuration iterm in '[SESSION_NAME.%s]' section of %s", session_name, file);
return -1;
}
for (int i = 0; i < toml_array_nelem(event_type_array); i++)
{
type_int = SESSION_EVENT_UNKNOWN;
type_str = toml_string_at(event_type_array, i);
if (!type_str.ok)
{
plugin_manager_log(ERROR, "can't parse 'SESSION_EVENT_TYPE' configuration iterm in '[SESSION_NAME.%s]' section of %s", session_name, file);
return -1;
}
type_int = event_type_str2int(type_str.u.s);
if (type_int == SESSION_EVENT_UNKNOWN)
{
plugin_manager_log(ERROR, "invalid value '%s' for 'SESSION_EVENT_TYPE' configuration item in '[SESSION_NAME.%s]' section of %s", type_str.u.s, session_name, file);
safe_free(type_str.u.s);
return -1;
}
(config->session_section[config->session_section_num].event) = (enum session_event_type)((config->session_section[config->session_section_num].event) | type_int);
safe_free(type_str.u.s);
}
config->session_section_num++;
}
return 0;
}
/******************************************************************************
* Public API
******************************************************************************/
struct plugin_manager_config *plugin_mangager_config_create()
{
struct plugin_manager_config *config = safe_alloc(struct plugin_manager_config, 1);
config->prefix_path = NULL;
config->file_path = NULL;
config->session_section_num = 0;
config->session_section = NULL;
config->plugin_section.init_func_name = NULL;
config->plugin_section.exit_func_name = NULL;
config->plugin_section.lib_path = NULL;
return config;
}
void plugin_mangager_config_destory(struct plugin_manager_config *config)
{
if (config)
{
safe_free(config->prefix_path);
safe_free(config->file_path);
safe_free(config->plugin_section.init_func_name);
safe_free(config->plugin_section.exit_func_name);
safe_free(config->plugin_section.lib_path);
if (config->session_section)
{
for (int i = 0; i < config->session_section_num; i++)
{
struct session_section_config *temp = &config->session_section[i];
safe_free(temp->cb_func_name);
}
config->session_section_num = 0;
safe_free(config->session_section);
}
safe_free(config);
}
}
void plugin_mangager_config_dump(struct plugin_manager_config *config)
{
if (config)
{
plugin_manager_log(DEBUG, "[CONFIG_PREFIX] : %s", config->prefix_path);
plugin_manager_log(DEBUG, "[CONFIG_FILE] : %s", config->file_path);
plugin_manager_log(DEBUG, "[PLUGINFO]->INIT_FUNC : %s", config->plugin_section.init_func_name);
plugin_manager_log(DEBUG, "[PLUGINFO]->EXIT_FUNC : %s", config->plugin_section.exit_func_name);
plugin_manager_log(DEBUG, "[PLUGINFO]->LIBRARY_PATH : %s", config->plugin_section.lib_path);
if (config->session_section)
{
for (int i = 0; i < config->session_section_num; i++)
{
char tmp_buffer[1024] = {0};
struct session_section_config *temp = &config->session_section[i];
event_type_int2str(temp->event, tmp_buffer, 1024);
plugin_manager_log(DEBUG, "[SESSION_NAME.%s]->SESSION_EVENT_TYPE : %d, %s", temp->session_name, temp->event, tmp_buffer);
plugin_manager_log(DEBUG, "[SESSION_NAME.%s]->SESSION_EVENT_CALLBACK : %s", temp->session_name, temp->cb_func_name);
}
}
}
}
int plugin_mangager_config_parse(struct plugin_manager_config *config, const char *prefix, const char *file)
{
FILE *fp = NULL;
toml_table_t *root = NULL;
char errbuf[200] = {0};
char tmp_buffer[4096] = {0};
config->prefix_path = safe_dup(prefix);
config->file_path = safe_dup(file);
strcat_prefix_and_file(prefix, file, tmp_buffer, sizeof(tmp_buffer));
fp = fopen(tmp_buffer, "r");
if (fp == NULL)
{
plugin_manager_log(ERROR, "can't open %s, %s", tmp_buffer, strerror(errno));
return -1;
}
root = toml_parse_file(fp, errbuf, sizeof(errbuf));
if (root == NULL)
{
plugin_manager_log(ERROR, "toml parsing %s failed, %s", file, errbuf);
goto err;
}
if (toml_parse_plugin_section(root, config, file) == -1)
{
goto err;
}
if (toml_parse_session_section(root, config, file) == -1)
{
goto err;
}
toml_free(root);
fclose(fp);
return 0;
err:
if (root)
{
toml_free(root);
}
if (fp)
{
fclose(fp);
fp = NULL;
}
return -1;
}
/******************************************************************************
* Test
******************************************************************************/
#ifdef PLUGIN_MANAGER_TEST
int main(int argc, char *argv[])
{
struct plugin_manager_config *config = plugin_mangager_config_create();
if (plugin_mangager_config_parse(config, argv[1], argv[2]) == -1)
{
plugin_manager_log(ERROR, "can't parser %s %s", argv[1], argv[2]);
}
plugin_mangager_config_dump(config);
plugin_mangager_config_destory(config);
return 0;
}
#endif

View File

@@ -0,0 +1,34 @@
#pragma once
#include "plugin_manager_util.h"
#include "sdk/include/session.h"
struct session_section_config
{
char session_name[MAX_SESSION_NAME_LENGTH];
char *cb_func_name;
enum session_event_type event;
};
struct plugin_section_config
{
char *init_func_name;
char *exit_func_name;
char *lib_path;
};
struct plugin_manager_config
{
char *prefix_path; // absolute path to stellar installation
char *file_path; // relative path to stellar installation
int session_section_num;
struct session_section_config *session_section; // array
struct plugin_section_config plugin_section;
};
struct plugin_manager_config *plugin_mangager_config_create();
void plugin_mangager_config_destory(struct plugin_manager_config *config);
int plugin_mangager_config_parse(struct plugin_manager_config *config, const char *prefix, const char *file);
void plugin_mangager_config_dump(struct plugin_manager_config *config);

View File

@@ -0,0 +1,168 @@
#include <time.h>
#include <dlfcn.h>
#include <stdlib.h>
#include <string.h>
#include "sdk/include/plugin.h"
#include "plugin_manager_util.h"
#include "plugin_manager_config.h"
#include "plugin_manager.h"
struct plugin_manager_module_evcb
{
char session_name[MAX_SESSION_NAME_LENGTH];
fn_session_event_callback *event_cb_ptr;
enum session_event_type event;
};
struct plugin_manager_module
{
char *prefix;
char *lib_path;
void *dl_handle;
plugin_init_callback *init_cb_ptr;
plugin_exit_callback *exit_cb_ptr;
struct plugin_manager_module_evcb *evcbs;
int evcbs_num;
};
void plugin_manager_module_close(struct plugin_manager_module *module)
{
if (module)
{
if (module->exit_cb_ptr)
{
module->exit_cb_ptr();
}
if (module->dl_handle)
{
dlclose(module->dl_handle);
module->dl_handle = NULL;
}
safe_free(module->prefix);
safe_free(module->lib_path);
safe_free(module->evcbs);
module->evcbs_num = 0;
safe_free(module);
}
}
struct plugin_manager_module *plugin_manager_module_open(struct plugin_manager_config *config)
{
if (config == NULL)
{
return NULL;
}
char dynamic_lib_path[4096] = {0};
struct plugin_manager_module *module = safe_alloc(struct plugin_manager_module, 1);
module->prefix = safe_dup(config->prefix_path);
module->lib_path = safe_dup(config->plugin_section.lib_path);
strcat_prefix_and_file(module->prefix, module->lib_path, dynamic_lib_path, sizeof(dynamic_lib_path));
module->evcbs_num = 0;
module->dl_handle = dlopen(dynamic_lib_path, RTLD_LAZY | RTLD_GLOBAL | RTLD_DEEPBIND);
if (module->dl_handle == NULL)
{
plugin_manager_log(ERROR, "can't dlopen %s, %s", dynamic_lib_path, dlerror());
goto err;
}
module->init_cb_ptr = (plugin_init_callback *)(dlsym(module->dl_handle, config->plugin_section.init_func_name));
if (module->init_cb_ptr == NULL)
{
plugin_manager_log(ERROR, "can't find symbol name of '%s' in dynamic library %s, %s",
config->plugin_section.init_func_name, dynamic_lib_path, dlerror());
goto err;
}
module->exit_cb_ptr = (plugin_exit_callback *)(dlsym(module->dl_handle, config->plugin_section.exit_func_name));
if (module->exit_cb_ptr == NULL)
{
plugin_manager_log(ERROR, "can't find symbol name of '%s' in dynamic library %s, %s",
config->plugin_section.exit_func_name, dynamic_lib_path, dlerror());
goto err;
}
if (config->session_section)
{
module->evcbs = safe_alloc(struct plugin_manager_module_evcb, config->session_section_num);
module->evcbs_num = config->session_section_num;
for (int i = 0; i < config->session_section_num; i++)
{
struct session_section_config *session_config = &config->session_section[i];
struct plugin_manager_module_evcb *event_cb = &module->evcbs[i];
strncpy(event_cb->session_name, session_config->session_name, strlen(session_config->session_name));
event_cb->event = session_config->event;
event_cb->event_cb_ptr = (fn_session_event_callback *)(dlsym(module->dl_handle, session_config->cb_func_name));
if (event_cb->event_cb_ptr == NULL)
{
plugin_manager_log(ERROR, "can't find symbol name of '%s' in dynamic library %s, %s",
session_config->cb_func_name, dynamic_lib_path, dlerror());
goto err;
}
}
}
return module;
err:
plugin_manager_module_close(module);
return NULL;
}
int plugin_manager_module_register(struct plugin_manager *plug_mgr, struct plugin_manager_module *module)
{
if (module && module->evcbs)
{
for (int i = 0; i < module->evcbs_num; i++)
{
struct plugin_manager_module_evcb *event_cb = &module->evcbs[i];
if (plugin_manager_register(plug_mgr, event_cb->session_name, event_cb->event, event_cb->event_cb_ptr) == -1)
{
plugin_manager_log(ERROR, "dynamic library '%s' failed to register the event callback function of session '%s'", module->lib_path, event_cb->session_name);
return -1;
}
}
}
return 0;
}
int plugin_manager_module_init(struct plugin_manager_module *module)
{
struct timespec start;
struct timespec end;
clock_gettime(CLOCK_MONOTONIC, &start);
int ret = module->init_cb_ptr();
if (ret == -1)
{
plugin_manager_log(ERROR, "dynamic library '%s' initialization failed", module->lib_path);
return -1;
}
clock_gettime(CLOCK_MONOTONIC, &end);
long elapsed = (end.tv_sec - start.tv_sec) * 1000000 + (end.tv_nsec - start.tv_nsec) / 1000;
plugin_manager_log(INFO, "plugin '%s' init success, using '%lld' us", module->lib_path, elapsed);
return 0;
}
void plugin_manager_module_exit(struct plugin_manager_module *module)
{
if (module && module->exit_cb_ptr)
{
module->exit_cb_ptr();
}
}

View File

@@ -0,0 +1,12 @@
#pragma once
#include "plugin_manager_config.h"
struct plugin_manager_module;
struct plugin_manager_module *plugin_manager_module_open(struct plugin_manager_config *config);
int plugin_manager_module_register(struct plugin_manager *plug_mgr, struct plugin_manager_module *module);
int plugin_manager_module_init(struct plugin_manager_module *module);
void plugin_manager_module_exit(struct plugin_manager_module *module);
void plugin_manager_module_close(struct plugin_manager_module *module);

View File

@@ -0,0 +1,40 @@
#include <string.h>
#include <stdlib.h>
#include "plugin_manager_util.h"
char *safe_dup(const char *str)
{
if (str == NULL)
{
return NULL;
}
char *dup = safe_alloc(char, strlen(str) + 1);
memcpy(dup, str, strlen(str));
return dup;
}
void strcat_prefix_and_file(const char *prefix, const char *file, char *buff, int size)
{
char prefix_buffer[4096] = {0};
char file_buffer[4096] = {0};
char *ptr = NULL;
memcpy(prefix_buffer, prefix, strlen(prefix));
memcpy(file_buffer, file, strlen(file));
if (prefix_buffer[strlen(prefix_buffer) - 1] != '/')
{
prefix_buffer[strlen(prefix_buffer)] = '/';
}
file_buffer[strcspn(file_buffer, "\r\n")] = 0;
ptr = file_buffer;
if (file_buffer[0] == '.' && file_buffer[1] == '/')
{
ptr += 2;
}
snprintf(buff, size, "%s%s", prefix_buffer, ptr);
}

View File

@@ -0,0 +1,61 @@
#pragma once
#include <stdio.h>
#define MAX_PLUGIN_NUM 512
#define MAX_SESSION_NAME_LENGTH 32
/******************************************************************************
* Malloc
******************************************************************************/
#define safe_alloc(type, number) ((type *)calloc(number, sizeof(type)))
#define safe_free(ptr) \
{ \
if (ptr) \
{ \
free(ptr); \
ptr = NULL; \
} \
}
char *safe_dup(const char *str);
/******************************************************************************
* Logger
******************************************************************************/
enum plugin_manager_log_level
{
DEBUG = 0x11,
INFO = 0x12,
ERROR = 0x13,
};
#ifndef plugin_manager_log
#define plugin_manager_log(level, format, ...) \
{ \
switch (level) \
{ \
case DEBUG: \
fprintf(stdout, "PLUGIN_MANAGER [DEBUG] " format "\n", ##__VA_ARGS__); \
fflush(stdout); \
break; \
case INFO: \
fprintf(stdout, "PLUGIN_MANAGER [INFO] " format "\n", ##__VA_ARGS__); \
fflush(stdout); \
break; \
case ERROR: \
fprintf(stderr, "PLUGIN_MANAGER [ERROR] " format "\n", ##__VA_ARGS__); \
fflush(stderr); \
break; \
} \
}
#endif
/******************************************************************************
* Str
******************************************************************************/
void strcat_prefix_and_file(const char *prefix, const char *file, char *buff, int size);

View File

@@ -0,0 +1,18 @@
add_executable(gtest_plugin_manager
gtest_plugin_manager.cpp
)
target_link_libraries(
gtest_plugin_manager
gtest_main
plugin_manager
session_manager
toml
dl
)
include(GoogleTest)
gtest_discover_tests(gtest_plugin_manager)
add_subdirectory(test_plugins/plugins_library)
file(COPY test_plugins/plugins_config DESTINATION ./)

View File

@@ -0,0 +1,159 @@
#include <gtest/gtest.h>
#include "../plugin_manager_config.h"
#include "../plugin_manager.h"
#include "session_manager.h"
TEST(PLUGIN_MANAGER_TEST, plugin_manager_config_HTTP)
{
char prefix_path[] = "./";
char file_path[] = "./plugins_config/http_event_plugin/http_event_plugin.inf";
struct plugin_manager_config *config = plugin_mangager_config_create();
EXPECT_TRUE(config != nullptr);
EXPECT_TRUE(plugin_mangager_config_parse(config, prefix_path, file_path) == 0);
EXPECT_STREQ(config->prefix_path, "./");
EXPECT_STREQ(config->file_path, "./plugins_config/http_event_plugin/http_event_plugin.inf");
EXPECT_STREQ(config->plugin_section.init_func_name, "http_event_plugin_init");
EXPECT_STREQ(config->plugin_section.exit_func_name, "http_event_plugin_exit");
EXPECT_STREQ(config->plugin_section.lib_path, "./test_plugins/plugins_library/http_event_plugin_test.so");
EXPECT_TRUE(config->session_section_num == 1);
EXPECT_STREQ(config->session_section[0].session_name, "HTTP");
EXPECT_STREQ(config->session_section[0].cb_func_name, "http_event_plugin_entry");
EXPECT_TRUE(config->session_section[0].event == (0x01 << 1 | 0x01 << 2 | 0x01 << 3 | 0x01 << 4 | 0x01 << 5));
plugin_mangager_config_dump(config);
plugin_mangager_config_destory(config);
}
TEST(PLUGIN_MANAGER_TEST, plugin_manager_config_CUSTOM)
{
char prefix_path[] = "./";
char file_path[] = "./plugins_config/custom_event_plugin/custom_event_plugin.inf";
struct plugin_manager_config *config = plugin_mangager_config_create();
EXPECT_TRUE(config != nullptr);
EXPECT_TRUE(plugin_mangager_config_parse(config, prefix_path, file_path) == 0);
EXPECT_STREQ(config->prefix_path, "./");
EXPECT_STREQ(config->file_path, "./plugins_config/custom_event_plugin/custom_event_plugin.inf");
EXPECT_STREQ(config->plugin_section.init_func_name, "custom_plugin_init");
EXPECT_STREQ(config->plugin_section.exit_func_name, "custom_plugin_exit");
EXPECT_STREQ(config->plugin_section.lib_path, "./test_plugins/plugins_library/custom_event_plugin_test.so");
EXPECT_TRUE(config->session_section_num == 2);
EXPECT_STREQ(config->session_section[0].session_name, "TCP");
EXPECT_STREQ(config->session_section[0].cb_func_name, "custom_plugin_tcp_entry");
EXPECT_TRUE(config->session_section[0].event == (0x01 << 1 | 0x01 << 2 | 0x01 << 3 | 0x01 << 4 | 0x01 << 5));
EXPECT_STREQ(config->session_section[1].session_name, "CUSTOM");
EXPECT_STREQ(config->session_section[1].cb_func_name, "custom_plugin_custom_entry");
EXPECT_TRUE(config->session_section[1].event == (0x01 << 1) | (0x01 << 3) | (0x01 << 5));
plugin_mangager_config_dump(config);
plugin_mangager_config_destory(config);
}
TEST(PLUGIN_MANAGER_TEST, plugin_manager_load)
{
char prefix_path[] = "./";
char file_path[] = "./plugins_config/plugins.inf";
struct plugin_manager *plug_mgr = plugin_manager_create();
EXPECT_TRUE(plug_mgr != nullptr);
EXPECT_TRUE(plugin_manager_load(plug_mgr, prefix_path, file_path) == 0);
plugin_manager_unload(plug_mgr);
plugin_manager_destory(plug_mgr);
}
TEST(PLUGIN_MANAGER_TEST, plugin_manager_dispatch_HTTP)
{
char prefix_path[] = "./";
char file_path[] = "./plugins_config/plugins.inf";
const char *session_name = "HTTP";
struct stellar_session session;
session.name = session_name;
struct stellar_session_event_data event_data;
event_data.s = &session;
event_data.plugin_ctx = NULL; // must be init to NULL
struct stellar_event event;
event.session_event_data = &event_data;
struct plugin_manager *plug_mgr = plugin_manager_create();
EXPECT_TRUE(plug_mgr != nullptr);
EXPECT_TRUE(plugin_manager_load(plug_mgr, prefix_path, file_path) == 0);
event_data.type = SESSION_EVENT_OPENING;
plugin_manager_dispatch(plug_mgr, &event);
event_data.type = SESSION_EVENT_RAWPKT;
plugin_manager_dispatch(plug_mgr, &event);
event_data.type = SESSION_EVENT_ORDPKT;
plugin_manager_dispatch(plug_mgr, &event);
event_data.type = SESSION_EVENT_META;
plugin_manager_dispatch(plug_mgr, &event);
event_data.type = SESSION_EVENT_CLOSING;
plugin_manager_dispatch(plug_mgr, &event);
event_data.type = SESSION_EVENT_ALL;
plugin_manager_dispatch(plug_mgr, &event);
plugin_manager_unload(plug_mgr);
plugin_manager_destory(plug_mgr);
}
TEST(PLUGIN_MANAGER_TEST, plugin_manager_dispatch_CUSTOM)
{
char prefix_path[] = "./";
char file_path[] = "./plugins_config/plugins.inf";
const char *session_name = "CUSTOM";
struct stellar_session session;
session.name = session_name;
struct stellar_session_event_data event_data;
event_data.s = &session;
event_data.plugin_ctx = NULL; // must be init to NULL
struct stellar_event event;
event.session_event_data = &event_data;
struct plugin_manager *plug_mgr = plugin_manager_create();
EXPECT_TRUE(plug_mgr != nullptr);
EXPECT_TRUE(plugin_manager_load(plug_mgr, prefix_path, file_path) == 0);
event_data.type = SESSION_EVENT_OPENING;
plugin_manager_dispatch(plug_mgr, &event);
event_data.type = SESSION_EVENT_RAWPKT;
plugin_manager_dispatch(plug_mgr, &event);
event_data.type = SESSION_EVENT_ORDPKT;
plugin_manager_dispatch(plug_mgr, &event);
event_data.type = SESSION_EVENT_META;
plugin_manager_dispatch(plug_mgr, &event);
event_data.type = SESSION_EVENT_CLOSING;
plugin_manager_dispatch(plug_mgr, &event);
event_data.type = SESSION_EVENT_ALL;
plugin_manager_dispatch(plug_mgr, &event);
plugin_manager_unload(plug_mgr);
plugin_manager_destory(plug_mgr);
}
int main(int argc, char **argv)
{
::testing::InitGoogleTest(&argc, argv);
int ret = RUN_ALL_TESTS();
return ret;
}

View File

@@ -0,0 +1,14 @@
[PLUGINFO]
INIT_FUNC="custom_plugin_init"
EXIT_FUNC="custom_plugin_exit"
LIBRARY_PATH="./test_plugins/plugins_library/custom_event_plugin_test.so"
# Support SESSION_EVENT_TYPE: "SESSION_EVENT_OPENING", "SESSION_EVENT_RAWPKT", "SESSION_EVENT_ORDPKT", "SESSION_EVENT_META", "SESSION_EVENT_CLOSING", "SESSION_EVENT_ALL"
[SESSION_NAME.TCP]
SESSION_EVENT_TYPE=["SESSION_EVENT_ALL"]
SESSION_EVENT_CALLBACK="custom_plugin_tcp_entry"
[SESSION_NAME.CUSTOM]
SESSION_EVENT_TYPE=["SESSION_EVENT_OPENING","SESSION_EVENT_ORDPKT","SESSION_EVENT_CLOSING"]
SESSION_EVENT_CALLBACK="custom_plugin_custom_entry"

View File

@@ -0,0 +1,10 @@
[PLUGINFO]
INIT_FUNC="http_event_plugin_init"
EXIT_FUNC="http_event_plugin_exit"
LIBRARY_PATH="./test_plugins/plugins_library/http_event_plugin_test.so"
# Support SESSION_EVENT_TYPE: "SESSION_EVENT_OPENING", "SESSION_EVENT_RAWPKT", "SESSION_EVENT_ORDPKT", "SESSION_EVENT_META", "SESSION_EVENT_CLOSING", "SESSION_EVENT_ALL"
[SESSION_NAME.HTTP]
SESSION_EVENT_TYPE=["SESSION_EVENT_ALL"]
SESSION_EVENT_CALLBACK="http_event_plugin_entry"

View File

@@ -0,0 +1,4 @@
# Relative path, relative to the installation path of stellar
./plugins_config/http_event_plugin/http_event_plugin.inf
./plugins_config/custom_event_plugin/custom_event_plugin.inf

View File

@@ -0,0 +1,9 @@
add_library(custom_event_plugin_test SHARED
custom_event_plugin.cpp
)
set_target_properties(custom_event_plugin_test PROPERTIES PREFIX "")
add_library(http_event_plugin_test SHARED
http_event_plugin.cpp
)
set_target_properties(http_event_plugin_test PROPERTIES PREFIX "")

View File

@@ -0,0 +1,58 @@
#include "session.h"
#include "packet.h"
#include "plugin.h"
#include <stddef.h>
#include <stdlib.h>
#include <stdio.h>
static char *g_handler = NULL;
static void *custom_decode(const char *payload, uint16_t len, void **pme)
{
return NULL;
}
extern "C" void custom_plugin_tcp_entry(const struct stellar_session *s, enum session_event_type event, struct stellar_packet *p, const char *payload, uint16_t len, void **pme)
{
char **per_session_pme = (char **)pme;
printf("RUN custom_plugin_tcp_entry, event: %d\n", event);
struct stellar_session_event_extras *info = (struct stellar_session_event_extras *)custom_decode(payload, len, pme);
struct stellar_session *new_session = session_manager_session_derive(s, "CUSTOM");
session_manager_trigger_event(new_session, SESSION_EVENT_OPENING, info);
session_manager_trigger_event(new_session, SESSION_EVENT_META, info);
}
extern "C" void custom_plugin_custom_entry(const struct stellar_session *s, enum session_event_type event, struct stellar_packet *p, const char *payload, uint16_t len, void **pme)
{
char **per_session_pme = (char **)pme;
printf("RUN custom_plugin_custom_entry, event: %d\n", event);
}
extern "C" int custom_plugin_init(void)
{
printf("RUN custom_plugin_init\n");
if (g_handler == NULL)
{
g_handler = (char *)malloc(1024);
snprintf(g_handler, 1024, "222222");
}
return 0;
}
extern "C" void custom_plugin_exit(void)
{
printf("RUN custom_plugin_exit\n");
if (g_handler)
{
free(g_handler);
g_handler = NULL;
}
}

View File

@@ -0,0 +1,82 @@
#include "session.h"
#include "packet.h"
#include "plugin.h"
#include <stdlib.h>
#include <stdio.h>
static char *g_handler = NULL;
struct per_session_pme_info
{
int flag;
char data[16];
};
extern "C" void http_event_plugin_entry(const struct stellar_session *s, enum session_event_type event, struct stellar_packet *p, const char *payload, uint16_t len, void **pme)
{
struct per_session_pme_info **per_session_pme = (struct per_session_pme_info **)pme;
printf("RUN http_event_plugin_entry, event: %d\n", event);
if (event & SESSION_EVENT_OPENING)
{
if (*per_session_pme == NULL)
{
struct per_session_pme_info *cur_ctx = (struct per_session_pme_info *)malloc(sizeof(struct per_session_pme_info));
snprintf(cur_ctx->data, 6, "******");
*per_session_pme = *&cur_ctx;
printf("http_event_plugin_entry->opening_handler\n");
}
}
if (event & SESSION_EVENT_RAWPKT)
{
printf("http_event_plugin_entry->rawpkt_handler\n");
}
if (event & SESSION_EVENT_ORDPKT)
{
printf("http_event_plugin_entry->ordpkt_handler\n");
}
if (event & SESSION_EVENT_META)
{
printf("http_event_plugin_entry->meta_handler\n");
}
if (event & SESSION_EVENT_CLOSING)
{
if (*per_session_pme)
{
printf("http_event_plugin_entry->closing_hanler\n");
free(*per_session_pme);
*per_session_pme = NULL;
}
}
}
extern "C" int http_event_plugin_init(void)
{
printf("RUN http_event_plugin_init\n");
if (g_handler == NULL)
{
g_handler = (char *)malloc(1024);
snprintf(g_handler, 1024, "111111");
}
return 0;
}
extern "C" void http_event_plugin_exit(void)
{
printf("RUN http_event_plugin_exit\n");
if (g_handler)
{
free(g_handler);
g_handler = NULL;
}
}

View File

@@ -1,15 +1,10 @@
#include "http.h" #include "sdk/include/session.h"
#include "session_manager.h"
void http_decoder(const struct stellar_session *s, int what, struct stellar_packet *p, const char *payload, uint16_t len, void **pme) void http_decoder(const struct stellar_session *s, enum session_event_type event, struct stellar_packet *p, const char *payload, uint16_t len, void **pme)
{ {
struct stellar_session_event_extras *info; struct stellar_session_event_extras *info;
struct stellar_session *new_session=session_manager_session_derive(s, "HTTP"); struct stellar_session *new_session = session_manager_session_derive(s, "HTTP");
session_manager_trigger_event(new_session, SESSION_EVENT_OPENING, info); session_manager_trigger_event(new_session, SESSION_EVENT_OPENING, info);
session_manager_trigger_event(new_session, SESSION_EVENT_META, info); session_manager_trigger_event(new_session, SESSION_EVENT_META, info);
} }
int http_peek(const struct stellar_session *s, const char *payload, uint32_t len)
{
return 0;
}

View File

@@ -1,8 +1,12 @@
#include <stddef.h>
#include "sdk/include/session.h"
#include "session_manager.h" #include "session_manager.h"
struct session_manager struct session_manager
{ {
struct stellar_session **tcp_table, **udp_table; struct stellar_session **tcp_table;
struct stellar_session **udp_table;
}; };
struct session_manager *session_manager_init() struct session_manager *session_manager_init()
@@ -10,16 +14,12 @@ struct session_manager *session_manager_init()
return nullptr; return nullptr;
} }
void session_manager_trigger_event(struct stellar_session *s, enum session_event_type type, struct stellar_session_event_extras *info)
void session_manager_trigger_event(struct stellar_session *s,
enum session_event_type type,
struct stellar_session_event_extras *info)
{ {
return; return;
} }
struct stellar_session *session_manager_session_derive(const struct stellar_session *this_session, struct stellar_session *session_manager_session_derive(const struct stellar_session *this_session, const char *session_name)
const char *new_session_type_name)
{ {
return nullptr; return nullptr;
} }
@@ -29,8 +29,54 @@ struct stellar_event *session_manager_commit(struct session_manager *h, struct s
return nullptr; return nullptr;
}; };
struct stellar_event *session_manager_fetch_event(struct session_manager *h) struct stellar_event *session_manager_fetch_event(struct session_manager *h)
{ {
return nullptr; return nullptr;
} }
/******************************************************************************
* API: between stellar_event and plugin_manager
******************************************************************************/
struct session_plugin_ctx *stellar_event_get_plugin_ctx(struct stellar_event *event)
{
return event->session_event_data->plugin_ctx;
}
void stellar_event_set_plugin_ctx(struct stellar_event *event, struct session_plugin_ctx *plugin_ctx)
{
event->session_event_data->plugin_ctx = plugin_ctx;
}
enum session_event_type stellar_event_get_type(struct stellar_event *event)
{
return event->session_event_data->type;
}
const char *stellar_event_get_session_name(struct stellar_event *event)
{
return event->session_event_data->s->name;
}
const struct stellar_session *stellar_event_get_session(struct stellar_event *event)
{
return event->session_event_data->s;
}
// TODO
struct stellar_packet *stellar_event_get_packet(struct stellar_event *event)
{
return NULL;
}
// TODO
const char *stellar_event_get_payload(struct stellar_event *event)
{
return NULL;
}
// TODO
uint16_t stellar_event_get_payload_length(struct stellar_event *event)
{
return 0;
}

View File

@@ -2,8 +2,6 @@
#include "sdk/include/session.h" #include "sdk/include/session.h"
struct per_session_evcb_runtime_ctx;
struct stellar_session_event_data struct stellar_session_event_data
{ {
struct stellar_session *s; struct stellar_session *s;
@@ -18,10 +16,6 @@ struct session_manager *session_manager_init();
struct stellar_event *session_manager_commit(struct session_manager *session_mgr, struct stellar_packet *pkt); struct stellar_event *session_manager_commit(struct session_manager *session_mgr, struct stellar_packet *pkt);
struct stellar_event *session_manager_fetch_event(struct session_manager *session_mgr); struct stellar_event *session_manager_fetch_event(struct session_manager *session_mgr);
// interfaces for data interaction between stellar event and plugin manager
struct session_plugin_ctx *stellar_event_get_plugin_ctx(struct stellar_event *event);
void stellar_event_set_plugin_ctx(struct stellar_event *event, struct session_plugin_ctx *plugin_ctx);
struct stellar_session struct stellar_session
{ {
stellar_session_type type; stellar_session_type type;
@@ -29,3 +23,18 @@ struct stellar_session
void *addr; void *addr;
void *data; void *data;
}; };
/******************************************************************************
* API: between stellar_event and plugin_manager
******************************************************************************/
struct session_plugin_ctx *stellar_event_get_plugin_ctx(struct stellar_event *event);
void stellar_event_set_plugin_ctx(struct stellar_event *event, struct session_plugin_ctx *plugin_ctx);
enum session_event_type stellar_event_get_type(struct stellar_event *event);
const char *stellar_event_get_session_name(struct stellar_event *event);
const struct stellar_session *stellar_event_get_session(struct stellar_event *event);
struct stellar_packet *stellar_event_get_packet(struct stellar_event *event);
const char *stellar_event_get_payload(struct stellar_event *event);
uint16_t stellar_event_get_payload_length(struct stellar_event *event);