Serial Port Monitor - Software Serial Port sniffer, logger & protocol analyzer for Windows
Download Device Monitoring Studio Hide this button

Custom Communication Mode

In addition to a number of built-in session types supported by Device Monitoring Studio for serial monitoring, the user may also define custom rules for packet joining and splitting.

This is done by means of TypeScript (or JavaScript) custom code. This topic describes the specifications the custom script must adhere to. First, in order to start editing a custom script, the user must select the “Custom” session type in corresponding dialog and then press the Edit button.

The following window appears:

Custom Script Editor Window

Use this window to edit a custom script. A window automatically highlights syntax errors. Use your mouse to hover over a highlighted error to see explanation.

If you have a custom script stored in a separate file, click the Load from File button to load it. If you need to store the custom script outside of Device Monitoring Studio, click the Save to File button. To reset to default sample implementation, click the Reset button.

When you open this window for the first time, a sample script is automatically loaded. It contains an implementation of a simple packet splitter that ends a packet whenever a character 0A is received. The code contains enough comments and should be self-explanatory.

Custom Splitter Code Structure

Serial source creates two isolated execution environments upon session start. One execution environment is used to process read requests (received data) and another is used to process write requests (sent data). These environments are isolated from each other and from any other scripts running in Device Monitoring Studio. That means that they cannot share any variables and call functions from different environments.

After an execution environment is created, a function called createSplitter is called. It must have the following signature:

function createSplitter(type: PacketType): IPacketSplitter;

Where PacketType is defined as:

enum PacketType {
  Read,
  Write
}

and IPacketSplitter as:

interface IPacketSplitter {
  addData(data: Uint8Array, splitPacket: (position: number) => void): void;
}

createSplitter function is passed a splitter type (either PacketType.Read or PacketType.Write) and must create an instance of a class that implements the IPacketSplitter interface.

For each captured data block, IPacketSplitter.addData method is called. It is passed a copy of data block and a function to be called when custom code decides there is a start of a new packet in this data. splitPacket function must be called with an offset within the passed data block. It must be between 0 and data block size (inclusive).

Please refer to the sample code for more details.