@bharper/atv-js 0.2.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE.md +21 -0
- package/README.md +80 -0
- package/dist/airplay/auth.d.ts +24 -0
- package/dist/airplay/auth.d.ts.map +1 -0
- package/dist/airplay/auth.js +195 -0
- package/dist/airplay/auth.js.map +1 -0
- package/dist/bplist.d.ts +19 -0
- package/dist/bplist.d.ts.map +1 -0
- package/dist/bplist.js +141 -0
- package/dist/bplist.js.map +1 -0
- package/dist/companion/auth.d.ts +34 -0
- package/dist/companion/auth.d.ts.map +1 -0
- package/dist/companion/auth.js +119 -0
- package/dist/companion/auth.js.map +1 -0
- package/dist/companion/connection.d.ts +50 -0
- package/dist/companion/connection.d.ts.map +1 -0
- package/dist/companion/connection.js +170 -0
- package/dist/companion/connection.js.map +1 -0
- package/dist/companion/keyboard.d.ts +39 -0
- package/dist/companion/keyboard.d.ts.map +1 -0
- package/dist/companion/keyboard.js +127 -0
- package/dist/companion/keyboard.js.map +1 -0
- package/dist/companion/pairing_keepalive.d.ts +4 -0
- package/dist/companion/pairing_keepalive.d.ts.map +1 -0
- package/dist/companion/pairing_keepalive.js +68 -0
- package/dist/companion/pairing_keepalive.js.map +1 -0
- package/dist/companion/protocol.d.ts +64 -0
- package/dist/companion/protocol.d.ts.map +1 -0
- package/dist/companion/protocol.js +246 -0
- package/dist/companion/protocol.js.map +1 -0
- package/dist/companion/remote.d.ts +75 -0
- package/dist/companion/remote.d.ts.map +1 -0
- package/dist/companion/remote.js +142 -0
- package/dist/companion/remote.js.map +1 -0
- package/dist/crypto/chacha20.d.ts +27 -0
- package/dist/crypto/chacha20.d.ts.map +1 -0
- package/dist/crypto/chacha20.js +88 -0
- package/dist/crypto/chacha20.js.map +1 -0
- package/dist/crypto/hkdf.d.ts +6 -0
- package/dist/crypto/hkdf.d.ts.map +1 -0
- package/dist/crypto/hkdf.js +45 -0
- package/dist/crypto/hkdf.js.map +1 -0
- package/dist/index.d.ts +85 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +191 -0
- package/dist/index.js.map +1 -0
- package/dist/mdns.d.ts +20 -0
- package/dist/mdns.d.ts.map +1 -0
- package/dist/mdns.js +165 -0
- package/dist/mdns.js.map +1 -0
- package/dist/opack.d.ts +21 -0
- package/dist/opack.d.ts.map +1 -0
- package/dist/opack.js +350 -0
- package/dist/opack.js.map +1 -0
- package/dist/pairing/credentials.d.ts +23 -0
- package/dist/pairing/credentials.d.ts.map +1 -0
- package/dist/pairing/credentials.js +31 -0
- package/dist/pairing/credentials.js.map +1 -0
- package/dist/pairing/srp.d.ts +54 -0
- package/dist/pairing/srp.d.ts.map +1 -0
- package/dist/pairing/srp.js +221 -0
- package/dist/pairing/srp.js.map +1 -0
- package/dist/pairing/tlv.d.ts +26 -0
- package/dist/pairing/tlv.d.ts.map +1 -0
- package/dist/pairing/tlv.js +68 -0
- package/dist/pairing/tlv.js.map +1 -0
- package/examples/pair.ts +103 -0
- package/examples/remote.ts +212 -0
- package/package.json +33 -0
- package/src/airplay/auth.ts +207 -0
- package/src/bplist.ts +136 -0
- package/src/companion/auth.ts +141 -0
- package/src/companion/connection.ts +161 -0
- package/src/companion/keyboard.ts +155 -0
- package/src/companion/pairing_keepalive.ts +75 -0
- package/src/companion/protocol.ts +253 -0
- package/src/companion/remote.ts +151 -0
- package/src/crypto/chacha20.ts +93 -0
- package/src/crypto/hkdf.ts +18 -0
- package/src/index.ts +248 -0
- package/src/mdns.ts +198 -0
- package/src/opack.ts +299 -0
- package/src/pairing/credentials.ts +44 -0
- package/src/pairing/srp.ts +234 -0
- package/src/pairing/tlv.ts +64 -0
- package/tsconfig.json +19 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"auth.js","sourceRoot":"","sources":["../../src/companion/auth.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Companion protocol TCP connection with frame-based protocol.
|
|
3
|
+
* Port of pyatv/protocols/companion/connection.py.
|
|
4
|
+
*
|
|
5
|
+
* Frame format: [1-byte FrameType][3-byte big-endian payload length][payload]
|
|
6
|
+
* When encrypted, payload includes 16-byte auth tag in the length field.
|
|
7
|
+
*/
|
|
8
|
+
export declare enum FrameType {
|
|
9
|
+
Unknown = 0,
|
|
10
|
+
NoOp = 1,
|
|
11
|
+
PS_Start = 3,
|
|
12
|
+
PS_Next = 4,
|
|
13
|
+
PV_Start = 5,
|
|
14
|
+
PV_Next = 6,
|
|
15
|
+
U_OPACK = 7,
|
|
16
|
+
E_OPACK = 8,
|
|
17
|
+
P_OPACK = 9,
|
|
18
|
+
PA_Req = 10,
|
|
19
|
+
PA_Rsp = 11,
|
|
20
|
+
SessionStartRequest = 16,
|
|
21
|
+
SessionStartResponse = 17,
|
|
22
|
+
SessionData = 18,
|
|
23
|
+
FamilyIdentityRequest = 32,
|
|
24
|
+
FamilyIdentityResponse = 33,
|
|
25
|
+
FamilyIdentityUpdate = 34
|
|
26
|
+
}
|
|
27
|
+
export interface FrameListener {
|
|
28
|
+
frameReceived(frameType: FrameType, payload: Buffer): void;
|
|
29
|
+
connectionLost(error?: Error): void;
|
|
30
|
+
}
|
|
31
|
+
export declare class CompanionConnection {
|
|
32
|
+
private socket;
|
|
33
|
+
private buffer;
|
|
34
|
+
private chacha;
|
|
35
|
+
private listener;
|
|
36
|
+
private host;
|
|
37
|
+
private port;
|
|
38
|
+
private connected;
|
|
39
|
+
constructor(host: string, port: number, listener?: FrameListener);
|
|
40
|
+
setListener(listener: FrameListener): void;
|
|
41
|
+
connect(): Promise<void>;
|
|
42
|
+
private processBuffer;
|
|
43
|
+
send(frameType: FrameType, data: Buffer): void;
|
|
44
|
+
enableEncryption(outputKey: Buffer, inputKey: Buffer): void;
|
|
45
|
+
close(): void;
|
|
46
|
+
get isConnected(): boolean;
|
|
47
|
+
getHost(): string;
|
|
48
|
+
getPort(): number;
|
|
49
|
+
}
|
|
50
|
+
//# sourceMappingURL=connection.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"connection.d.ts","sourceRoot":"","sources":["../../src/companion/connection.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAOH,oBAAY,SAAS;IACnB,OAAO,IAAI;IACX,IAAI,IAAI;IACR,QAAQ,IAAI;IACZ,OAAO,IAAI;IACX,QAAQ,IAAI;IACZ,OAAO,IAAI;IACX,OAAO,IAAI;IACX,OAAO,IAAI;IACX,OAAO,IAAI;IACX,MAAM,KAAK;IACX,MAAM,KAAK;IACX,mBAAmB,KAAK;IACxB,oBAAoB,KAAK;IACzB,WAAW,KAAK;IAChB,qBAAqB,KAAK;IAC1B,sBAAsB,KAAK;IAC3B,oBAAoB,KAAK;CAC1B;AAID,MAAM,WAAW,aAAa;IAC5B,aAAa,CAAC,SAAS,EAAE,SAAS,EAAE,OAAO,EAAE,MAAM,GAAG,IAAI,CAAC;IAC3D,cAAc,CAAC,KAAK,CAAC,EAAE,KAAK,GAAG,IAAI,CAAC;CACrC;AAED,qBAAa,mBAAmB;IAC9B,OAAO,CAAC,MAAM,CAA2B;IACzC,OAAO,CAAC,MAAM,CAAmB;IACjC,OAAO,CAAC,MAAM,CAA+B;IAC7C,OAAO,CAAC,QAAQ,CAAgB;IAChC,OAAO,CAAC,IAAI,CAAS;IACrB,OAAO,CAAC,IAAI,CAAS;IACrB,OAAO,CAAC,SAAS,CAAS;gBAEd,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,QAAQ,CAAC,EAAE,aAAa;IAMhE,WAAW,CAAC,QAAQ,EAAE,aAAa,GAAG,IAAI;IAIpC,OAAO,IAAI,OAAO,CAAC,IAAI,CAAC;IA6B9B,OAAO,CAAC,aAAa;IAyBrB,IAAI,CAAC,SAAS,EAAE,SAAS,EAAE,IAAI,EAAE,MAAM,GAAG,IAAI;IAwB9C,gBAAgB,CAAC,SAAS,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,IAAI;IAI3D,KAAK,IAAI,IAAI;IAQb,IAAI,WAAW,IAAI,OAAO,CAEzB;IAED,OAAO,IAAI,MAAM;IAIjB,OAAO,IAAI,MAAM;CAGlB"}
|
|
@@ -0,0 +1,170 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Companion protocol TCP connection with frame-based protocol.
|
|
4
|
+
* Port of pyatv/protocols/companion/connection.py.
|
|
5
|
+
*
|
|
6
|
+
* Frame format: [1-byte FrameType][3-byte big-endian payload length][payload]
|
|
7
|
+
* When encrypted, payload includes 16-byte auth tag in the length field.
|
|
8
|
+
*/
|
|
9
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
12
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
13
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
14
|
+
}
|
|
15
|
+
Object.defineProperty(o, k2, desc);
|
|
16
|
+
}) : (function(o, m, k, k2) {
|
|
17
|
+
if (k2 === undefined) k2 = k;
|
|
18
|
+
o[k2] = m[k];
|
|
19
|
+
}));
|
|
20
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
21
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
22
|
+
}) : function(o, v) {
|
|
23
|
+
o["default"] = v;
|
|
24
|
+
});
|
|
25
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
26
|
+
var ownKeys = function(o) {
|
|
27
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
28
|
+
var ar = [];
|
|
29
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
30
|
+
return ar;
|
|
31
|
+
};
|
|
32
|
+
return ownKeys(o);
|
|
33
|
+
};
|
|
34
|
+
return function (mod) {
|
|
35
|
+
if (mod && mod.__esModule) return mod;
|
|
36
|
+
var result = {};
|
|
37
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
38
|
+
__setModuleDefault(result, mod);
|
|
39
|
+
return result;
|
|
40
|
+
};
|
|
41
|
+
})();
|
|
42
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
43
|
+
exports.CompanionConnection = exports.FrameType = void 0;
|
|
44
|
+
const net = __importStar(require("net"));
|
|
45
|
+
const chacha20_1 = require("../crypto/chacha20");
|
|
46
|
+
var FrameType;
|
|
47
|
+
(function (FrameType) {
|
|
48
|
+
FrameType[FrameType["Unknown"] = 0] = "Unknown";
|
|
49
|
+
FrameType[FrameType["NoOp"] = 1] = "NoOp";
|
|
50
|
+
FrameType[FrameType["PS_Start"] = 3] = "PS_Start";
|
|
51
|
+
FrameType[FrameType["PS_Next"] = 4] = "PS_Next";
|
|
52
|
+
FrameType[FrameType["PV_Start"] = 5] = "PV_Start";
|
|
53
|
+
FrameType[FrameType["PV_Next"] = 6] = "PV_Next";
|
|
54
|
+
FrameType[FrameType["U_OPACK"] = 7] = "U_OPACK";
|
|
55
|
+
FrameType[FrameType["E_OPACK"] = 8] = "E_OPACK";
|
|
56
|
+
FrameType[FrameType["P_OPACK"] = 9] = "P_OPACK";
|
|
57
|
+
FrameType[FrameType["PA_Req"] = 10] = "PA_Req";
|
|
58
|
+
FrameType[FrameType["PA_Rsp"] = 11] = "PA_Rsp";
|
|
59
|
+
FrameType[FrameType["SessionStartRequest"] = 16] = "SessionStartRequest";
|
|
60
|
+
FrameType[FrameType["SessionStartResponse"] = 17] = "SessionStartResponse";
|
|
61
|
+
FrameType[FrameType["SessionData"] = 18] = "SessionData";
|
|
62
|
+
FrameType[FrameType["FamilyIdentityRequest"] = 32] = "FamilyIdentityRequest";
|
|
63
|
+
FrameType[FrameType["FamilyIdentityResponse"] = 33] = "FamilyIdentityResponse";
|
|
64
|
+
FrameType[FrameType["FamilyIdentityUpdate"] = 34] = "FamilyIdentityUpdate";
|
|
65
|
+
})(FrameType || (exports.FrameType = FrameType = {}));
|
|
66
|
+
const HEADER_LENGTH = 4;
|
|
67
|
+
class CompanionConnection {
|
|
68
|
+
socket = null;
|
|
69
|
+
buffer = Buffer.alloc(0);
|
|
70
|
+
chacha = null;
|
|
71
|
+
listener;
|
|
72
|
+
host;
|
|
73
|
+
port;
|
|
74
|
+
connected = false;
|
|
75
|
+
constructor(host, port, listener) {
|
|
76
|
+
this.host = host;
|
|
77
|
+
this.port = port;
|
|
78
|
+
this.listener = listener || { frameReceived: () => { }, connectionLost: () => { } };
|
|
79
|
+
}
|
|
80
|
+
setListener(listener) {
|
|
81
|
+
this.listener = listener;
|
|
82
|
+
}
|
|
83
|
+
async connect() {
|
|
84
|
+
if (this.connected)
|
|
85
|
+
return;
|
|
86
|
+
return new Promise((resolve, reject) => {
|
|
87
|
+
this.socket = net.createConnection({ host: this.host, port: this.port }, () => {
|
|
88
|
+
this.connected = true;
|
|
89
|
+
this.socket?.unref();
|
|
90
|
+
resolve();
|
|
91
|
+
});
|
|
92
|
+
this.socket.on('data', (data) => {
|
|
93
|
+
this.buffer = Buffer.concat([this.buffer, data]);
|
|
94
|
+
this.processBuffer();
|
|
95
|
+
});
|
|
96
|
+
this.socket.on('error', (err) => {
|
|
97
|
+
if (!this.connected) {
|
|
98
|
+
reject(err);
|
|
99
|
+
}
|
|
100
|
+
else {
|
|
101
|
+
this.listener.connectionLost(err);
|
|
102
|
+
}
|
|
103
|
+
});
|
|
104
|
+
this.socket.on('close', () => {
|
|
105
|
+
this.connected = false;
|
|
106
|
+
this.listener.connectionLost();
|
|
107
|
+
});
|
|
108
|
+
});
|
|
109
|
+
}
|
|
110
|
+
processBuffer() {
|
|
111
|
+
while (this.buffer.length >= HEADER_LENGTH) {
|
|
112
|
+
const payloadLength = HEADER_LENGTH + ((this.buffer[1] << 16) | (this.buffer[2] << 8) | this.buffer[3]);
|
|
113
|
+
if (this.buffer.length < payloadLength)
|
|
114
|
+
break;
|
|
115
|
+
const header = this.buffer.subarray(0, HEADER_LENGTH);
|
|
116
|
+
let payload = Buffer.from(this.buffer.subarray(HEADER_LENGTH, payloadLength));
|
|
117
|
+
this.buffer = this.buffer.subarray(payloadLength);
|
|
118
|
+
if (this.chacha && payload.length > 0) {
|
|
119
|
+
try {
|
|
120
|
+
payload = this.chacha.decrypt(payload, undefined, header);
|
|
121
|
+
}
|
|
122
|
+
catch (err) {
|
|
123
|
+
// Decryption failed, skip this frame
|
|
124
|
+
continue;
|
|
125
|
+
}
|
|
126
|
+
}
|
|
127
|
+
this.listener.frameReceived(header[0], payload);
|
|
128
|
+
}
|
|
129
|
+
}
|
|
130
|
+
send(frameType, data) {
|
|
131
|
+
if (!this.socket || !this.connected) {
|
|
132
|
+
throw new Error('Not connected');
|
|
133
|
+
}
|
|
134
|
+
let payloadLength = data.length;
|
|
135
|
+
if (this.chacha && payloadLength > 0) {
|
|
136
|
+
payloadLength += chacha20_1.AUTH_TAG_LENGTH;
|
|
137
|
+
}
|
|
138
|
+
const header = Buffer.alloc(HEADER_LENGTH);
|
|
139
|
+
header[0] = frameType;
|
|
140
|
+
header[1] = (payloadLength >> 16) & 0xff;
|
|
141
|
+
header[2] = (payloadLength >> 8) & 0xff;
|
|
142
|
+
header[3] = payloadLength & 0xff;
|
|
143
|
+
let payload = data;
|
|
144
|
+
if (this.chacha && data.length > 0) {
|
|
145
|
+
payload = this.chacha.encrypt(data, undefined, header);
|
|
146
|
+
}
|
|
147
|
+
this.socket.write(Buffer.concat([header, payload]));
|
|
148
|
+
}
|
|
149
|
+
enableEncryption(outputKey, inputKey) {
|
|
150
|
+
this.chacha = new chacha20_1.Chacha20Cipher(outputKey, inputKey, 12);
|
|
151
|
+
}
|
|
152
|
+
close() {
|
|
153
|
+
this.connected = false;
|
|
154
|
+
if (this.socket) {
|
|
155
|
+
this.socket.destroy();
|
|
156
|
+
this.socket = null;
|
|
157
|
+
}
|
|
158
|
+
}
|
|
159
|
+
get isConnected() {
|
|
160
|
+
return this.connected;
|
|
161
|
+
}
|
|
162
|
+
getHost() {
|
|
163
|
+
return this.host;
|
|
164
|
+
}
|
|
165
|
+
getPort() {
|
|
166
|
+
return this.port;
|
|
167
|
+
}
|
|
168
|
+
}
|
|
169
|
+
exports.CompanionConnection = CompanionConnection;
|
|
170
|
+
//# sourceMappingURL=connection.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"connection.js","sourceRoot":"","sources":["../../src/companion/connection.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Keyboard/text input via Companion protocol.
|
|
3
|
+
* Port of pyatv/protocols/companion/api.py text input handling +
|
|
4
|
+
* pyatv/protocols/companion/__init__.py CompanionKeyboard.
|
|
5
|
+
*/
|
|
6
|
+
import { CompanionProtocol } from './protocol';
|
|
7
|
+
export declare enum KeyboardFocusState {
|
|
8
|
+
Unknown = "unknown",
|
|
9
|
+
Focused = "focused",
|
|
10
|
+
Unfocused = "unfocused"
|
|
11
|
+
}
|
|
12
|
+
export interface KeyboardState {
|
|
13
|
+
focusState: KeyboardFocusState;
|
|
14
|
+
}
|
|
15
|
+
/**
|
|
16
|
+
* Execute a text input command: optionally clear existing text, then append new text.
|
|
17
|
+
* Returns the current text after the operation, or null if keyboard not focused.
|
|
18
|
+
*/
|
|
19
|
+
export declare function textInputCommand(protocol: CompanionProtocol, text: string, clearPreviousInput: boolean): Promise<string | null>;
|
|
20
|
+
/**
|
|
21
|
+
* Get the current text from a focused keyboard.
|
|
22
|
+
*/
|
|
23
|
+
export declare function getText(protocol: CompanionProtocol): Promise<string | null>;
|
|
24
|
+
/**
|
|
25
|
+
* Set (replace) the text in a focused keyboard.
|
|
26
|
+
*/
|
|
27
|
+
export declare function setText(protocol: CompanionProtocol, text: string): Promise<void>;
|
|
28
|
+
/**
|
|
29
|
+
* Check if keyboard is currently focused by starting a text input session.
|
|
30
|
+
*/
|
|
31
|
+
export declare function getKeyboardFocus(protocol: CompanionProtocol): Promise<boolean>;
|
|
32
|
+
/**
|
|
33
|
+
* Register keyboard focus state listeners on a protocol instance.
|
|
34
|
+
* Uses polling since _tiStarted/_tiStopped events aren't reliably pushed.
|
|
35
|
+
* Calls the callback whenever focus state changes.
|
|
36
|
+
* Returns a function to stop the polling.
|
|
37
|
+
*/
|
|
38
|
+
export declare function watchKeyboardFocus(protocol: CompanionProtocol, callback: (state: KeyboardFocusState) => void, pollIntervalMs?: number): () => void;
|
|
39
|
+
//# sourceMappingURL=keyboard.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"keyboard.d.ts","sourceRoot":"","sources":["../../src/companion/keyboard.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,EAAE,iBAAiB,EAAE,MAAM,YAAY,CAAC;AAG/C,oBAAY,kBAAkB;IAC5B,OAAO,YAAY;IACnB,OAAO,YAAY;IACnB,SAAS,cAAc;CACxB;AAED,MAAM,WAAW,aAAa;IAC5B,UAAU,EAAE,kBAAkB,CAAC;CAChC;AAgBD;;;GAGG;AACH,wBAAsB,gBAAgB,CACpC,QAAQ,EAAE,iBAAiB,EAC3B,IAAI,EAAE,MAAM,EACZ,kBAAkB,EAAE,OAAO,GAC1B,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,CA4CxB;AAED;;GAEG;AACH,wBAAsB,OAAO,CAAC,QAAQ,EAAE,iBAAiB,GAAG,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,CAEjF;AAED;;GAEG;AACH,wBAAsB,OAAO,CAAC,QAAQ,EAAE,iBAAiB,EAAE,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAEtF;AAED;;GAEG;AACH,wBAAsB,gBAAgB,CAAC,QAAQ,EAAE,iBAAiB,GAAG,OAAO,CAAC,OAAO,CAAC,CAKpF;AAED;;;;;GAKG;AACH,wBAAgB,kBAAkB,CAChC,QAAQ,EAAE,iBAAiB,EAC3B,QAAQ,EAAE,CAAC,KAAK,EAAE,kBAAkB,KAAK,IAAI,EAC7C,cAAc,SAAO,GACpB,MAAM,IAAI,CAiCZ"}
|
|
@@ -0,0 +1,127 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Keyboard/text input via Companion protocol.
|
|
4
|
+
* Port of pyatv/protocols/companion/api.py text input handling +
|
|
5
|
+
* pyatv/protocols/companion/__init__.py CompanionKeyboard.
|
|
6
|
+
*/
|
|
7
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
8
|
+
exports.KeyboardFocusState = void 0;
|
|
9
|
+
exports.textInputCommand = textInputCommand;
|
|
10
|
+
exports.getText = getText;
|
|
11
|
+
exports.setText = setText;
|
|
12
|
+
exports.getKeyboardFocus = getKeyboardFocus;
|
|
13
|
+
exports.watchKeyboardFocus = watchKeyboardFocus;
|
|
14
|
+
const bplist_1 = require("../bplist");
|
|
15
|
+
var KeyboardFocusState;
|
|
16
|
+
(function (KeyboardFocusState) {
|
|
17
|
+
KeyboardFocusState["Unknown"] = "unknown";
|
|
18
|
+
KeyboardFocusState["Focused"] = "focused";
|
|
19
|
+
KeyboardFocusState["Unfocused"] = "unfocused";
|
|
20
|
+
})(KeyboardFocusState || (exports.KeyboardFocusState = KeyboardFocusState = {}));
|
|
21
|
+
/**
|
|
22
|
+
* Start a text input session. Returns the response containing _tiD if keyboard is focused.
|
|
23
|
+
*/
|
|
24
|
+
async function textInputStart(protocol) {
|
|
25
|
+
return protocol.sendCommand('_tiStart', {});
|
|
26
|
+
}
|
|
27
|
+
/**
|
|
28
|
+
* Stop a text input session.
|
|
29
|
+
*/
|
|
30
|
+
async function textInputStop(protocol) {
|
|
31
|
+
return protocol.sendCommand('_tiStop', {});
|
|
32
|
+
}
|
|
33
|
+
/**
|
|
34
|
+
* Execute a text input command: optionally clear existing text, then append new text.
|
|
35
|
+
* Returns the current text after the operation, or null if keyboard not focused.
|
|
36
|
+
*/
|
|
37
|
+
async function textInputCommand(protocol, text, clearPreviousInput) {
|
|
38
|
+
// Restart session to get latest state
|
|
39
|
+
await textInputStop(protocol);
|
|
40
|
+
const response = await textInputStart(protocol);
|
|
41
|
+
const content = (response._c || {});
|
|
42
|
+
const tiData = content._tiD;
|
|
43
|
+
if (!tiData || !Buffer.isBuffer(tiData)) {
|
|
44
|
+
return null; // Keyboard not focused
|
|
45
|
+
}
|
|
46
|
+
// Extract session UUID and current text from NSKeyedArchiver data
|
|
47
|
+
const [sessionUuid, currentTextRaw] = (0, bplist_1.readArchiveProperties)(tiData, ['sessionUUID'], ['documentState', 'docSt', 'contextBeforeInput']);
|
|
48
|
+
if (!sessionUuid || !Buffer.isBuffer(sessionUuid)) {
|
|
49
|
+
return null;
|
|
50
|
+
}
|
|
51
|
+
let currentText = typeof currentTextRaw === 'string' ? currentTextRaw : '';
|
|
52
|
+
// Clear text if requested
|
|
53
|
+
if (clearPreviousInput) {
|
|
54
|
+
protocol.sendEvent('_tiC', {
|
|
55
|
+
_tiV: 1,
|
|
56
|
+
_tiD: (0, bplist_1.createRtiClearTextPayload)(sessionUuid),
|
|
57
|
+
});
|
|
58
|
+
currentText = '';
|
|
59
|
+
}
|
|
60
|
+
// Append new text
|
|
61
|
+
if (text) {
|
|
62
|
+
protocol.sendEvent('_tiC', {
|
|
63
|
+
_tiV: 1,
|
|
64
|
+
_tiD: (0, bplist_1.createRtiInputTextPayload)(sessionUuid, text),
|
|
65
|
+
});
|
|
66
|
+
currentText += text;
|
|
67
|
+
}
|
|
68
|
+
return currentText;
|
|
69
|
+
}
|
|
70
|
+
/**
|
|
71
|
+
* Get the current text from a focused keyboard.
|
|
72
|
+
*/
|
|
73
|
+
async function getText(protocol) {
|
|
74
|
+
return textInputCommand(protocol, '', false);
|
|
75
|
+
}
|
|
76
|
+
/**
|
|
77
|
+
* Set (replace) the text in a focused keyboard.
|
|
78
|
+
*/
|
|
79
|
+
async function setText(protocol, text) {
|
|
80
|
+
await textInputCommand(protocol, text, true);
|
|
81
|
+
}
|
|
82
|
+
/**
|
|
83
|
+
* Check if keyboard is currently focused by starting a text input session.
|
|
84
|
+
*/
|
|
85
|
+
async function getKeyboardFocus(protocol) {
|
|
86
|
+
await textInputStop(protocol);
|
|
87
|
+
const response = await textInputStart(protocol);
|
|
88
|
+
const content = (response._c || {});
|
|
89
|
+
return '_tiD' in content && content._tiD !== null && content._tiD !== undefined;
|
|
90
|
+
}
|
|
91
|
+
/**
|
|
92
|
+
* Register keyboard focus state listeners on a protocol instance.
|
|
93
|
+
* Uses polling since _tiStarted/_tiStopped events aren't reliably pushed.
|
|
94
|
+
* Calls the callback whenever focus state changes.
|
|
95
|
+
* Returns a function to stop the polling.
|
|
96
|
+
*/
|
|
97
|
+
function watchKeyboardFocus(protocol, callback, pollIntervalMs = 1000) {
|
|
98
|
+
let lastState = KeyboardFocusState.Unknown;
|
|
99
|
+
let running = true;
|
|
100
|
+
const poll = async () => {
|
|
101
|
+
if (!running)
|
|
102
|
+
return;
|
|
103
|
+
try {
|
|
104
|
+
const focused = await getKeyboardFocus(protocol);
|
|
105
|
+
const newState = focused ? KeyboardFocusState.Focused : KeyboardFocusState.Unfocused;
|
|
106
|
+
if (newState !== lastState) {
|
|
107
|
+
lastState = newState;
|
|
108
|
+
callback(newState);
|
|
109
|
+
}
|
|
110
|
+
}
|
|
111
|
+
catch {
|
|
112
|
+
// Connection may be closed, stop polling
|
|
113
|
+
running = false;
|
|
114
|
+
return;
|
|
115
|
+
}
|
|
116
|
+
if (running) {
|
|
117
|
+
setTimeout(poll, pollIntervalMs);
|
|
118
|
+
}
|
|
119
|
+
};
|
|
120
|
+
// Start polling
|
|
121
|
+
poll();
|
|
122
|
+
// Return stop function
|
|
123
|
+
return () => {
|
|
124
|
+
running = false;
|
|
125
|
+
};
|
|
126
|
+
}
|
|
127
|
+
//# sourceMappingURL=keyboard.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"keyboard.js","sourceRoot":"","sources":["../../src/companion/keyboard.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
import { CompanionConnection } from './connection';
|
|
2
|
+
export declare function getCompanionPairingConnection(host: string, port: number): CompanionConnection;
|
|
3
|
+
export declare function releaseCompanionPairingConnection(connection: CompanionConnection): void;
|
|
4
|
+
//# sourceMappingURL=pairing_keepalive.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"pairing_keepalive.d.ts","sourceRoot":"","sources":["../../src/companion/pairing_keepalive.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,mBAAmB,EAAE,MAAM,cAAc,CAAC;AA4BnD,wBAAgB,6BAA6B,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,mBAAmB,CAwB7F;AAED,wBAAgB,iCAAiC,CAAC,UAAU,EAAE,mBAAmB,GAAG,IAAI,CAoBvF"}
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.getCompanionPairingConnection = getCompanionPairingConnection;
|
|
4
|
+
exports.releaseCompanionPairingConnection = releaseCompanionPairingConnection;
|
|
5
|
+
const connection_1 = require("./connection");
|
|
6
|
+
const COMPANION_AGENT_IDLE_MS = 2 * 60 * 1000;
|
|
7
|
+
const connectionCache = new Map();
|
|
8
|
+
function connectionKey(host, port) {
|
|
9
|
+
return `${host}:${port}`;
|
|
10
|
+
}
|
|
11
|
+
function scheduleCleanup(key, entry) {
|
|
12
|
+
if (entry.timer)
|
|
13
|
+
clearTimeout(entry.timer);
|
|
14
|
+
entry.lastUsed = Date.now();
|
|
15
|
+
entry.timer = setTimeout(() => {
|
|
16
|
+
if (Date.now() - entry.lastUsed >= COMPANION_AGENT_IDLE_MS) {
|
|
17
|
+
entry.connection.close();
|
|
18
|
+
connectionCache.delete(key);
|
|
19
|
+
}
|
|
20
|
+
}, COMPANION_AGENT_IDLE_MS);
|
|
21
|
+
entry.timer.unref();
|
|
22
|
+
}
|
|
23
|
+
function getCompanionPairingConnection(host, port) {
|
|
24
|
+
const key = connectionKey(host, port);
|
|
25
|
+
const existing = connectionCache.get(key);
|
|
26
|
+
if (existing) {
|
|
27
|
+
if (existing.connection.isConnected) {
|
|
28
|
+
scheduleCleanup(key, existing);
|
|
29
|
+
return existing.connection;
|
|
30
|
+
}
|
|
31
|
+
existing.connection.close();
|
|
32
|
+
connectionCache.delete(key);
|
|
33
|
+
}
|
|
34
|
+
const connection = new connection_1.CompanionConnection(host, port);
|
|
35
|
+
const entry = {
|
|
36
|
+
connection,
|
|
37
|
+
lastUsed: Date.now(),
|
|
38
|
+
timer: setTimeout(() => {
|
|
39
|
+
connection.close();
|
|
40
|
+
connectionCache.delete(key);
|
|
41
|
+
}, COMPANION_AGENT_IDLE_MS),
|
|
42
|
+
};
|
|
43
|
+
entry.timer.unref();
|
|
44
|
+
connectionCache.set(key, entry);
|
|
45
|
+
return connection;
|
|
46
|
+
}
|
|
47
|
+
function releaseCompanionPairingConnection(connection) {
|
|
48
|
+
const key = connectionKey(connection.getHost(), connection.getPort());
|
|
49
|
+
const existing = connectionCache.get(key);
|
|
50
|
+
if (existing) {
|
|
51
|
+
scheduleCleanup(key, existing);
|
|
52
|
+
}
|
|
53
|
+
else {
|
|
54
|
+
const entry = {
|
|
55
|
+
connection,
|
|
56
|
+
lastUsed: Date.now(),
|
|
57
|
+
timer: setTimeout(() => {
|
|
58
|
+
connection.close();
|
|
59
|
+
connectionCache.delete(key);
|
|
60
|
+
}, COMPANION_AGENT_IDLE_MS),
|
|
61
|
+
};
|
|
62
|
+
entry.timer.unref();
|
|
63
|
+
connectionCache.set(key, entry);
|
|
64
|
+
}
|
|
65
|
+
// Detach listener to avoid delivering stale events.
|
|
66
|
+
connection.setListener({ frameReceived: () => { }, connectionLost: () => { } });
|
|
67
|
+
}
|
|
68
|
+
//# sourceMappingURL=pairing_keepalive.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"pairing_keepalive.js","sourceRoot":"","sources":["../../src/companion/pairing_keepalive.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Companion protocol message dispatch layer.
|
|
3
|
+
* Port of pyatv/protocols/companion/protocol.py.
|
|
4
|
+
*
|
|
5
|
+
* Messages are OPACK-encoded with structure:
|
|
6
|
+
* { _i: identifier, _t: messageType, _c: content, _x: transactionId }
|
|
7
|
+
*/
|
|
8
|
+
import { CompanionConnection, FrameType, FrameListener } from './connection';
|
|
9
|
+
export declare enum MessageType {
|
|
10
|
+
Event = 1,
|
|
11
|
+
Request = 2,
|
|
12
|
+
Response = 3
|
|
13
|
+
}
|
|
14
|
+
export interface CompanionEventListener {
|
|
15
|
+
(data: Record<string, unknown>): void;
|
|
16
|
+
}
|
|
17
|
+
export declare class CompanionProtocol implements FrameListener {
|
|
18
|
+
connection: CompanionConnection;
|
|
19
|
+
private xid;
|
|
20
|
+
private pendingRequests;
|
|
21
|
+
private pendingAuth;
|
|
22
|
+
private eventListeners;
|
|
23
|
+
private events;
|
|
24
|
+
private srp;
|
|
25
|
+
private credentialString;
|
|
26
|
+
private _onConnectionLost?;
|
|
27
|
+
constructor(connection: CompanionConnection, credentialString: string | null);
|
|
28
|
+
set onConnectionLost(handler: (error?: Error) => void);
|
|
29
|
+
frameReceived(frameType: FrameType, payload: Buffer): void;
|
|
30
|
+
connectionLost(error?: Error): void;
|
|
31
|
+
private handleAuthFrame;
|
|
32
|
+
/**
|
|
33
|
+
* Exchange an auth frame and wait for the response.
|
|
34
|
+
*/
|
|
35
|
+
exchangeAuth(frameType: FrameType, data: Record<string, unknown>, timeout?: number): Promise<Record<string, unknown>>;
|
|
36
|
+
private handleOpack;
|
|
37
|
+
/**
|
|
38
|
+
* Send an OPACK request and wait for the response.
|
|
39
|
+
*/
|
|
40
|
+
exchangeOpack(data: Record<string, unknown>, frameType?: FrameType, timeout?: number): Promise<Record<string, unknown>>;
|
|
41
|
+
/**
|
|
42
|
+
* Send an OPACK event (no response expected).
|
|
43
|
+
*/
|
|
44
|
+
sendEvent(identifier: string, content: Record<string, unknown>): void;
|
|
45
|
+
/**
|
|
46
|
+
* Send an OPACK request with standard message structure.
|
|
47
|
+
*/
|
|
48
|
+
sendCommand(identifier: string, content?: Record<string, unknown>, timeout?: number): Promise<Record<string, unknown>>;
|
|
49
|
+
/**
|
|
50
|
+
* Register a listener for a specific event name.
|
|
51
|
+
*/
|
|
52
|
+
listenTo(eventName: string, listener: CompanionEventListener): void;
|
|
53
|
+
/**
|
|
54
|
+
* Subscribe to device events.
|
|
55
|
+
*/
|
|
56
|
+
subscribeEvent(eventName: string): Promise<void>;
|
|
57
|
+
/**
|
|
58
|
+
* Start the protocol: connect, verify credentials if available, enable encryption.
|
|
59
|
+
*/
|
|
60
|
+
start(): Promise<void>;
|
|
61
|
+
private setupEncryption;
|
|
62
|
+
close(): void;
|
|
63
|
+
}
|
|
64
|
+
//# sourceMappingURL=protocol.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"protocol.d.ts","sourceRoot":"","sources":["../../src/companion/protocol.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAGH,OAAO,EAAE,mBAAmB,EAAE,SAAS,EAAE,aAAa,EAAE,MAAM,cAAc,CAAC;AAM7E,oBAAY,WAAW;IACrB,KAAK,IAAI;IACT,OAAO,IAAI;IACX,QAAQ,IAAI;CACb;AAUD,MAAM,WAAW,sBAAsB;IACrC,CAAC,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,IAAI,CAAC;CACvC;AAED,qBAAa,iBAAkB,YAAW,aAAa;IACrD,UAAU,EAAE,mBAAmB,CAAC;IAChC,OAAO,CAAC,GAAG,CAAuC;IAClD,OAAO,CAAC,eAAe,CAAqC;IAC5D,OAAO,CAAC,WAAW,CAAqC;IACxD,OAAO,CAAC,cAAc,CAA+C;IACrE,OAAO,CAAC,MAAM,CAAsB;IACpC,OAAO,CAAC,GAAG,CAAiB;IAC5B,OAAO,CAAC,gBAAgB,CAAgB;IACxC,OAAO,CAAC,iBAAiB,CAAC,CAA0B;gBAExC,UAAU,EAAE,mBAAmB,EAAE,gBAAgB,EAAE,MAAM,GAAG,IAAI;IAM5E,IAAI,gBAAgB,CAAC,OAAO,EAAE,CAAC,KAAK,CAAC,EAAE,KAAK,KAAK,IAAI,EAEpD;IAID,aAAa,CAAC,SAAS,EAAE,SAAS,EAAE,OAAO,EAAE,MAAM,GAAG,IAAI;IAe1D,cAAc,CAAC,KAAK,CAAC,EAAE,KAAK,GAAG,IAAI;IAmBnC,OAAO,CAAC,eAAe;IAevB;;OAEG;IACG,YAAY,CAChB,SAAS,EAAE,SAAS,EACpB,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAC7B,OAAO,SAAkB,GACxB,OAAO,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IAyBnC,OAAO,CAAC,WAAW;IAwBnB;;OAEG;IACG,aAAa,CACjB,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAC7B,SAAS,GAAE,SAA6B,EACxC,OAAO,SAAkB,GACxB,OAAO,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IAenC;;OAEG;IACH,SAAS,CAAC,UAAU,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,IAAI;IAUrE;;OAEG;IACG,WAAW,CACf,UAAU,EAAE,MAAM,EAClB,OAAO,GAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAM,EACrC,OAAO,SAAkB,GACxB,OAAO,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IASnC;;OAEG;IACH,QAAQ,CAAC,SAAS,EAAE,MAAM,EAAE,QAAQ,EAAE,sBAAsB,GAAG,IAAI;IAMnE;;OAEG;IACG,cAAc,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAMtD;;OAEG;IACG,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC;YASd,eAAe;IAO7B,KAAK,IAAI,IAAI;CAGd"}
|