linux 中的虚拟 UART 设备

问题描述 投票:0回答:1

我正在尝试使用 socat 命令实现虚拟 UART,用于发送和接收字符串,该字符串在发送时使用 XOR 密码进行加密,在接收时使用 C 程序进行解密。

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <fcntl.h>
#include <unistd.h>
#include <termios.h>

#define BUFFER_SIZE 256
#define UART_DEVICE_TX "./ttyV0"  // Transmit end
#define UART_DEVICE_RX "./ttyV1"  // Receive end

// XOR cipher for encryption and decryption
void xor_cipher(char *data, size_t length, char key) {
    for (size_t i = 0; i < length; ++i) {
        data[i] ^= key;
    }
}

// Configure the UART device
int configure_uart(const char *device) {
    int uart_fd = open(device, O_RDWR | O_NOCTTY);
    if (uart_fd < 0) {
        perror("Failed to open UART device");
        return -1;
    }

    struct termios options;
    tcgetattr(uart_fd, &options);

    // Set baud rate to 9600, 8 data bits, no parity, 1 stop bit
    cfsetispeed(&options, B9600);
    cfsetospeed(&options, B9600);
    options.c_cflag = (options.c_cflag & ~CSIZE) | CS8;  // 8 data bits
    options.c_cflag |= (CLOCAL | CREAD);                 // Enable receiver
    options.c_cflag &= ~(PARENB | CSTOPB);               // No parity, 1 stop bit
    options.c_iflag &= ~(IXON | IXOFF | IXANY);          // Disable flow control
    options.c_lflag = 0;                                 // Raw input mode
    options.c_oflag = 0;                                 // Raw output mode

    tcsetattr(uart_fd, TCSANOW, &options);
    return uart_fd;
}

int main() {
    const char key = 0x5A;          // XOR encryption key
    char original_message[] = "Hello, UART!";  // Original message
    char encrypted_message[BUFFER_SIZE];
    char received_message[BUFFER_SIZE];

    printf("Original message: %s\n", original_message);

    // Copy the original message and encrypt it
    strcpy(encrypted_message, original_message);
    xor_cipher(encrypted_message, strlen(encrypted_message), key);

    // Configure UART devices
    int uart_fd_tx = configure_uart(UART_DEVICE_TX);  // Transmit end
    int uart_fd_rx = configure_uart(UART_DEVICE_RX);  // Receive end
    if (uart_fd_tx < 0 || uart_fd_rx < 0) {
        return EXIT_FAILURE;
    }

    // Send the encrypted message to the TX port (master)
    write(uart_fd_tx, encrypted_message, strlen(encrypted_message));
    printf("Encrypted message sent: %s\n", encrypted_message);

    // Receive the encrypted message from the RX port (slave)
    memset(received_message, 0, BUFFER_SIZE);
    int bytes_read = read(uart_fd_rx, received_message, BUFFER_SIZE - 1);
    if (bytes_read < 0) {
        perror("Failed to read from UART device");
        close(uart_fd_tx);
        close(uart_fd_rx);
        return EXIT_FAILURE;
    }

    // Decrypt the received message
    xor_cipher(received_message, bytes_read, key);
    printf("Decrypted message: %s\n", received_message);

    // Check if the original and decrypted messages match
    if (strcmp(original_message, received_message) == 0) {
        printf("Decryption successful: Messages match.\n");
    } else {
        printf("Decryption failed: Messages do not match.\n");
    }

    // Clean up
    close(uart_fd_tx);
    close(uart_fd_rx);
    return EXIT_SUCCESS;
}

为了在工作目录中创建虚拟 uart 驱动程序,我使用了以下命令:

socat -d -d PTY,link=./ttyV0,raw,echo=0 PTY,link=./ttyV1,raw,echo=0

编译并运行c文件后,加密部分运行并在tty1上获取加密数据(

cat ./ttyV1

但是解密部分不起作用..我需要帮助来解决这个问题。

当我尝试不看设备时,它工作正常

原消息:你好,UART!

已发送加密消息:?665vz

收到加密消息:?665vz

解密消息:你好,UART!

解密成功:消息匹配。

当我在一个终端中启动 cat ./ttyV1 并运行该程序时,它将显示如下

原消息:你好,UART!

已发送加密消息:?665vz

不做解密部分

但是可以在运行 cat ./ttyV1 的另一个终端中看到密钥

为什么会出现这种情况?

c linux-device-driver embedded-linux uart socat
1个回答
0
投票

当打开的 TTY 接收数据时,数据将保存在缓冲区中,直到被打开 TTY 的进程之一读取为止。一旦它被进程读取,它就会被丢弃,并且不再可供其他进程读取。如果多个进程尝试从管道、FIFO 或套接字的接收端读取数据,也会发生同样的情况。

© www.soinside.com 2019 - 2024. All rights reserved.