#include <stdio.h>
#include <stdint.h>
#include <string.h>
#include <stdbool.h>
// N_PDU类型定义
typedef enum {
    N_PDU_SINGLE_FRAME = 0,    // 单帧
    N_PDU_FIRST_FRAME = 1,     // 首帧  
    N_PDU_CONSECUTIVE_FRAME = 2, // 连续帧
    N_PDU_FLOW_CONTROL = 3     // 流控帧
} N_PDU_TYPE;
// 流控状态
typedef enum {
    FLOW_CONTROL_CONTINUE = 0,  // 继续发送
    FLOW_CONTROL_WAIT = 1,      // 等待
    FLOW_CONTROL_OVERFLOW = 2   // 溢出
} FLOW_CONTROL_STATUS;
// N_PDU帧结构
typedef struct {
    uint8_t pci;               // 协议控制信息
    uint8_t data[4096];        // 数据域
    uint16_t data_length;      // 数据长度
    N_PDU_TYPE frame_type;     // 帧类型
} N_PDU_FRAME;// 多帧传输上下文

typedef struct {
    uint8_t sequence_number;   // 序列号
    uint16_t total_length;     // 总数据长度
    uint16_t received_bytes;   // 已接收字节数
    uint8_t buffer[4096];      // 数据缓冲区
    bool transmission_active;  // 传输是否活跃
} MULTI_FRAME_CONTEXT;

定义以上数据结构。

函数部分:

// 创建单帧
bool create_single_frame(const uint8_t* data, uint16_t data_len, N_PDU_FRAME* frame) {
    if (data_len > 7 || data == NULL || frame == NULL) {
        return false;
    }    
// PCI: 高4位为类型(0), 低4位为数据长度
    frame->pci = (N_PDU_SINGLE_FRAME << 4) | (data_len & 0x0F);   
    memcpy(frame->data, data, data_len);
    frame->data_length = data_len;
    frame->frame_type = N_PDU_SINGLE_FRAME;
    
    return true;
}
// 创建首帧
bool create_first_frame(const uint8_t* data, uint16_t total_len, N_PDU_FRAME* frame) {
    if (total_len > 4095 || data == NULL || frame == NULL) {
        return false;
    }
    
    // PCI: 高4位为类型(1), 低4位为长度的高4位
    // 首帧数据前两个字节存储总长度
    frame->pci = (N_PDU_FIRST_FRAME << 4) | ((total_len >> 8) & 0x0F);
    frame->data[0] = total_len & 0xFF;  // 长度低字节
    frame->data[1] = (total_len >> 8) & 0xFF; // 长度高字节
    
    // 复制剩余数据(如果有)
    uint16_t copy_len = (total_len > 6) ? 6 : total_len;
    if (copy_len > 0) {
        memcpy(&frame->data[2], data, copy_len);
    }
    
    frame->data_length = 2 + copy_len;
    frame->frame_type = N_PDU_FIRST_FRAME;
    
    return true;
}

// 创建连续帧
bool create_consecutive_frame(uint8_t sequence_number, const uint8_t* data, 
                             uint16_t data_len, N_PDU_FRAME* frame) {
    if (sequence_number > 15 || data_len > 7 || frame == NULL) {
        return false;
    }
    
    // PCI: 高4位为类型(2), 低4位为序列号
    frame->pci = (N_PDU_CONSECUTIVE_FRAME << 4) | (sequence_number & 0x0F);
    memcpy(frame->data, data, data_len);
    frame->data_length = data_len;
    frame->frame_type = N_PDU_CONSECUTIVE_FRAME;
    
    return true;
}

// 创建流控帧
bool create_flow_control_frame(FLOW_CONTROL_STATUS status, uint8_t block_size, 
                              uint8_t separation_time, N_PDU_FRAME* frame) {
    if (frame == NULL) return false;
    
    // PCI: 高4位为类型(3), 低4位为流控状态
    frame->pci = (N_PDU_FLOW_CONTROL << 4) | (status & 0x0F);
    frame->data[0] = block_size;
    frame->data[1] = separation_time;
    frame->data_length = 2;
    frame->frame_type = N_PDU_FLOW_CONTROL;
    
    return true;
}

帧解析与处理

// 解析接收到的帧
bool parse_received_frame(const uint8_t* raw_data, uint16_t raw_len, N_PDU_FRAME* frame) {
    if (raw_len < 1 || frame == NULL) return false;
    
    uint8_t pci = raw_data[0];
    N_PDU_TYPE frame_type = (pci >> 4) & 0x0F;
    
    frame->pci = pci;
    frame->frame_type = frame_type;
    
    switch (frame_type) {
        case N_PDU_SINGLE_FRAME: {
            uint8_t data_len = pci & 0x0F;
            if (raw_len < 1 + data_len) return false;
            
            memcpy(frame->data, &raw_data[1], data_len);
            frame->data_length = data_len;
            break;
        }
        
        case N_PDU_FIRST_FRAME: {
            if (raw_len < 3) return false; // 至少需要PCI + 2字节长度
            
            uint16_t total_len = ((pci & 0x0F) << 8) | raw_data[1];
            uint16_t data_len = raw_len - 2; // 减去PCI和长度字节
            
            frame->data[0] = raw_data[1]; // 存储长度信息
            frame->data[1] = raw_data[2];
            memcpy(&frame->data[2], &raw_data[3], data_len - 1);
            frame->data_length = data_len + 1;
            break;
        }
        
        case N_PDU_CONSECUTIVE_FRAME: {
            if (raw_len < 2) return false;
            
            uint8_t data_len = raw_len - 1;
            memcpy(frame->data, &raw_data[1], data_len);
            frame->data_length = data_len;
            break;
        }
        
        case N_PDU_FLOW_CONTROL: {
            if (raw_len < 3) return false;
            
            frame->data[0] = raw_data[1]; // block size
            frame->data[1] = raw_data[2]; // separation time
            frame->data_length = 2;
            break;
        }
        
        default:
            return false;
    }
    
    return true;
}

// 多帧传输接收处理
bool process_multi_frame_reception(const N_PDU_FRAME* frame, MULTI_FRAME_CONTEXT* context) {
    if (frame == NULL || context == NULL) return false;
    
    switch (frame->frame_type) {
        case N_PDU_FIRST_FRAME: {
            // 解析总长度
            context->total_length = ((frame->pci & 0x0F) << 8) | frame->data[0];
            context->received_bytes = 0;
            context->sequence_number = 0;
            context->transmission_active = true;
            
            // 复制首帧中的数据
            uint16_t copy_len = frame->data_length - 1; // 减去长度字节
            if (copy_len > 0) {
                memcpy(context->buffer, &frame->data[1], copy_len);
                context->received_bytes = copy_len;
            }
            break;
        }
        
        case N_PDU_CONSECUTIVE_FRAME: {
            if (!context->transmission_active) return false;
            
            // 检查序列号
            uint8_t expected_sn = (context->sequence_number + 1) & 0x0F;
            uint8_t received_sn = frame->pci & 0x0F;
            
            if (received_sn != expected_sn) {
                // 序列号错误,重置传输
                context->transmission_active = false;
                return false;
            }
            
            // 复制数据
            uint16_t copy_len = frame->data_length;
            if (context->received_bytes + copy_len > context->total_length) {
                copy_len = context->total_length - context->received_bytes;
            }
            
            memcpy(&context->buffer[context->received_bytes], frame->data, copy_len);
            context->received_bytes += copy_len;
            context->sequence_number = received_sn;
            
            // 检查是否接收完成
            if (context->received_bytes >= context->total_length) {
                context->transmission_active = false;
            }
            break;
        }
        
        default:
            return false;
    }
    
    return true;
}

示例

// 示例:发送多帧数据
void send_multi_frame_data(const uint8_t* data, uint16_t total_len) {
    N_PDU_FRAME frame;
    MULTI_FRAME_CONTEXT context = {0};
    
    printf("开始多帧传输,总长度: %d bytes\n", total_len);
    
    // 发送首帧
    create_first_frame(data, total_len, &frame);
    send_frame(&frame); // 假设的发送函数
    
    uint16_t sent_bytes = 6; // 首帧已发送6字节数据
    uint8_t sequence_number = 0;
    
    // 发送连续帧
    while (sent_bytes < total_len) {
        // 等待流控帧(如果需要)
        // receive_flow_control();
        
        uint16_t chunk_size = (total_len - sent_bytes > 7) ? 7 : total_len - sent_bytes;
        
        create_consecutive_frame(sequence_number, &data[sent_bytes], chunk_size, &frame);
        send_frame(&frame);
        
        sent_bytes += chunk_size;
        sequence_number = (sequence_number + 1) & 0x0F;
        
        printf("发送连续帧 #%d, 已发送: %d/%d bytes\n", 
               sequence_number, sent_bytes, total_len);
    }
    
    printf("多帧传输完成\n");
}

// 示例:打印帧信息
void print_frame_info(const N_PDU_FRAME* frame) {
    const char* type_str[] = {"单帧", "首帧", "连续帧", "流控帧"};
    
    printf("帧类型: %s, PCI: 0x%02X\n", 
           type_str[frame->frame_type], frame->pci);
    
    if (frame->frame_type == N_PDU_SINGLE_FRAME) {
        printf("数据长度: %d\n", frame->pci & 0x0F);
    } else if (frame->frame_type == N_PDU_FIRST_FRAME) {
        uint16_t total_len = ((frame->pci & 0x0F) << 8) | frame->data[0];
        printf("总长度: %d\n", total_len);
    } else if (frame->frame_type == N_PDU_CONSECUTIVE_FRAME) {
        printf("序列号: %d\n", frame->pci & 0x0F);
    } else if (frame->frame_type == N_PDU_FLOW_CONTROL) {
        const char* status_str[] = {"继续", "等待", "溢出"};
        printf("流控状态: %s, 块大小: %d, 间隔时间: %d\n",
               status_str[frame->pci & 0x0F], frame->data[0], frame->data[1]);
    }
    
    printf("数据: ");
    for (int i = 0; i < frame->data_length && i < 8; i++) {
        printf("%02X ", frame->data[i]);
    }
    printf("\n\n");
}

int main() {
    // 测试单帧
    uint8_t single_frame_data[] = {0x11, 0x22, 0x33, 0x44};
    N_PDU_FRAME single_frame;
    create_single_frame(single_frame_data, 4, &single_frame);
    print_frame_info(&single_frame);
    
    // 测试多帧传输
    uint8_t multi_frame_data[20];
    for (int i = 0; i < 20; i++) {
        multi_frame_data[i] = i + 0x10;
    }
    send_multi_frame_data(multi_frame_data, 20);
    
    return 0;
}

Logo

有“AI”的1024 = 2048,欢迎大家加入2048 AI社区

更多推荐