Skip to content
Jakob Ketterl edited this page Jul 3, 2023 · 2 revisions

Protocol

Communicating with a codecserver

Message wire format

Protobuf is used for serialization. The .proto files can be found in src/lib/proto. They are also installed into the system includes folder (${PREFIX}/include/codecserver/proto/), and they are also available in the package libcodecserver-dev from the OpenWebRX Debian and Ubuntu repositories.

Messages on the wire are preceded by an unsigned integer in Protobuf Varint encoding. This indicates the length of the following message.

The message itself is packed in an Any message. This allows recovery of the type. In C++ and Java, Coded{Input,Output}Streams may be used to simplify integration.

To receive a message without such support:

  1. Read the Varint to know the expected length of the message
  2. Read the message as an Any
  3. Use the type_url to construct an object of the appropriate type

To send a message without such support:

  1. Pack the message in an Any (e.g. any = google.protobuf.any_pb2.Any(); any.Pack(my_msg))
  2. Get the size in bytes of the message and encode it as a Varint
  3. Send this size in bytes, then the message over the wire

Connecting

Connect to the server, either over TCP or over UNIX domain sockets. Check the codecserver.conf ([server:...] section) of the server to see what you have enabled for your server and what the port or socket path is.

Setup

When connecting, the server will send you a Handshake message. You can use the protocolVersion to ensure you have a compatible implementation.

To check if the server has support for the codec you want to use, send a Check message. If the codec is supported, you will received a Response message with Status: OK. You can also immediately try to start a session with a codec and see if that is successful, Check is mostly meant as a stand-alone message to see what codecs are supported.

Starting a session

To start a session, send a Request with the codec you want to use. You can select the directions you want to use (encoding, decoding, or both), some devices may not implement both (software devices in particular). The codec you want to use may require you to provide args, these are codec-specific. For example, the ambe codec can take a rate or a ratep string.

In the Response, the server may indicate the expected framing for the codec and argument you selected. This describes the number of bits expected for encoded/decoded samples.

Coding audio

To encode or decode audio, send SpeechData or ChannelData, respectively. Coding is an asynchronous process and you should not await this synchronously.

To encode data, send SpeechData messages to the server. At some point you will receive ChannelData back, this is the encoded data. To decode data, send ChannelData messages to the server. At some point you will receive SpeechData back, this is the decoded data.

The format of both SpeechData and ChannelData will be specific to the codec and its arguments.