# CASTV2 protocol The CASTV2 protocol is a TCP-based client/server message passing protocol. ## Prerequsites Before being able to communicate with the CASTV2 protocol, you will need: * A TCP networking library * A [TLS](https://en.wikipedia.org/wiki/Transport_Layer_Security) library (i.e. [openssl](https://www.openssl.org)) * A [protocol buffers](https://developers.google.com/protocol-buffers/) compiler * A JSON library ## *TODO* * Talk about broadcasing with `*` as the `destination_id` ## Low-level ### TCP/IP To communicate with a Cast device using the CASTV2 protocol, you first need to open up a network connection on port `8009` to the Cast device. ### TLS At the lowest level, just above TCP, the CASTV2 protocol is transmitted over [TLS](https://en.wikipedia.org/wiki/Transport_Layer_Security). The Cast device itself uses a self-signed certificate for verification. You may run into problems if your TLS library automatically rejects self-signed certificates. You must explicitly allow them in order to complete a successful TLS handshake. ### Raw protocol Just above SSL, data is transmitted in discrete packets named "messages". A single message is sent with a 32-bit big endian unsigned integer representing the size of the message, and then the raw message itself. | Field | Type | |-------------|----------------| | Size | 32-bit integer | | Raw message | Raw bytes | ## Mid level Cast messages are described using the [protobuf](https://developers.google.com/protocol-buffers) library. The full protobuf definition can be found at `extensions/common/api/cast_channel` in the Chromium [source tree](https://chromium.googlesource.com/chromium/src.git/+/master/extensions/common/api/cast_channel). The message definition looks like this ```protobuf message CastMessage { enum ProtocolVersion { CASTV2_1_0 = 0; } required ProtocolVersion protocol_version = 1; required string source_id = 2; required string destination_id = 3; required string namespace = 4; enum PayloadType { STRING = 0; BINARY = 1; } required PayloadType payload_type = 5; optional string payload_utf8 = 6; optional bytes payload_binary = 7; } ``` ### Protocol version Every message is required to specify the version of the CAST protocol it uses. ### Source/destination IDs These are textual IDs used to identify the endpoints that the messages are being transmitted to/from. Google Chrome uses `sender-0` to identify itself and it uses `receiver-0` to identify the Cast device. These are not the only possible values. When `PING` messages are sent from the Cast device to the client, the messages have `Tr@n$p0rt` as the source and destination. ### Namespaces A namespace can be thought of as a "channel name" through which a message can be sent. For example, the initial `CONNECT` message is sent on the `urn:x-cast:com.google.cast.tp.connection` namespace. * `urn:x-cast:com.google.cast.tp.connection` * `urn:x-cast:com.google.cast.tp.heartbeat` * `urn:x-cast:com.google.cast.receiver` * `urn:x-cast:com.google.cast.tp.deviceauth` #### `urn:x-cast:com.google.cast.tp.connection` This is used to send `CONNECT` and `CLOSE` message to manage the virtual connection between the client and the Cast device. #### `urn:x-cast:com.google.cast.tp.heartbeat` This is used to send `PING` and `PONG` heartbeat events. #### `urn:x-cast:com.google.cast.receiver` This is used to manage and query the Cast receiver itself. Most of the interesting messages go through this namespace. #### `urn:x-cast:com.google.cast.tp.deviceauth` This is used for authentication of the Cast device. Authentication only occurs if the client initiates it. ### Payloads There are two types of messages - `STRING` and `BINARY`. #### `STRING` payloads `STRING` payloads contain JSON data. For all textual messages, it looks like the following template. ```json { "type": "", "