Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .doc/CSM-TCP-Router 1.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified .doc/CSM-TCP-Router Sever BD.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
172 changes: 86 additions & 86 deletions .doc/CSM-TCP-Router.drawio

Large diffs are not rendered by default.

104 changes: 104 additions & 0 deletions .doc/Protocol.v0.(en).md
Original file line number Diff line number Diff line change
@@ -0,0 +1,104 @@
# Protocol Definition

The TCP packet format used in the CSM-TCP-Router is defined as follows:

``` txt
| Data Length (4B) | Version (1B) | TYPE (1B) | FLAG1 (1B) | FLAG2 (1B) | Text Data |
╰─────────────────────── Header (8B) ──────────────────────────────╯╰─── Data Length Range ──╯
```

## Header Fields

### Data Length (4 Bytes)

This field specifies the length of the data section and is represented using 4 bytes.

### Version (1 Byte)

This field indicates the version of the data packet. The current version is `0x01`. Different versions can be handled appropriately to ensure forward compatibility.

### Packet Type (1 Byte)

This field defines the type of the data packet and is an enumerated value. The supported packet types are:

- Information Packet (`info`) - `0x00`
- Error Packet (`error`) - `0x01`
- Command Packet (`cmd`) - `0x02`
- Synchronous Response Packet (`resp`) - `0x03`
- Asynchronous Response Packet (`async-resp`) - `0x04`
- Subscription Status Packet (`status`) - `0x05`

### FLAG1 (1 Byte)

This field is reserved for future use to describe additional attributes of the data packet.

### FLAG2 (1 Byte)

Similar to FLAG1, this field is reserved for future use to describe additional attributes of the data packet.

## Data Content

### Information Packet (`info`)

The content of an information packet is plain text containing informational data.

### Error Packet (`error`)

The content of an error packet is plain text describing an error, formatted as per the CSM Error format.

> [!NOTE]
> The CSM Error format is: `[Error: Error Code] Error Message`.

### Command Packet (`cmd`)

The content of a command packet is a command in the CSM local command format. It supports the following types of messages:

- Synchronous (`-@`)
- Asynchronous (`->`)
- Asynchronous without return (`->|`)
- Register (`register`)
- Unregister (`unregister`)

> [!NOTE]
> Example: Suppose there is a CSM module named `DAQmx` in the local program with an interface `API: Start Sampling`. You can send the following messages to control data acquisition:
>
> ``` c++
> API: Start Sampling -@ DAQmx // Synchronous message
> API: Start Sampling -> DAQmx // Asynchronous message
> API: Start Sampling ->| DAQmx // Asynchronous message without return
> ```
>
> These messages can also be sent over a TCP connection to achieve remote control.

> [!NOTE]
> Example: Suppose there is a CSM module `A` that continuously sends a monitoring status called `Status`. Another module `B` can subscribe to this status:
>
> ``` c++
> status@a >> api@b -><register> // Subscribe to status
> status@a >> api@b -><unregister> // Unsubscribe from status
> ```
>
> Similarly, these messages can be sent over a TCP connection to manage subscriptions remotely.
>
> If the subscriber (`api@b`) is omitted, it indicates that the client connected to the TCP router is subscribing to the status:
>
> ``` c++
> status@a -><register> // Client subscribes to module A's status
> status@a >> api@b -><unregister> // Client unsubscribes from module A's status
> ```
>
> When module `A` sends a `Status`, the client will automatically receive a `status` packet.

### Synchronous Response Packet (`resp`)

After executing a synchronous command, the TCP router sends a response packet back to the client.

### Asynchronous Response Packet (`async-resp`)

After executing an asynchronous command, the TCP router sends a response packet back to the client. The format is: `Response Data <- Original Asynchronous Message`.

### Subscription Status Packet (`status`)

When a client subscribes to the status of a CSM module, it will automatically receive this packet whenever the status changes.

The packet format is: `Status Name >> Status Data <- Sending Module`.
108 changes: 108 additions & 0 deletions .doc/Protocol.v0.(zh-cn).md
Original file line number Diff line number Diff line change
@@ -0,0 +1,108 @@
# 传输协议

CSM-TCP-Router 中 TCP 数据包格式定义如下:

``` txt
| 数据长度(4B) | 版本(1B) | TYPE(1B) | FLAG1(1B) | FLAG2(1B) | 文本数据 |
╰─────────────────────────── 包头 ──────────────────────────╯╰──── 数据长度字范围 ────╯
```

## 包头字段

### 数据长度(4字节)

数据长度为4字节,表示数据字段的长度。

### 版本信息(1字节)

版本信息为1字节,表示数据包的版本信息。当前的版本信息为 `0x01`。可以根据版本信息进行不同的处理,实现向前兼容。

### 数据包类型(1字节)

数据包类型用于描述数据包的内容,为枚举类型,目前支持的数据包类型有:

- 信息数据包(info) - `0x00`
- 错误数据包(error) - `0x01`
- 指令数据包(cmd) - `0x02`
- 同步响应数据包(resp) - `0x03`
- 异步响应数据包(async-resp) - `0x04`
- 订阅返回数据包(status) - `0x05`

### FLAG1类型(1字节)

FLAG1用于描述数据包的属性, 保留字段。

### FLAG2类型(1字节)

FLAG2用于描述数据包的属性, 保留字段。

## 数据内容

### 信息数据包(info)

info 数据包的数据内容为提示信息内容,纯文本格式。

### 错误数据包(error)

error 数据包的数据内容为错误信息内容,为纯文本格式,文本格式定为 CSM Error 格式。

> [!NOTE]
> CSM Error 格式为:"[Error: `错误代码`]`错误字符串`"。
>

### 指令数据包(cmd)

指令数据包的数据内容为指令内容,格式为 CSM 本地指令格式,支持:

- 同步(-@)
- 异步(->)
- 无返回异步(->|)消息,
- 注册(register)
- 注销(unregister)。

> [!NOTE]
> 举例:假设本地程序存在名为DAQmx的CSM模块,具有一个接口为 "API: Start Sampling".
> 本地我们可以发送消息给这个模块,控制采集的启停:
>
> ``` c++
> API: Start Sampling -@ DAQmx // 同步消息
> API: Start Sampling -> DAQmx // 异步消息
> API: Start Sampling ->| DAQmx // 异步无返回消息
> ```
>
> 现在只要通过TCP连接,发送同样的文本消息,就可以实现远程消息。
>

> [!NOTE]
> 举例:假设本地程序存在名为A的CSM模块,不停的发送一个监控状态为 "Status", 另外一个模块B可以订阅这个状态。
>
> ``` c++
> status@a >> api@b -><register> // 订阅状态
> status@a >> api@b -><unregister> // 取消订阅
> ```
>
> 现在只要通过TCP连接,发送同样的文本消息,就可以实现远程控制底层 csm 模块的订阅
>
> 但是如果发送中缺省了订阅方(api@b), 则表示连接到 tcp-router 的 client订阅状态
>
> ``` c++
> status@a -><register> // client 订阅 A 模块status
> status@a >> api@b -><unregister> // 取消 client 订阅 A 模块status
> ```
>
> 当 A 模块发出 Status 后,client 将自动收到 `status` 数据包
>

### 同步响应数据包(resp)

当执行完毕同步消息指令后,tcp-router 将 response 返回给 client.

### 异步响应数据包(async-resp)

当执行完毕同步消息指令后,tcp-router 将 response 返回给 client. 格式为:"`Response数据` <- `异步消息原文`"

### 订阅返回数据包(status)

Client 订阅了CSM模块的状态,当状态发生时,client 会自动收到此数据包。

数据包格式为 "状态名 >> `状态数据` <- 发送模块"
138 changes: 138 additions & 0 deletions .doc/Protocol.v1.(zh-cn).md
Original file line number Diff line number Diff line change
@@ -0,0 +1,138 @@
# 传输协议

CSM-TCP-Router 中 TCP 数据包格式定义如下:

``` txt
╭────────────────── CRC校验范围 ────────────────────╮
| 数据长度(4B) | 版本(1B) | FLAG1(1B) | FLAG2(1B) | TYPE(1B) | 文本长度(4B) | 文本数据 | 二进制长度(4B) | 二进制数据 | CRC(2B) |
╰─────────────────────────── 包头 ──────────────────────────╯╰──────────────────── 数据长度字范围 ──────────────────────────╯
```

## 包头字段

### 数据长度(4字节)

数据长度为4字节,表示数据字段的长度。

### 版本信息(1字节)

版本信息为1字节,表示数据包的版本信息。当前的版本信息为 `0x01`。可以根据版本信息进行不同的处理,实现向前兼容。

### FLAG1类型(1字节)

FLAG1用于描述数据包的属性

``` ini
FLAG_TEXT = 0b00000001 # 存在文本数据(置1时需解析文本长度+内容)
FLAG_BIN = 0b00000010 # 存在二进制数据(置1时需解析二进制长度+内容)
FLAG_CRC = 0B00010000 # 存在CRC校验(置1时需解析CRC校验)
```

### FLAG2类型(1字节)

FLAG2用于描述数据包的属性, 保留字段。

### 数据包类型(1字节)

数据包类型用于描述数据包的内容,为枚举类型,目前支持的数据包类型有:

- 信息数据包(info) - `0x00`
- 错误数据包(error) - `0x01`
- 指令数据包(cmd) - `0x02`
- 同步响应数据包(resp) - `0x03`
- 异步响应数据包(async-resp) - `0x04`
- 订阅返回数据包(status) - `0x05`

## 数据内容

当 FLAG1 的 `FLAG_TEXT` 为1时,数据包中存在文本数据。文本数据的格式为:`文本数据长度(4字节)` | `文本数据内容`。
当 FLAG1 的 `FLAG_BIN` 为1时,数据包中存在二进制数据。二进制数据的格式为:`二进制数据长度(4字节)` | `二进制数据内容`。

> [!NOTE]
> `数据包类型`决定了数据内容的格式, 主要规定了文本数据的内容。
>

> [!NOTE]
>
> 目前当文本数据格式中存在`MassData`类型的参数或返回数据时,才会有二进制数据。
>

### 文本数据

#### 信息数据包(info)

info 数据包的数据内容为提示信息内容,纯文本格式。

#### 错误数据包(error)

error 数据包的数据内容为错误信息内容,为纯文本格式,文本格式定为 CSM Error 格式。

> [!NOTE]
> CSM Error 格式为:"[Error: `错误代码`]`错误字符串`"。
>

#### 指令数据包(cmd)

指令数据包的数据内容为指令内容,格式为 CSM 本地指令格式,支持:

- 同步(-@)
- 异步(->)
- 无返回异步(->|)消息,
- 注册(register)
- 注销(unregister)。

> [!NOTE]
> 举例:假设本地程序存在名为DAQmx的CSM模块,具有一个接口为 "API: Start Sampling".
> 本地我们可以发送消息给这个模块,控制采集的启停:
>
> - API: Start Sampling -@ DAQmx // 同步消息
> - API: Start Sampling -> DAQmx // 异步消息
> - API: Start Sampling ->| DAQmx // 异步无返回消息
>
> 现在只要通过TCP连接,发送同样的文本消息,就可以实现远程消息。
>

> [!NOTE]
> 举例:假设本地程序存在名为A的CSM模块,不停的发送一个监控状态为 "Status", 另外一个模块B可以订阅这个状态。
>
> - status@a >> api@b -><register> // 订阅状态
> - status@a >> api@b -><unregister> // 取消订阅
>
> 现在只要通过TCP连接,发送同样的文本消息,就可以实现远程控制底层 csm 模块的订阅
>
> 但是如果发送中缺省了订阅方(api@b), 则表示连接到 tcp-router 的 client订阅状态
>
> - status@a -><register> // client 订阅 A 模块status
> - status@a >> api@b -><unregister> // 取消 client 订阅 A 模块status
>
> 当 A 模块发出 Status 后,client 将自动收到 `status` 数据包
>

#### 同步响应数据包(resp)

当执行完毕同步消息指令后,tcp-router 将 response 返回给 client.

#### 异步响应数据包(async-resp)

当执行完毕同步消息指令后,tcp-router 将 response 返回给 client. 格式为:"`Response数据` <- `异步消息原文`"

#### 订阅返回数据包(status)

Client 订阅了CSM模块的状态,当状态发生时,client 会自动收到此数据包。

数据包格式为 "状态名 >> `状态数据` <- 发送模块"

### 二进制数据

当大量数据需要进行传递时,使用二进制格式传输会在不损失精度的前提下节省带宽。目前支持 CSM MassData 数据格式,当文本描述中的参数、返回为 CSM MassData 数据时,MassData 指向的数据区域,将被放置在`二进制数据段` 传输。

> [!NOTE]
> 举例,假设本地程序存在名为DAQmx的CSM模块,具有一个接口为 "API: Read Data", 返回的 Response 为 MassData 格式
>
> 通常返回的纯文本描述为 <MassData>Start:100;Length:1000
>
> 此时,MassData 指向的数据区域,将被放置在`二进制数据段` 传输。

## CRC校验

当 FLAG1 的 `FLAG_CRC` 为1时,数据包中存在CRC校验。CRC校验为2字节,校验范围为数据内容段,不包括包头。
18 changes: 7 additions & 11 deletions CSM-TCP-Router.vipb
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
<VI_Package_Builder_Settings Version="2020.1" Created_Date="2023-09-27 14:21:53" Modified_Date="2025-02-28 15:22:55" Creator="liyao" Comments="" ID="87a1501566075aebed5513952fe62c41">
<VI_Package_Builder_Settings Version="2020.1" Created_Date="2023-09-27 14:21:53" Modified_Date="2025-03-26 22:57:17" Creator="liyao" Comments="" ID="d445ff5669eab75606fa3bc7f2771d1e">
<Library_General_Settings>
<Package_File_Name>NEVSTOP_lib_CSM_TCP_Router_Example</Package_File_Name>
<Library_Version>2025.2.0.2</Library_Version>
<Library_Version>2025.3.0.2</Library_Version>
<Auto_Increment_Version>false</Auto_Increment_Version>
<Library_Source_Folder>src</Library_Source_Folder>
<Library_Output_Folder>vip</Library_Output_Folder>
Expand All @@ -18,11 +18,10 @@
<Advanced_Settings>
<Package_Dependencies>
<Additional_External_Dependencies>jki_lib_tcp_server &gt;=5.0.0.8</Additional_External_Dependencies>
<Additional_External_Dependencies>nevstop_lib_communicable_state_machine &gt;=2025.2.28.95859</Additional_External_Dependencies>
<Additional_External_Dependencies>nevstop_lib_csm_api_string_arguments_support &gt;=2025.1.27.145038</Additional_External_Dependencies>
<Additional_External_Dependencies>nevstop_lib_csm_ini_static_variable_support &gt;=2025.2.28.100053</Additional_External_Dependencies>
<Additional_External_Dependencies>nevstop_lib_communicable_state_machine &gt;=2025.3.24.114002</Additional_External_Dependencies>
<Additional_External_Dependencies>nevstop_lib_csm_api_string_arguments_support &gt;=2025.3.14.155345</Additional_External_Dependencies>
<Additional_External_Dependencies>nevstop_lib_csm_ini_static_variable_support &gt;=2025.3.23.221959</Additional_External_Dependencies>
<Additional_External_Dependencies>nevstop_lib_csm_massdata_parameter_support &gt;=2024.12.31.84154</Additional_External_Dependencies>
<Additional_External_Dependencies>nevstop_lib_globalstop &gt;=2022.12.12.102654</Additional_External_Dependencies>
<Additional_External_Dependencies>oglib_error &gt;=4.2.0.23</Additional_External_Dependencies>
<Additional_External_Dependencies>oglib_time &gt;=4.0.1.3</Additional_External_Dependencies>
</Package_Dependencies>
Expand Down Expand Up @@ -75,11 +74,8 @@
<Copyright/>
<Packager>NEVSTOP</Packager>
<URL>https://github.com/NEVSTOP-LAB/CSM-TCP-Router-App</URL>
<Release_Notes>[add] add IP address/Port input dialog for client.
[update] update connection information
[update] update server/client VI icon
[fix] type "bye", client will exit, as the connection will be closed from server side.
[fix] minor fix. #5</Release_Notes>
<Release_Notes>[add] #4 support async message/register/unregister.
[update] #8 Remove GlobalStop Library, multiple clients instances could work simultaneously</Release_Notes>
</Description>
<Destinations>
<Toolkit_VIs>
Expand Down
Loading
Loading