首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >C数组操作协议转换

C数组操作协议转换
EN

Stack Overflow用户
提问于 2015-01-14 15:16:52
回答 1查看 131关注 1票数 0

我正在尝试执行协议转换

第一协议

代码语言:javascript
复制
| 1 byte (address) | 1 byte (function code) |  0-254 bytes (data) | 2 bytes ( CRC )| 

第二协议

代码语言:javascript
复制
| 2 bytes (address) | 2 bytes (0) | 2 bytes (length) | 1 byte (0) | 1 byte (function code) | 0-254 bytes (data) | 

接收到第一协议帧,并将其数据转换为第二协议帧。

第一个协议的字节0应该映射到第二个协议的字节0和1。

代码语言:javascript
复制
static int convert(uint8_t *buffer, int len, uint8_t* frame){

    frame[0] = 0x00;
    frame[1] = buffer[0];

    frame[2] = 0x00;
    frame[3] = 0x00;

    frame[4] = 0x00;
    frame[5] = len - 4 + 1;

    frame[6] = 0x00;

    frame[7] = buffer[1];

    memcpy(&frame[8], &buffer[2], len-4);

    return frame[5] + 6;
}


uint8_t buffIN[260]; // first protocol

uint8_t buffOUT[264]; // second protocol


/*READ DATA INT buffIN*/ 
//8 bytes received
// if frame is valid continue else signal error

int res = convert(&buffIN, 8  &buffOUT);

如果有人用不同的方法,请告诉我

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2015-01-14 20:18:31

需要考虑的协议转换有两个方面:传输的不同特性和数据的差异。最重要的传输特性是数据的特性,特别是与您的转换器正在运行的处理器有关的数据。其他特征可能包括字符集(纯ASCII与Unicode的某些风格--或在过去的EBCDIC中)、数值的大小、日期格式等。数据中的差异包括字段顺序、字段存在和数据表示(将一组值映射到另一组值)。

另外,大多数协议转换器都需要双向转换。

现在回到过去,记住程序最基本的范例:输入-过程-输出。这种结构在协议转换中非常有用。您希望所有处理(无论方向如何)以标准格式对经过消毒的数据进行操作。因此,定义一个独立于要转换的协议的协议包的内部表示。设计它,以使转换器的处理器的最佳使用。

然后写四个例程:

  • 将协议1转换为内部格式
  • 将内部格式转换为协议1
  • 将协议2转换为内部格式
  • 将内部格式转换为协议2

你的简化主线变成:

代码语言:javascript
复制
while(TRUE)
    if (protocol 1 packet available)
        convert it to internal format
        perform any necessary processing
        convert to protocol 2 and transmit
    endif
    if (protocol 2 packet available)
        convert it to internal format
        perform any necessary processing
        convert to protocol 1 and transmit
    endif
endwhile

这使两个协议的转换完全脱离了对彼此的了解,并且很容易将其中一个协议转换为另一个协议,或者对其中一个协议的变化做出响应。

现在,就您的具体示例而言,我的内部结构如下所示:

代码语言:javascript
复制
typedef struct internalForm {
    unsigned int address;
    unsigned int function;
    size_t payloadLength;
    unsigned char payload[255];
} internalForm;

我的四种方法都有这样的原型:

代码语言:javascript
复制
#include <stdbool.h>
bool   P1ToInternal(const unsigned char *packet, size_t packetLength, internalForm * internal);
size_t InternalToP1(const internalForm * internal, unsigned char *packet, size_t packetLength);
bool   P2ToInternal(const unsigned char *packet, size_t packetLength, internalForm * internal);
size_t InternalToP2(const internalForm * internal, unsigned char *packet, size_t packetLength);

bool返回只是表示输入的转换失败。“输出”函数返回转换后的数据包的大小,或错误时返回0。

在更复杂的转换中,我实际上有一个函数代码和其他“枚举”字段的内部表示。转换例程将处理内部表示和协议特定表示之间的映射。

一个方向的完全执行可以是:

代码语言:javascript
复制
bool P1ToInternal(const unsigned char *packet, size_t packetLength, internalForm * internal)
{
    internal->address = (unsigned int) packet[0];
    internal->function = (unsigned int) packet[1];

    // You need to write the function below. It could just be a look up
    size_t dataLength = MapP1FunctionToPayloadLength(internal->function);
    if (dataLength > sizeof(internal->payload))
        return false;

    // You need to write CheckCRC()
    if (!CheckCRC(&packet[2], dataLength, &packet[2+dataLength]))
        return false;

    internal->payloadLength = dataLength;
    memset(internal->payload, 0, sizeof(internal->payload));
    memcpy(internal->payload, &packet[2], dataLength);
    return true;
}

size_t InternalToP2(const internalForm * internal, unsigned char *packet, size_t bufferLength)
{
    if (bufferLength < internal->payloadLength + 8)
        return 0;

    memset(packet, 0, bufferLength);

    // Assumes little-endian representation, but it's not hard to see what 
    // to do for the alternative. And you should have an enum for the array
    // indices.
    packet[1] = internal->address & 0xff;
    packet[5] = internal->payloadLength; // Not sure where your +1 is coming from
    packet[7] = internal->function & 0xff;
    memcpy(&payload[8], internal->payload, internal->payloadLength);

    return internal->PayloadLength + 8;
}

对于您的简单示例来说,这可能有点过分,但作为一个框架,它将导致非常健壮的转换程序。转换错误将是非常明显和易于调试的。输入输出转换和内部处理都可以独立进行单元测试.

最后,转换如下:

代码语言:javascript
复制
unsigned char inBuff[260], outBuff[264];

struct internalForm internal;

if (P1ToInternal(inBuff, sizeof(inBuff), &internal))
{
    size_t len = InternalToP2(&internal, outBuff, sizeof(outBuff))
    if (len)
        transmitP2(outBuff, len);
}
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/27946260

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档