Version 1.1 (April 5, 2012)
Continuous wave (CW) is an early method of radio transmission, in which a carrier wave is switched on and off to deliver a message. Typically information is carried varying the duration of the on and off periods by using, for example, Morse code.
The continuous wave protocol (CWP) provides means to send and receive information encoded using continuous wave semantics over a packet switched communication channel in real time.
This document uses the key words "MUST", "MUST NOT", "SHOULD", "SHOULD NOT", and "MAY" in accordance with RFC 2119.
The continuous wave protocol is based on two concepts: a state and a frequency.
A state imitates continuous wave messaging: whether a radio station is sending signal. A state can be either Down (a station is not sending: off, binary number 0) or Up (a station is sending: on, binary number 1). See the next figure:
state | Up | +------+ | | | Down |-----+ +------ | +-------------------> time
A frequency imitates the radio frequency of which is used to send continuous wave messages. To receive a sent message, a receiver must be on the same frequency than the sender.
The continuous wave protocol is designed to operate on top of another transmission protocol. The underlaying protocol MUST provide the following features:
The underlaying protocol MAY be Transmission Control Protocol (TCP).
The continuous wave protocol defines one-way communication. The channels transferring data opposite directions MUST be independent of each other.
The order of bytes (endianness) is the standard network byte order (big-endian, most significant byt first) for all 16-bit and 32-bit numeric values.
The data format of continuous wave protocol is expressed in Augmented Backus-Naur Form (see RFC 5234).
cwp = *message
A data stream MUST consist of unlimited amount of sequential messages.
message = state-change / frequency-change
A message MUST be either a state change message or a frequency change message.
state-change = state-up state-down
A state-change message actually consists of two sequential messages: a state-up message following at some point a state-down message. There MUST not be anything else between these messages.
state-up = 0x00000000-7fffffff ; a timestamp (a signed 32-bit integer >= 0)
A state-up message MUST be a signed 32-bit integer representing a time in milliseconds that has been elapsed since the communication channel has been established. The value MUST be either zero or positive.
state-down = 0x0000-ffff ; a duration (an unsigned 16-bit integer)
A state-down message MUST be an unsigned 16-bit integer representing a time in milliseconds that has been elapsed since the last state-up message.
frequency-change = 0x80000000-ffffffff ; the opposite of a frequency (a signed 32-bit integer < 0)
A frequency-change message MUST be a signed 32-bit integer representing the opposite value of a frequency. The frequency MUST be between 1 and 2147483647 (2^31 - 1), but it MUST be coded as a two's complement number between -1 and -2147483647 (-(2^31 - 1)).
The value -2147483648 is reserved for future extensions and MUST not be send. It MUST be silently ignored if received.
As can be deduced from the data format, the continuous wave protocol has two states: Down or Up. See the following figure:
O----> +------------+ ----state-up---> +------------+ |::::Down::::| |:::::Up:::::| +----> +------------+ <--state-down--- +------------+ | | +-frequency-change-+
In the Down state, a sender MUST write one signed 32-bit integer and a receiver MUST read one signed 32-bit integer. It is either a state-up message or a frequency-change message. If the message is a state-up message, the sender and the receiver MUST switch to the Up state. If the message is a frequency-change message, the sender and the receiver MUST stay in the Down state.
In the Up state, a sender MUST write one unsigned 16-bit integer and a receiver MUST read one unsigned 16-bit integer. It is a state-down message. After that, the sender and the receiver MUST switch to the Down state.
If a sender expects that the current Up state will last longer than 65535 (2^16 - 1) milliseconds, it MUST change to the next Up state by sending a state-down message immediately followed by a state-up message of which timestamp is equal to the sum of the timestamp of the previous state-up message and the duration of the state-down message. In order to avoid latency-related issues and possible error-detection on receiving end, a sender SHOULD not wait until the Up state has lasted the maximum time, but send sequential state change messages earlier, for example, after every 30000 milliseconds. A receiver MAY combine sequential Up states if the duration of the Down state between them is zero, or handle them separately.
The sending and the receiving states are independent of each other.
Immediately after a communication channel has been established, the default state MUST be Down and the current frequency MUST be equal to 1 for both the sender and the receiver.
An application implementing the continuous wave protocol SHOULD indicate the states somehow to a user, visually, aurally or by other means. For example, a lamp MAY be be dimmed in the Down state and bright in the Up state, or a sound MAY not be played in the Down state and played in the Up state. If the sent and the received frequency is different, the receiver SHOULD NOT indicate state change messages to a user.
It is highly probable that the underlying communication channel introduces latency. Because the continuous wave protocol is operating on real-time, especially variable latency hampers the interpretation of a message.
A receiver SHOULD manage latency by buffering the received messages before indicating the state to a user. The buffer length SHOULD be continuously adjusted based on the current, historical and/or expected latency. A receiver MAY discard state-up message of which timestamp is clearly impossible, such as before the last received timestamp or in the future.
A receiver MAY use the following scheme to adjust the buffer length:
The continuous wave protocol MAY be used directly between two communication parties. To imitate all around radio waves, "the Ether", a server MAY be used.
A continuous wave protocol server MUST be able to manage multiple clients. The server MUST maintain the individual state of each client including the receiving and sending protocol states and the frequency.
For each client, the server MUST maintain a separate sending state that is the combination of receiving states from all clients in the same frequency not including the client of which sending state is maintained. The combined sending state of a client MUST be Down if and only if the server has not received a state-up message without the corresponding state-down message from any other client. Otherwise the sending state MUST be Up. The server MUST send state-up and state-down messages to each connected client based on the state changes of the combined sending state of that client. The server MUST NOT send back (echo) to a client any state change messages from that client.
The server MUST switch to the same frequency by sending a frequency-change message when it receives a frequency-change message from a client. The server MAY send additional frequency-change messages, but the frequency MUST be the same that was requested by the client, or if the client has not requested any frequency set by default when the communication channel was established.
The server SHOULD manage latency in accordance with section 6, Latency Management.
Servers MAY be interconnected. However, that introduces more latency, which SHOULD be taken into account when building such system.
Author wants to thank Mr. Antti Juustila for his invaluable comments and help with reference implementation.