Socket
Socket
Sign inDemoInstall

castv2

Package Overview
Dependencies
Maintainers
1
Versions
10
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

castv2 - npm Package Compare versions

Comparing version 0.1.9 to 0.1.10

56

lib/client.js

@@ -67,12 +67,12 @@ var EventEmitter = require('events').EventEmitter;

'recv message: protocolVersion=%s sourceId=%s destinationId=%s namespace=%s data=%s',
message.protocol_version,
message.source_id,
message.destination_id,
message.protocolVersion,
message.sourceId,
message.destinationId,
message.namespace,
(message.payload_type === 1) // BINARY
? util.inspect(message.payload_binary)
: message.payload_utf8
(message.payloadType === 1) // BINARY
? util.inspect(message.payloadBinary)
: message.payloadUtf8
);
if(message.protocol_version !== 0) { // CASTV2_1_0
self.emit('error', new Error('Unsupported protocol version: ' + message.protocol_version));
if(message.protocolVersion !== 0) { // CASTV2_1_0
self.emit('error', new Error('Unsupported protocol version: ' + message.protocolVersion));
self.close();

@@ -83,9 +83,9 @@ return;

self.emit('message',
message.source_id,
message.destination_id,
message.sourceId,
message.destinationId,
message.namespace,
(message.payload_type === 1) // BINARY
? message.payload_binary
: message.payload_utf8
);
(message.payloadType === 1) // BINARY
? message.payloadBinary
: message.payloadUtf8
);
}

@@ -104,5 +104,5 @@

var message = {
protocol_version: 0, // CASTV2_1_0
source_id: sourceId,
destination_id: destinationId,
protocolVersion: 0, // CASTV2_1_0
sourceId: sourceId,
destinationId: destinationId,
namespace: namespace

@@ -112,7 +112,7 @@ };

if(Buffer.isBuffer(data)) {
message.payload_type = 1 // BINARY;
message.payload_binary = data;
message.payloadType = 1 // BINARY;
message.payloadBinary = data;
} else {
message.payload_type = 0 // STRING;
message.payload_utf8 = data;
message.payloadType = 0 // STRING;
message.payloadUtf8 = data;
}

@@ -122,9 +122,9 @@

'send message: protocolVersion=%s sourceId=%s destinationId=%s namespace=%s data=%s',
message.protocol_version,
message.source_id,
message.destination_id,
message.protocolVersion,
message.sourceId,
message.destinationId,
message.namespace,
(message.payload_type === 1) // BINARY
? util.inspect(message.payload_binary)
: message.payload_utf8
(message.payloadType === 1) // BINARY
? util.inspect(message.payloadBinary)
: message.payloadUtf8
);

@@ -140,2 +140,2 @@

module.exports = Client;
module.exports = Client;
var fs = require('fs');
var ProtoBuf = require("protobufjs");
var protobuf = require("protobufjs");
var builder = ProtoBuf.loadProtoFile(__dirname + "/cast_channel.proto");
var extensions = builder.build('extensions.api.cast_channel');
var builder = protobuf.load(__dirname + "/cast_channel.proto", onLoad);
var messages = [
'CastMessage',
'AuthChallenge',
'AuthResponse',
'AuthError',
'CastMessage',
'AuthChallenge',
'AuthResponse',
'AuthError',
'DeviceAuthMessage'
];
var extensions = [];
function onLoad(err, root) {
if (err) throw err;
messages.forEach(function(message) {
extensions[message] =
root.lookupType(`extensions.api.cast_channel.${message}`);
});
}
messages.forEach(function(message) {
module.exports[message] = {
serialize: function(data) {
var msg = new extensions[message](data);
return msg.encode().toBuffer();
if (!extensions[message]) {
throw new Error('extension not loaded yet');
}
var Message = extensions[message];
return Message.encode(data).finish();
},
parse: function(data) {
return extensions[message].decode(data);
if (!extensions[message]) {
throw new Error('extension not loaded yet');
}
var Message = extensions[message];
return Message.decode(data);
}
};
});
});

@@ -54,12 +54,12 @@ var EventEmitter = require('events').EventEmitter;

clientId,
message.protocol_version,
message.source_id,
message.destination_id,
message.protocolVersion,
message.sourceId,
message.destinationId,
message.namespace,
(message.payload_type === 1) // BINARY
? util.inspect(message.payload_binary)
: message.payload_utf8
(message.payloadType === 1) // BINARY
? util.inspect(message.payloadBinary)
: message.payloadUtf8
);
if(message.protocol_version !== 0) { // CASTV2_1_0
if(message.protocolVersion !== 0) { // CASTV2_1_0
debug('client error: clientId=%s unsupported protocol version (%s)', clientId, message.protocolVersion);

@@ -73,9 +73,9 @@ var socket = self.clients[clientId].socket;

clientId,
message.source_id,
message.destination_id,
message.sourceId,
message.destinationId,
message.namespace,
(message.payload_type === 1) // BINARY
? message.payload_binary
: message.payload_utf8
);
(message.payloadType === 1) // BINARY
? message.payloadBinary
: message.payloadUtf8
);
}

@@ -118,5 +118,5 @@

var message = {
protocol_version: 0, // CASTV2_1_0
source_id: sourceId,
destination_id: destinationId,
protocolVersion: 0, // CASTV2_1_0
sourceId: sourceId,
destinationId: destinationId,
namespace: namespace

@@ -126,7 +126,7 @@ };

if(Buffer.isBuffer(data)) {
message.payload_type = 1 // BINARY;
message.payload_binary = data;
message.payloadType = 1 // BINARY;
message.payloadBinary = data;
} else {
message.payload_type = 0 // STRING;
message.payload_utf8 = data;
message.payloadType = 0 // STRING;
message.payloadUtf8 = data;
}

@@ -137,9 +137,9 @@

clientId,
message.protocol_version,
message.source_id,
message.destination_id,
message.protocolVersion,
message.sourceId,
message.destinationId,
message.namespace,
(message.payload_type === 1) // BINARY
? util.inspect(message.payload_binary)
: message.payload_utf8
(message.payloadType === 1) // BINARY
? util.inspect(message.payloadBinary)
: message.payloadUtf8
);

@@ -156,2 +156,2 @@

module.exports = Server;
module.exports = Server;
{
"name": "castv2",
"version": "0.1.9",
"version": "0.1.10",
"description": "An implementation of the Chromecast CASTV2 protocol",

@@ -9,7 +9,7 @@ "author": "thibauts",

"dependencies": {
"debug": "^2.2.0",
"protobufjs": "^3.2.2"
"debug": "^4.1.1",
"protobufjs": "^6.8.8"
},
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1"
"test": "echo \"Error: no test specified\" && exit 0"
},

@@ -16,0 +16,0 @@ "repository": {

@@ -10,3 +10,3 @@ castv2

This module is an implementation of the Chromecast CASTV2 protocol over TLS. The internet is very scarse on information about the new Chromecast protocol so big props go to [github.com/vincentbernat](https://github.com/vincentbernat) and his [nodecastor](https://github.com/vincentbernat/nodecastor) module that helped me start off on the right foot and save a good deal of time in my research.
This module is an implementation of the Chromecast CASTV2 protocol over TLS. The internet is very sparse on information about the new Chromecast protocol so big props go to [github.com/vincentbernat](https://github.com/vincentbernat) and his [nodecastor](https://github.com/vincentbernat/nodecastor) module that helped me start off on the right foot and save a good deal of time in my research.

@@ -85,3 +85,3 @@ The module provides both a `Client` and a `Server` implementation of the low-level protocol. The server is (sadly) pretty useless because device authentication gets in the way for now (and maybe for good). The client still allows you to connect and exchange messages with a Chromecast dongle without any restriction.

This is an attempt at documenting the low-level protocol. I hope it will give sender-app makers a clearer picture of what is happening behind the curtain, and give the others ideas about how this kind of protocol can be implemented. The information presented here has been collated from various internet sources (mainly exemple code and other attempts to implement the protocol) and my own trial and error. Correct me as needed as I may have gotten concepts or namings wrong.
This is an attempt at documenting the low-level protocol. I hope it will give sender-app makers a clearer picture of what is happening behind the curtain, and give the others ideas about how this kind of protocol can be implemented. The information presented here has been collated from various internet sources (mainly example code and other attempts to implement the protocol) and my own trial and error. Correct me as needed as I may have gotten concepts or namings wrong.

@@ -144,3 +144,3 @@ ### The TLS / Protocol Buffers layer

Before being able to echange messages with a receiver (be it an *application* or the *platform*), a sender must establish a *virtual connection* with it. This is accomplished through the `urn:x-cast:com.google.cast.tp.connection` namespace / protocol. This has the effect of both allowing the sender to send messages to the receiver, and of subscribing the sender to the receiver's broadcasts (eg. status updates).
Before being able to exchange messages with a receiver (be it an *application* or the *platform*), a sender must establish a *virtual connection* with it. This is accomplished through the `urn:x-cast:com.google.cast.tp.connection` namespace / protocol. This has the effect of both allowing the sender to send messages to the receiver, and of subscribing the sender to the receiver's broadcasts (eg. status updates).

@@ -160,3 +160,3 @@ The protocol is JSON encoded and the semantics are pretty simple :

Connections are kept alive through the `urn:x-cast:com.google.cast.tp.heartbeat` namespace / protocol. At regular intervals the sender must send a `PING` message that will get answered by a `PONG`. The protocol is JSON encoded.
Connections are kept alive through the `urn:x-cast:com.google.cast.tp.heartbeat` namespace / protocol. At regular intervals, the sender must send a `PING` message that will get answered by a `PONG`. The protocol is JSON encoded.

@@ -174,3 +174,3 @@ | **Message payload** | **Description**

First the sender sends a *challenge* message to the platform receiver `receiver-0` which responds by either a *response* message containing a signature, certificate and a variable number of certificate authority certificates that the sent certificate is verified against or an *error* message. These 3 payloads are protocol buffers encoded and described in `cast_channel.proto` as follows :
First, the sender sends a *challenge* message to the platform receiver `receiver-0` which responds by either a *response* message containing a signature, certificate and a variable number of certificate authority certificates that the sent certificate is verified against or an *error* message. These 3 payloads are protocol buffers encoded and described in `cast_channel.proto` as follows :

@@ -206,5 +206,5 @@ ```protobuf

The platform receiver `receiver-0` implements the `urn:x-cast:com.google.cast.receiver` namespace / protocol which provides an interface to *launch*, *stop*, and *query the status* of running applications. `receiver-0` also broadcast status messages on this namespace when other senders launch, stop, or affect the status of running apps. It also allows to check app for availability.
The platform receiver `receiver-0` implements the `urn:x-cast:com.google.cast.receiver` namespace / protocol which provides an interface to *launch*, *stop*, and *query the status* of running applications. `receiver-0` also broadcast status messages on this namespace when other senders launch, stop, or affect the status of running apps. It also allows checking the app for availability.
The protocol is JSON encoded and is request / response based. Requests include a `type` field containing the type of the request, namely `LAUNCH`, `STOP`, `GET_STATUS` and `GET_APP_AVAILABILITY`, and a `requestId` field that will be reflected in the receiver's response and allows the sender to pair request and responses. `requestId` is not shown in the table below but must be present in every request. In the wild it is an initially random integer that gets incremented for each subsequent request.
The protocol is JSON encoded and is request / response based. Requests include a `type` field containing the type of the request, namely `LAUNCH`, `STOP`, `GET_STATUS` and `GET_APP_AVAILABILITY`, and a `requestId` field that will be reflected in the receiver's response and allows the sender to pair request and responses. `requestId` is not shown in the table below but must be present in every request. In the wild, it is an initially random integer that gets incremented for each subsequent request.

@@ -249,3 +249,3 @@ | **Message payload** | **Description**

Another important field here is `transportId` as it is the destinationId to be used to communicate with the app. Note that the app being a receiver like any other you must issue it a `CONNECT` message through the `urn:x-cast:com.google.cast.tp.connection` procotol before being able to send messages. In this case this will have the side effect of subscribing you to media updates (on the media channel) of this *Default Media Player* session.
Another important field here is `transportId` as it is the destinationId to be used to communicate with the app. Note that the app being a receiver like any other you must issue it a `CONNECT` message through the `urn:x-cast:com.google.cast.tp.connection` protocol before being able to send messages. In this case, this will have the side effect of subscribing you to media updates (on the media channel) of this *Default Media Player* session.

@@ -252,0 +252,0 @@ You can join an existing session (launched by another sender) by issuing the same `CONNECT` message.

Sorry, the diff of this file is not supported yet

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc