Sunday, March 2, 2025

An overengineering example to set a packet frame

In this article, I want to share an overengineering design that not necessary for a simple use case. However, it would be a good design for a complicated system if such packet is used for many interfaces.

Target: to set a packet frame with some header, some payload, in the following format:

Packet Header:

Source      : DeviceA

Destination : DeviceB

Sequence    : 42

Checksum    : 13

Message Type: 1

Full frame (28 bytes):

01 2a 44 65 76 69 63 65 41 00 00 00 44 65 76 69 63 65 42 00 00 00 aa 12 34 56 ff 0d

Let's see how simple a C-style will be:

int setPacketFrame(unsigned char* acData, unsigned char ucType)

{

    acData[0] = ucType;

    acData[1] = getSequenceNum();  //

    snprintf(acData+2, 10, "%s", SOURCE_DEV);

    snprintf(acData+12, 10, "%s", DEST_DEV);

    acData[22] = getReq();  //payload starts here

    acData[23] = getResult();

    acData[24] = getReason();

    acData[25] = getSomething1();

    acData[26] = getSomething2();

    acData[27] = calcBcc(acData+1, 12);

    return 28;

}

What do you think of this function? Look forward to your opinions on it.

Let's check the C++ complicated design, to hit the nut directly, see the flowchart as follows.

 


And see all the classes:

 

Simply speaking, this design is structured to build and finalize a network packet composed of a fixed header, a variable payload, and a checksum appended at the end. It uses a combination of low-level byte manipulation (via the PacketBuffer class) and higher-level abstractions (via the NetworkPacket interface and its implementation in ContiguousPacket) to offer a fluent API for constructing packets. 

Some highlights:

  • Abstraction Layers:
    Low-level memory manipulation is abstracted away using PacketBuffer, while higher-level packet-building logic is encapsulated in NetworkPacket and ContiguousPacket.
  • Fluent Interface:
    Chained method calls allow for a compact and readable way to set header fields and payloads.
  • Extensibility:
    The use of an abstract base class and cloning via CRTP facilitates the extension of the packet system to support different types of packets if needed.
  • You may find the source code from https://github.com/happytong/PacketWrapper/blob/main/packet_wrapper.cpp.


    No comments:

    Post a Comment

    Designing an Event-Driven System in C++

    Event-driven architecture is a fundamental paradigm in software design where components communicate through events rather than direct method...