diff --git a/README-CN.md b/README-CN.md index cb24ff34..39c85faf 100644 --- a/README-CN.md +++ b/README-CN.md @@ -8,59 +8,32 @@ [English](https://github.com/neugates/neuron/blob/main/README.md) | 简体中文 -Neuron 是一个工业物联网(IIoT)边缘工业协议网关软件,用于现代大数据技术,以发挥工业 4.0 的力量。它支持对多种工业协议的一站式访问,并将其转换为标准 MQTT 协议以访问工业物联网平台。 +Neuron 是一款工业物联网 (IIoT) 连接服务器,用于现代大数据和 AI/ML 技术,以利用工业 4.0 的力量。支持一站式接入数十种工业协议,并将其转换为MQTT协议,实现工业物联网平台与各种工业设备的互联互通。 -Neuron 2.0 版本对 1.x 版本中的部分非必要功能进行了精简,重点聚焦在工业协议的数据采集和转发功能上,以期为工业物联网平台建设提供更加高效灵活的一站式协议接入与管理。 +![neuron-overview](docs/pictures/neuron-final.png) -## 产品目标和功能 +以下是 Neuron 的一些重要特性: -Neuron 的设计目标是专注于工业物联网的数据采集、转发和汇聚:通过将来自繁杂多样工业设备的、不同协议类型的数据转换为统一标准的物联网 MQTT 消息,从而实现这些独立设备的互联互通,更好地融入工业物联网的大系统之中,进行远程的直接控制和信息获取。 +- 具有实时能力的边缘原生应用程序可以利用边缘端的低延迟网络。 +- 松耦合模块化 [架构设计](https://neugates.io/docs/en/latest/architecture.html) 通过可插拔模块扩展更多功能服务。 +- 支持可以在运行时更新设备和应用程序模块的热插件。 +- 支持多种工业设备协议,包括 Modbus、OPCUA、Ethernet/IP、IEC104、BACnet 等 [更多协议](https://neugates.io/docs/en/latest/module-plugins/module-list.html)。 +- 支持同时连接大量不同协议的工业设备。 +- 结合[eKuiper](https://www.lfedge.org/projects/ekuiper)提供的规则引擎功能,快速实现基于规则的设备控制或 AI/ML 分析。 +- 通过 [SparkplugB](https://neugates.io/docs/en/latest/use_cases.html) 解决方案支持对工业应用程序的数据访问,例如 MES 或 ERP、SCADA、historian 和数据分析软件。 +- 具有非常低的内存占用,小于 10M 的内存占用和 CPU 使用率,可以在 ARM、x86 和 RISC-V 等资源有限的硬件上运行。 +- 支持在本地安装可执行文件或部署在容器化环境中。 +- 控制工业设备,通过[API](https://neugates.io/docs/en/latest/api.html)和[MQTT](https://neugates.io/docs/en/latest/mqtt.html) 服务更改参数和数据标签。 +- 与其他 EMQ 产品高度集成,包括 EMQX、NanoMQ、eKuiper。 +- 核心框架和 Modbus、MQTT 和 eKuiper 的代码在 LGPLv3 的许可下开源。商业模块需要 [EMQ 许可证](https://neugates.io/docs/en/latest/getting-started/license_policy.html) 才能运行。 -我们希望 Neuron 既可以在低端嵌入式 Linux 设备中运行,也可以运行在有较大内存的 Linux 主机中,以支持大规模的连接设备和海量的数据点位。因此 Neuron 的设计需要能够有极少的内存占用和极低的 CPU 占用,同时具有良好的可伸缩性,可满足不同运行资源条件下的需求。 +欲了解更多信息,请访问我们的[主页](https://neugates.io)。 -Neuron 的主要功能和特性如下: +## 前提条件 -- 插件化的南向设备驱动和北向应用; -- 内置有轻量级的 Web Server,可以通过浏览器来配置和控制、监听设备; -- 可替换的 MQTT 客户端,可以通过 MQTT 接口来控制和读写设备; -- 支持同时连接大量不同协议的工业设备; -- 和 EMQ 的其他产品高度融合,包括 EMQ X、NanoMQ、eKuiper(由 EMQ 发起,现归属于 LF Edge 基金会维护运营) 等; -- 支持 Neuron 运行期更新设备驱动。 +[安装所需依赖项](https://github.com/neugates/neuron/blob/main/Install-dependencies.md) -功能的完整列表,请参阅[应用和驱动使用介绍](https://neugates.io/plugins)。 - -获取更多信息,请访问[官网](https://neugates.io)。 - -## 架构设计 - -现代的 CPU 大都已经是多核心的了,即便是用在嵌入式系统中比较低端的 ARM 和 Risc-V 架构的 CPU,也都拥有多核心的芯片。因此我们需要能够充分利用这些多核心 CPU ,也就是说,Neuron 需要具有非常好的多核多线程性能。为此,我们使用了 NNG 这个基础消息库,这是一个多线程的 IO 处理和消息处理的异步并发库,能够充分利用 CPU 的多个核心。 - -我们采用了星型总线这一组织形式:有一个消息路由中心,该消息路由基于 NNG 提供高效率的消息转发。消息的发送和接收是线程间通讯,使用共享 Buffer 和智能指针,没有任何的内存拷贝,具有非常高的效率。围绕着这个路由中心,是各个具体功能的节点,由 Adapter 和 Plugin 组成。这些节点既可以是内置固有的,如轻量级的 Web Server;也可以是动态增加的,如各种设备驱动、MQTT 客户端、eKuiper 接口等。这样的设计隔离了各个设备驱动和北向应用的功能模块之间的耦合,另外采用订阅-发布机制来实现数据流的分发和聚合,使得 Neuron 有着极大的灵活性。用户可以根据现场的工作情况动态增加和减少设备驱动的节点,具有良好的可配置性。另外,当运行 Neuron 的硬件 CPU 性能好、核心多、内存大时,Neuron 能支持更多的设备驱动节点、海量的数据点位、更大的数据吞吐量、更低的响应时间,具有良好的系统可伸缩性。 - -Neuron 采用了插件机制来支持变化多端的用户功能需求,用户可以根据应用场景的功能需求动态的加载不同功能的插件,得到有不同功能的节点。当设备驱动有 Bug 需要修复,或者有新的功能需要升级时,可以通过动态更新插件来解决问题,升级新功能。每个节点的运行是独立的,当升级一个节点的插件时,不会影响其他节点的运行,Neuron 也不需要重新启动。 - -Neuron的总体架构概览如下图所示: - -![arch-overview](docs/pictures/neuron-arch-overview.png) - -Neuron的总线拓扑结构和数据流的分散/汇聚如下图所示: - -![neuron-bus-topo](docs/pictures/neuron-bus-topo.png) - -![neuron-dataflow](docs/pictures/neuron-dataflow.png) - -Neuron的层次结构图如下图所示: - -![neuron-layers](docs/pictures/neuron-layers.png) - - -## 安装 - -### 安装依赖 - -[Install Required Dependencies](https://github.com/neugates/neuron/blob/main/Install-dependencies.md) - -### 编译 +## 编译 ```shell $ git clone https://github.com/emqx/neuron @@ -70,10 +43,6 @@ $ mkdir build && cd build $ cmake .. && make ``` -## 前端 -[下载前端包](https://github.com/emqx/neuron-dashboard/releases)。 -下载后的前端包,解压放到Neuron可执行目录下的dist目录中。 - ## 快速开始 ```shell @@ -83,7 +52,7 @@ $ ./neuron ## 单元测试 -运行所有单元测试 +运行所有的单元测试 ```shell $ cd build @@ -92,44 +61,64 @@ $ ctest --output-on-failure ## 功能测试 -运行所有功能测试 +运行所有的功能测试 ```shell -mosquitto -v & -pip3 install -r ft/requirements.txt -python3 -m robot -P ft/ --variable neuron_api:http -d ft/http_reports ft + +$ mosquitto -v & +$ pip3 install -r ft/requirements.txt +$ python3 -m robot -P ft/ --variable neuron_api:http -d ft/http_reports ft ``` ## 压力测试 -目录`ft/data/persistence/`下存放有用于压力测试的数据集。 +在目录`ft/data/persistence/`中有压力测试的数据集。 -可运行以下命令进行压力测试 +运行压力测试 ```shell # 安装依赖 -pip3 install -r ft/requirements.txt +$ pip3 install -r ft/requirements.txt # 使用http接口在数据集total-10k上进行测试 -python3 -m robot -P ft/ --variable neuron_api:http --variable dataset:total-10k -d ft/http-total-10k ft/pressure.test +$ python3 -m robot -P ft/ --variable neuron_api:http --variable dataset:total-10k -d ft/http-total-10k ft/pressure.test # 使用http接口在数据集total-50k上进行测试 -python3 -m robot -P ft/ --variable neuron_api:http --variable dataset:total-50k -d ft/http-total-50k ft/pressure.test +$ python3 -m robot -P ft/ --variable neuron_api:http --variable dataset:total-50k -d ft/http-total-50k ft/pressure.test # 如果使用mqtt接口则需要MQTT服务器,此例为mosquitto -mosquitto -v & +$ mosquitto -v & # 使用mqtt接口在数据集simple-1k上进行测试 -python3 -m robot -P ft/ --variable neuron_api:mqtt --variable dataset:simple-1k -d ft/mqtt-simple-1k ft/pressure.test +$ python3 -m robot -P ft/ --variable neuron_api:mqtt --variable dataset:simple-1k -d ft/mqtt-simple-1k ft/pressure.test + ``` +## Zlog + +在 zlog.conf 文件的规则中更改日志级别。可用的日志级别包括 INFO,DEBUG,NOTICE,WARN,ERROR 和 FATAL。 + +## 关系报告 + +以下是与 Neuron 开发相关的所有的 github repos: + +- [核心框架](https://github.com/emqx/neuron) - public +- Pluggable Modules - private +- [前端界面](https://github.com/emqx/neuron-dashboard) - public +- [官网文档](https://github.com/emqx/neuron-docs) - public + ## 社区 -您可通过以下途径与 Neuron 社区及开发者联系。 +请访问我们的 [官方网站](https://neugates.io),去了解如何在您的大数据和 IIoT 项目中使用 Neuron。 -- 论坛:https://askemq.com/c/neuron/8 -- GitHub Discussions:https://github.com/emqx/neuron/discussions -- Slack:https://slack-invite.emqx.io/ -- Discord:https://discord.gg/xYGf3fQnES +如果您发现任何 bug 或者问题,请您反馈到 [Github Issues](https://github.com/emqx/neuron/issues) 中。非常感谢您的帮助。 +You can connect with the Neuron community and developers in the following ways. +您可以通过以下方式与 Neuron 社区和开发人员联系 + +- [Github Discussions](https://github.com/emqx/neuron/discussions) +- [Slack](https://slack-invite.emqx.io/) +- [Discord](https://discord.gg/xYGf3fQnES) + +作者:EMQ Neuron 工业物联网团队 diff --git a/README.md b/README.md index 925fdd41..875ecd87 100644 --- a/README.md +++ b/README.md @@ -27,7 +27,6 @@ The following are some important features of Neuron: - Highly integrated with other EMQ products, including EMQX, NanoMQ, eKuiper. - The code of the core framework and Modbus, MQTT and eKuiper are licensed under open source LGPLv3. Commercial modules require a [EMQ License](https://neugates.io/docs/en/latest/getting-started/license_policy.html) to run. - For more information, please visit our [Homepage](https://neugates.io). ## Prerequisite @@ -65,9 +64,9 @@ $ ctest --output-on-failure To run all functional testers ```shell -mosquitto -v & -pip3 install -r ft/requirements.txt -python3 -m robot -P ft/ --variable neuron_api:http -d ft/http_reports ft +$ mosquitto -v & +$ pip3 install -r ft/requirements.txt +$ python3 -m robot -P ft/ --variable neuron_api:http -d ft/http_reports ft ``` @@ -79,21 +78,25 @@ To run pressure tests ```shell # python dependencies -pip3 install -r ft/requirements.txt +$ pip3 install -r ft/requirements.txt # through http api, on dataset total-10k -python3 -m robot -P ft/ --variable neuron_api:http --variable dataset:total-10k -d ft/http-total-10k ft/pressure.test +$ python3 -m robot -P ft/ --variable neuron_api:http --variable dataset:total-10k -d ft/http-total-10k ft/pressure.test # through http api, on dataset total-50k -python3 -m robot -P ft/ --variable neuron_api:http --variable dataset:total-50k -d ft/http-total-50k ft/pressure.test +$ python3 -m robot -P ft/ --variable neuron_api:http --variable dataset:total-50k -d ft/http-total-50k ft/pressure.test # A MQTT broker is needed if using the mqtt api, mosquitto in this example -mosquitto -v & +$ mosquitto -v & # through mqtt api, on dataset simple-1k -python3 -m robot -P ft/ --variable neuron_api:mqtt --variable dataset:simple-1k -d ft/mqtt-simple-1k ft/pressure.test +$ python3 -m robot -P ft/ --variable neuron_api:mqtt --variable dataset:simple-1k -d ft/mqtt-simple-1k ft/pressure.test ``` +## Zlog + +Change the log level in the rules in the zlog.conf file. Available levels include INFO, DEBUG, NOTICE, WARN, ERROR and FATAL. + ## Relational Repos The following are all the github repos related to Neuron development. @@ -103,17 +106,16 @@ The following are all the github repos related to Neuron development. - [Dashboard](https://github.com/emqx/neuron-dashboard) - public - [Documentation](https://github.com/emqx/neuron-docs) - public - ## Community Please visit our [offical website](https://neugates.io) to have a good inspiration of how to apply Neuron in your big data and IIoT project. -If you found any bugs or issues, please drop it in [Github Issues](https://github.com/emqx/neuron/issues). Your help is much appriceiated. +If you found any bugs or issues, please drop it in [Github Issues](https://github.com/emqx/neuron/issues). Your help is much appriceiated. You can connect with the Neuron community and developers in the following ways. - [Github Discussions](https://github.com/emqx/neuron/discussions) - [Slack](https://slack-invite.emqx.io/) -- [Discord](https://discord.gg/xYGf3fQnES) +- [Discord](https://discord.gg/xYGf3fQnES) By EMQ Neuron Industrial IoT Team diff --git a/ft/persist_test.robot b/ft/persist_test.robot index 07594773..d546deb7 100644 --- a/ft/persist_test.robot +++ b/ft/persist_test.robot @@ -21,7 +21,7 @@ ${tag4} {"name": "tag4", "address": "2!400005", "attribute": ${TAG_A ${tag5} {"name": "tag5", "address": "2!400006", "attribute": ${TAG_ATTRIBUTE_READ}, "type": ${TAG_TYPE_INT16}} ${tag6} {"name": "tag6", "address": "2!400007", "attribute": ${TAG_ATTRIBUTE_READ}, "type": ${TAG_TYPE_INT16}} ${tag7} {"name": "tag7", "address": "2!400008", "attribute": ${TAG_ATTRIBUTE_READ}, "type": ${TAG_TYPE_INT16}} -${tag8} {"name": "tag8", "address": "2!400009", "attribute": %{TAG_ATTRIBUTE_READ}, "type": ${TAG_TYPE_INT16}} +${tag8} {"name": "tag8", "address": "2!400009", "attribute": ${TAG_ATTRIBUTE_READ}, "type": ${TAG_TYPE_INT16}} *** Test Cases *** Get the newly added adapters after stopping and restarting Neuron, it should return success diff --git a/include/neuron/connection/neu_connection.h b/include/neuron/connection/neu_connection.h index 03684b4a..36f40f85 100644 --- a/include/neuron/connection/neu_connection.h +++ b/include/neuron/connection/neu_connection.h @@ -67,7 +67,7 @@ typedef enum neu_conn_tty_flow { NEU_CONN_TTYP_FLOW_ENABLE, } neu_conn_tty_flow_e; -typedef void (*neu_conn_callback)(void *data, int fd); +typedef void (*neu_conn_callback)(void *ctx, int fd); typedef struct neu_conn_param { zlog_category_t *log; @@ -111,53 +111,126 @@ typedef struct neu_conn_param { typedef struct neu_conn neu_conn_t; -neu_conn_t *neu_conn_new(neu_conn_param_t *param, void *data, +/** + * @brief create a new connection. + * + * @param[in] param required to create a connection. + * @param[in] ctx Mainly used in the neu_conn_callback callback function. + * @param[in] connected The neu_conn_callback callback function will be + * triggered when the connection is successful. + * @param[in] disconnected The callback function of neu_conn_callback will be + * triggered when the connection fails. + * @return Connection on success, NULL on failure. + */ +neu_conn_t *neu_conn_new(neu_conn_param_t *param, void *ctx, neu_conn_callback connected, neu_conn_callback disconnected); -neu_conn_t *neu_conn_reconfig(neu_conn_t *conn, neu_conn_param_t *param); -void neu_conn_destory(neu_conn_t *conn); -void neu_conn_disconnect(neu_conn_t *conn); -int neu_conn_tcp_server_accept(neu_conn_t *conn); -int neu_conn_tcp_server_close_client(neu_conn_t *conn, int fd); +/** + * @brief Reconfigure the connection. + * + * @param[in] conn Connection that need to be configured. + * @param[in] param New configuration parameters for the connection. + * @return Connection on success, NULL on failure. + */ +neu_conn_t *neu_conn_reconfig(neu_conn_t *conn, neu_conn_param_t *param); + +/** + * @brief Destroy connection + * + * @param conn + */ +void neu_conn_destory(neu_conn_t *conn); + +/** + * @brief Disconnect + * + * + * @param[in] conn + */ +void neu_conn_disconnect(neu_conn_t *conn); + +/** + * @brief Receive connection requests from clients. + * + * @param[in] conn + * @return Successfully returns a number greater than 0, i.e. client fd, -1 on + * failure. + */ +int neu_conn_tcp_server_accept(neu_conn_t *conn); + +/** + * @brief Close a client connection. + * + * @param[in] conn + * @param[in] fd Get the fd from neu_conn_tcp_server_accept function. + * @return 0 on success, -1 on failure. + */ +int neu_conn_tcp_server_close_client(neu_conn_t *conn, int fd); + +/** + * @brief Send data over the connection. + * + * @param[in] conn + * @param[in] buf Store the data to be sent. + * @param[in] len Length of data to be sent. + * @return When greater than 0, returns the number of bytes successfully sent, + * less than or equal to 0 fails. + */ ssize_t neu_conn_send(neu_conn_t *conn, uint8_t *buf, ssize_t len); + +/** + * @brief Receive data via connection read. + * + * @param[in] conn + * @param[in] buf The received data is stored in buf. + * @param[in] len Length of buf. + * @return When greater than 0, it will return the number of bytes successfully + * received, less than or equal to 0 fails. + */ ssize_t neu_conn_recv(neu_conn_t *conn, uint8_t *buf, ssize_t len); +/** + * @brief Specify the client to send data. + * + * @param[in] conn + * @param[in] fd Client's file descriptor. + * @param[in] buf Store the data to be sent. + * @param[in] len Length of data to be sent. + * @return When greater than 0, returns the number of bytes successfully sent, + * less than or equal to 0 fails. + */ ssize_t neu_conn_tcp_server_send(neu_conn_t *conn, int fd, uint8_t *buf, ssize_t len); + +/** + * @brief Receive data via tcp server connection read. + * + * @param[in] conn + * @param[in] fd Client's file descriptor. + * @param[in] buf The received data is stored in buf. + * @param[in] len Length of buf. + * @return When greater than 0, returns the number of bytes successfully + * received, less than or equal to 0 fails. + */ ssize_t neu_conn_tcp_server_recv(neu_conn_t *conn, int fd, uint8_t *buf, ssize_t len); -#define NEU_STREAM_CONSUME(buf, size) \ - neu_protocol_unpack_buf_t protocol_buf = { 0 }; \ - neu_protocol_unpack_buf_init(&protocol_buf, (buf), (size)); \ - while (neu_protocol_unpack_buf_unused_size(&protocol_buf) > 0) - -#define NEU_STREAM_CONSUME_USED_SIZE(used) \ - offset -= used; \ - memmove(recv_buf, recv_buf + used, offset); - -#define NEU_TCP_CLIENT_CONSUME(conn) \ - static __thread uint8_t recv_buf[2048] = { 0 }; \ - static __thread uint16_t offset = 0; \ - ssize_t ret = \ - neu_conn_recv((conn), recv_buf + offset, sizeof(recv_buf) - offset); \ - if (ret > 0) \ - offset += ret; \ - if (ret > 0) \ - NEU_STREAM_CONSUME(recv_buf, offset) - typedef int (*neu_conn_stream_consume_fn)( void *context, neu_protocol_unpack_buf_t *protocol_buf); + void neu_conn_stream_consume(neu_conn_t *conn, void *context, neu_conn_stream_consume_fn fn); + void neu_conn_stream_tcp_server_consume(neu_conn_t *conn, int fd, void *context, neu_conn_stream_consume_fn fn); typedef neu_buf_result_t (*neu_conn_process_msg)( void *context, neu_protocol_unpack_buf_t *protocol_buf); + int neu_conn_wait_msg(neu_conn_t *conn, void *context, uint16_t n_byte, neu_conn_process_msg fn); + int neu_conn_tcp_server_wait_msg(neu_conn_t *conn, int fd, void *context, uint16_t n_byte, neu_conn_process_msg fn); diff --git a/include/neuron/event/event.h b/include/neuron/event/event.h index b4f68877..32e1a627 100644 --- a/include/neuron/event/event.h +++ b/include/neuron/event/event.h @@ -28,21 +28,53 @@ extern "C" { typedef struct neu_events neu_events_t; +/** + * @brief Creat a new event. + * When an event is created, a corresponding thread is created, and both + * io_event and timer_event in this event are scheduled for processing in this + * thread. + * @return the newly created event. + */ neu_events_t *neu_event_new(void); -int neu_event_close(neu_events_t *events); + +/** + * @brief Close a event. + * + * @param[in] events + * @return 0 on successful shutdown. + */ +int neu_event_close(neu_events_t *events); typedef struct neu_event_timer neu_event_timer_t; typedef int (*neu_event_timer_callback)(void *usr_data); typedef struct neu_event_timer_param { - int64_t second; - int64_t millisecond; - void * usr_data; + // timer trigger period + int64_t second; + int64_t millisecond; + // Parameters passed to callback when timer fires + void *usr_data; + // Callback function that fires every time the timer fires neu_event_timer_callback cb; } neu_event_timer_param_t; +/** + * @brief Add a timer to the event. + * + * @param[in] events + * @param[in] timer Parameters when creating timer. + * @return The added event timer. + */ neu_event_timer_t *neu_event_add_timer(neu_events_t * events, neu_event_timer_param_t timer); + +/** + * @brief Remove timer from event. + * + * @param[in] events + * @param[in] timer + * @return 0 on success. + */ int neu_event_del_timer(neu_events_t *events, neu_event_timer_t *timer); enum neu_event_io_type { @@ -55,13 +87,33 @@ typedef int (*neu_event_io_callback)(enum neu_event_io_type type, int fd, void *usr_data); typedef struct neu_event_io_param { - int fd; - void * usr_data; + // fd that fires io_event. + int fd; + // Arguments passed to the neu_event_io_callback callback function when the + // io_event is fired. + void *usr_data; + // The neu_event_io_callback callback function is triggered when io_event is + // triggered. neu_event_io_callback cb; } neu_event_io_param_t; +/** + * @brief Add io_event to the event. + * + * @param[in] events + * @param[in] io + * @return The added event io. + */ neu_event_io_t *neu_event_add_io(neu_events_t *events, neu_event_io_param_t io); -int neu_event_del_io(neu_events_t *events, neu_event_io_t *io); + +/** + * @brief Delete io_event from event. + * + * @param[in] events + * @param[in] io + * @return 0 on success. + */ +int neu_event_del_io(neu_events_t *events, neu_event_io_t *io); #ifdef __cplusplus } diff --git a/include/neuron/plugin.h b/include/neuron/plugin.h index 21c7e77e..85a809a0 100644 --- a/include/neuron/plugin.h +++ b/include/neuron/plugin.h @@ -97,9 +97,32 @@ neu_plugin_to_plugin_common(neu_plugin_t *plugin) return (neu_plugin_common_t *) plugin; } +/** + * @brief when creating a node, initialize the common parameter in + * the plugin. + * + * @param[in] common refers to common parameter in plugins. + */ void neu_plugin_common_init(neu_plugin_common_t *common); + +/** + * @brief Check the common parameter in the plugin. + * + * @param[in] plugin represents plugin information. + * @return Returns true if the check is correct,false otherwise. + */ bool neu_plugin_common_check(neu_plugin_t *plugin); +/** + * @brief Encapsulate the request,convert the request into a message and send. + * + * @param[in] plugin + * @param[in] head the request header function. + * @param[in] data that different request headers correspond to different data. + * + * @return 0 for successful message processing, non-0 for message processing + * failure. + */ int neu_plugin_op(neu_plugin_t *plugin, neu_reqresp_head_t head, void *data); #ifdef __cplusplus diff --git a/include/neuron/tag.h b/include/neuron/tag.h index 9e7e4352..9fd79b9c 100644 --- a/include/neuron/tag.h +++ b/include/neuron/tag.h @@ -87,6 +87,14 @@ inline static bool neu_tag_attribute_test(neu_datatag_t * tag, UT_icd *neu_tag_get_icd(); +/** + * @brief Special usage of parsing tag address, e.g. setting length of string + * type, setting of endian. + * + * @param[in] datatag contains all the information about the tag. + * @param[in] option contain actions that the label can perform. + * @return 0 on success, -1 on failure. + */ int neu_datatag_parse_addr_option(neu_datatag_t * datatag, neu_datatag_addr_option_u *option); diff --git a/include/neuron/tag_sort.h b/include/neuron/tag_sort.h index 4d31583d..3f15cc19 100644 --- a/include/neuron/tag_sort.h +++ b/include/neuron/tag_sort.h @@ -55,9 +55,22 @@ typedef struct { typedef bool (*neu_tag_sort_fn)(neu_tag_sort_t *sort, void *tag, void *tag_to_be_sorted); +/** + * @brief Use sort and cmp to sort and classify tags. + * + * @param[in] tags The tags that needs to be processed. + * @param[in] sort Function for tag sort. + * @param[in] cmp Function for tags comparison. + * @return processed tags. + */ neu_tag_sort_result_t *neu_tag_sort(UT_array *tags, neu_tag_sort_fn sort, neu_tag_sort_cmp cmp); +/** + * @brief free the result. + * + * @param[in] result the tags result that needs to be relesed. + */ void neu_tag_sort_free(neu_tag_sort_result_t *result); #ifdef __cplusplus diff --git a/include/neuron/utils/async_queue.h b/include/neuron/utils/async_queue.h index 442bdb9e..be896bad 100644 --- a/include/neuron/utils/async_queue.h +++ b/include/neuron/utils/async_queue.h @@ -30,15 +30,53 @@ typedef bool (*neu_async_queue_expire)(void *elem); typedef void (*neu_async_queue_free)(void *elem); typedef bool (*neu_async_queue_filter)(void *filter_elem, void *elem); +/** + * @brief Create a new asynchronous queue. + * + * @param[in] key_fn Calculate the key of the element. + * @param[in] expire_fn Element invalidation check function in queue. + * @param[in] free_fn Release expired elements and elements that exceed the + * queue length. + * @param[in] max_size Maximum length of the queue. + * @return a created async queue. + */ neu_async_queue_t *neu_async_queue_new(neu_async_queue_key key_fn, neu_async_queue_expire expire_fn, neu_async_queue_free free_fn, uint16_t max_size); +/** + * @brief destroy queue. + * + * @param[in] q the queue that needs to be destroyed. + */ void neu_async_queue_destroy(neu_async_queue_t *q); -void neu_async_queue_push(neu_async_queue_t *q, void *elem); -int neu_async_queue_pop(neu_async_queue_t *q, uint64_t key, void **elem); +/** + * @brief Add element at the end of the queue. + * + * @param[in] q the queue that requires an operation. + * @param[in] elem that needs to be added at the end of the queue. + */ +void neu_async_queue_push(neu_async_queue_t *q, void *elem); + +/** + * @brief Pop the element corrseponding to key in the queue. + * + * @param[in] q the queue that requires an operation. + * @param[in] key + * @param[out] elem that needs to be deleted at the end of the queue. + * @return 0 for success, -1 for failure. + */ +int neu_async_queue_pop(neu_async_queue_t *q, uint64_t key, void **elem); + +/** + * @brief remove some elements from the queue. + * + * @param[in] q the queue that requires an operation. + * @param[in] filter element comparison function. + * @param[in] filter_elem + */ void neu_async_queue_remove(neu_async_queue_t *q, neu_async_queue_filter filter, void *filter_elem); diff --git a/include/neuron/utils/base64.h b/include/neuron/utils/base64.h index 6b9ba37c..69286d0c 100644 --- a/include/neuron/utils/base64.h +++ b/include/neuron/utils/base64.h @@ -24,7 +24,23 @@ extern "C" { #endif -char * neu_encode64(const unsigned char *input, int length); +/** + * @brief base64 encoding. + * + * @param[in] input Data to be encoded. + * @param[in] length Length of data to be encoded. + * @return Encoded data. + */ + +char *neu_encode64(const unsigned char *input, int length); + +/** + * @brief base64 decoding. + * + * @param[out] length Pointer to the length of the decoded data. + * @param[in] input Data to be decoded. + * @return The decoded data. + */ unsigned char *neu_decode64(int *length, const char *input); #ifdef __cplusplus diff --git a/include/neuron/utils/protocol_buf.h b/include/neuron/utils/protocol_buf.h index ad2f05e9..d8ff7895 100644 --- a/include/neuron/utils/protocol_buf.h +++ b/include/neuron/utils/protocol_buf.h @@ -35,6 +35,13 @@ typedef struct { uint16_t offset; } neu_protocol_buf_t, neu_protocol_pack_buf_t, neu_protocol_unpack_buf_t; +/** + * @brief Initialization of protocol_pack_buf. + * + * @param[in] buf neu_protocol_pack_buf_t to be initialized. + * @param[in] base Memory used in protocol_pack_buf. + * @param[in] size Size of base memory. + */ inline static void neu_protocol_pack_buf_init(neu_protocol_pack_buf_t *buf, uint8_t *base, uint16_t size) { @@ -43,6 +50,13 @@ inline static void neu_protocol_pack_buf_init(neu_protocol_pack_buf_t *buf, buf->offset = size; } +/** + * @brief Initialization of protocol_unpack_buf. + * + * @param[in] buf neu_protocol_unpack_buf_t to be initialized. + * @param[in] base Memory used in protocol_unpack_buf. + * @param[in] size Size of base memory. + */ inline static void neu_protocol_unpack_buf_init(neu_protocol_unpack_buf_t *buf, uint8_t *base, uint16_t size) {