[c]解析类RFC2217协议

基于chatGPT答案

RFC 2217协议

RFC 2217 是一种远程串行端口协议,也称为 "COM port control protocol"。它定义了在客户端和服务器之间通过网络连接访问串行端口设备的标准通信协议。该协议可以允许客户端通过网络连接来访问串行设备,就像直接连接到本地串行端口一样。RFC 2217 不仅支持数据传输,还支持对串口线路控制信号(如 DTR、RTS 等)进行远程控制。RFC 2217 协议已被广泛采用,并且是自由开放的标准协议。

类RFC2217协议

RFC2217是一个通过以太网即时修改设备串口参数的一个标准协议,本设备支持一个类似RFC2217的协议,不是标准RFC2217,实现同样的功能,但是协议更简单。

RFC2217协议说明

协议长度为8个字节,具体协议内容如下,举例的数值为HEX格式:
image

来自 USR-C322配置类 RFC2217 自动波特率功能

RFC2217参数设置表
RFC2217参数设置

115200,N,8,1 55 AA 55 01 C2 00 83 46
115200,ODD,8,1 55 AA 55 01 C2 00 8B 4E
115200,EVEN,8,1 55 AA 55 01 C2 00 9B 5E
115200,N,7,1 55 AA 55 01 C2 00 82 45
115200,N,6,1 55 AA 55 01 C2 00 81 44
115200,N,8,1 55 AA 55 01 C2 00 83 46
115200,N,5,1 55 AA 55 01 C2 00 80 43
115200,N,8,2 55 AA 55 01 C2 00 87 4A
38400,N,8,1 55 AA 55 00 E1 00 83 64
19200,N,8,1 55 AA 55 00 4B 00 83 CE
57600,N,8,1 55 AA 55 00 E1 00 83 64
14400,N,8,1 55 AA 55 00 38 40 83 FB
9600,N,8,1 55 AA 55 00 25 80 83 28
4800,N,8,1 55 AA 55 00 12 C0 83 55
2400,N,8,1 55 AA 55 00 09 60 83 EC
1200,N,8,1 55 AA 55 00 04 B0 83 37
600,N,8,1 55 AA 55 00 02 58 83 DD
230400,N,8,1 55 AA 55 03 84 00 83 OA
460800,N,8,1 55 AA 55 07 08 00 83 92

思路

以下是可以用于解析 RFC 2217 协议的一些开源代码:

1. libtelnet:一个 C 语言实现的库,包括了 RFC 2217 的支持。可以通过该库轻松地实现远程串行端口连接。
2. ser2net:一个类似于 telnet 服务器的软件,可以将本地串口设备暴露为网络服务。它支持多种协议,包括 RFC 2217。
3. rfc2217:这是一个简单的命令行工具,用于建立基于 RFC 2217 的远程串行端口连接。它也是用 C 语言编写的,并且提供了源代码。

这些工具都提供了用于解析 RFC 2217 指令的 C 语言代码,您可以参考它们的源代码来编写您自己的RFC 2217指令解析程序。

demo

下面是一个简单的C语言程序,用于解析RFC2217协议的指令“55 AA 55 01 C2 00 83 46”:

#include <stdio.h>

int main() {
    unsigned char data[] = {0x55, 0xAA, 0x55, 0x01, 0xC2, 0x00, 0x83, 0x46};
    int i;

    printf("RFC2217 Command:\n");
    for(i = 0; i < sizeof(data); i++) {
        printf("%02X ", data[i]);
    }
    printf("\n");

    // 解析指令
    if(data[0] == 0x55 && data[1] == 0xAA && data[2] == 0x55 && data[3] == 0x01) {
        int baudrate = (data[4] << 24) | (data[5] << 16) | (data[6] << 8) | data[7];
        printf("Baudrate: %d\n", baudrate);
    }
    else {
        printf("Invalid Command.\n");
    }

    return 0;
}

程序首先将指令存储在一个无符号字符数组中。然后,它打印出指令的十六进制表示形式,以便我们可以检查它是否正确。接下来,它检查指令的前四个字节是否是RFC2217协议指令的标志(0x55 0xAA 0x55 0x01)。如果是,它将指令中的下一个四个字节解释为一个32位整数,表示波特率。最后,程序打印出波特率,并结束执行。如果指令不是RFC2217协议指令,程序将打印出“Invalid Command.”的错误信息。

解析用到的函数

memmem() 函数

memmem() 函数是 C 标准库中的一个函数,用于在内存块中查找一个子串。它的函数声明如下:

void *memmem(const void *haystack, size_t haystacklen,
             const void *needle, size_t needlelen);

该函数的参数含义如下:

haystack:指向要搜索的内存块的起始地址。
haystacklen:要搜索的内存块的长度(单位:字节)。
needle:指向要查找的子串的起始地址。
needlelen:要查找的子串的长度(单位:字节)。
该函数返回一个指向第一次出现子串的地址的指针,或者返回 NULL,如果没有找到子串则返回 NULL。

例如,以下代码将在一个内存块中查找一个特定的子串,并返回其地址:

const char* buf = "hello world";
size_t len = strlen(buf);
const char* sub = "world";
size_t sublen = strlen(sub);

const char* result = memmem(buf, len, sub, sublen);
if (result) {
    printf("Found substring at position %ld.\n", result - buf);
} else {
    printf("Substring not found.\n");
}

在上面的示例中,我们使用 memmem() 函数在一个字符串中查找另一个子串。在实际使用时,您可以根据需要修改参数类型和数据源。注意,该函数仅适用于查找较小的子串,因为在大型内存块中查找长子串可能会很慢。

posted @ 2023-03-21 01:11  dysonnnn  阅读(1263)  评论(0编辑  收藏  举报