Search code examples
node.jstcptcpclientpacket

TCP Packet Structure


Can somebody help me creating a tcp packet with this packet structure in nodejs ? enter image description here

   const net = require('net');
var createPacket = require("./MSPPacketHandler/createPacket");

var host = '192.168.4.1';
var port = 23;


let client = new net.Socket();
client.connect(port, host, () => {
    var str = "";
    console.log("Connected");
    client.write(createPacket("Roll",0x6c,">")); //This will send the byte buffer over TCP

    client.on('data',function(chunk){
        str += chunk;
    })

    client.on('end',function(){
        console.log(str);
    });
})
// Packet format
// Header bytes:     0x24, 0x4d
// Direction byte:   0x3c or 0x3e
// Msg Length:       0x00 to 0xff
// Command:          0x01 to 0xff
// Payload Bytes:    .....
// CRC               xx

function createPacket(payload_data,command,direction){
    const packetMainLength = 6; // fixed overhead of packet without payload
    const payload = payload_data; // string
    const packetLength = packetMainLength + payload.length;

    const buffer = Buffer.alloc(packetLength, 0);
    // write common MSP message header
    buffer[0] = 0x24;
    buffer[1] = 0x4d;

    // write direction
    buffer[2] = (direction == "<" ? 0x3c : 0x3e); // to the flight controller

    // write payload length
    buffer[3] = packetLength;

    // write command
    //buffer[4] = 0x6c; // pick the appropriate command to the controller
    buffer[4] = command;

    // put our payload string into the buffer
    buffer.write(payload, 5, payload.length, 'utf8');
    const afterIndex = 5 + payload.length;

    // calculate CRC of direction, length and payload and put it into the packet 
    // after the payload

    const crcStartIndex = 3;
    let crc = buffer[crcStartIndex];
    for (let index = 1; index < payload.length + 2; index++) {
        crc = crc ^ buffer[index + crcStartIndex];
    }

    buffer[afterIndex] = crc;

    console.log(buffer);

    return buffer;
    
}

module.exports = createPacket;

This is create packet function. It takes three arguments and returns buffer. I sent the buffer as it is , do i need to convert it to string ? Adding some random text as the stackoverflow is asking to add more description.


Solution

  • Create a Buffer object and you can then use the .writeInt8() method to put single byte values into the buffer at the right positions (it appears your format is all single byte values) or fir single byte values, you can just directly index into the buffer using array syntax too.

    You will have to manually understand what values go into which bytes of the buffer, including the payload length, the payload and the CRC of the payload (calculated as described in your image).

    For example, if your payload was the characters in the string "Hello", you could construct that packet like this:

    // Packet format
    // Header bytes:     0x24, 0x4d
    // Direction byte:   0x3c or 0x3e
    // Msg Length:       0x00 to 0xff
    // Command:          0x01 to 0xff
    // Payload Bytes:    .....
    // CRC               xx
    
    const packetMainLength = 6; // fixed overhead of packet without payload
    const payload = "Hello"
    const packetLength = packetMainLength + payload.length;
    
    const buffer = Buffer.alloc(packetLength, 0);
    // write common MSP message header
    buffer[0] = 0x24;
    buffer[1] = 0x4d;
    
    // write direction
    buffer[2] = 0x3c; // to the flight controller
    
    // write payload length
    buffer[3] = packetLength;
    
    // write command
    buffer[4] = 0x1; // pick the appropriate command to the controller
    
    // put our payload string into the buffer
    buffer.write(payload, 5, payload.length, 'utf8');
    const afterIndex = 5 + payload.length;
    
    // calculate CRC of direction, length and payload and put it into the packet 
    // after the payload
    
    const crcStartIndex = 3;
    let crc = buffer[crcStartIndex];
    for (let index = 1; index < payload.length + 2; index++) {
        crc = crc ^ buffer[index + crcStartIndex];
    }
    
    buffer[afterIndex] = crc;
    
    console.log(buffer);
    

    Since most of this is common for all packets, you could create a common function that would take the payload, command and direction as function arguments and then it would create the packet for you with that data in it.