UNPKG

13.3 kBTypeScriptView Raw
1import { EventEmitter } from "events";
2import { Socket } from "net";
3import { HAPConnection } from "../util/eventedhttp";
4/**
5 * @group HomeKit Data Streams (HDS)
6 */
7export type PreparedDataStreamSession = {
8 connection: HAPConnection;
9 accessoryToControllerEncryptionKey: Buffer;
10 controllerToAccessoryEncryptionKey: Buffer;
11 accessoryKeySalt: Buffer;
12 port?: number;
13 connectTimeout?: NodeJS.Timeout;
14};
15/**
16 * @group HomeKit Data Streams (HDS)
17 */
18export type PrepareSessionCallback = (error?: Error, preparedSession?: PreparedDataStreamSession) => void;
19/**
20 * @group HomeKit Data Streams (HDS)
21 */
22export type EventHandler = (message: Record<any, any>) => void;
23/**
24 * @group HomeKit Data Streams (HDS)
25 */
26export type RequestHandler = (id: number, message: Record<any, any>) => void;
27/**
28 * @group HomeKit Data Streams (HDS)
29 */
30export type ResponseHandler = (error: Error | undefined, status: HDSStatus | undefined, message: Record<any, any>) => void;
31/**
32 * @group HomeKit Data Streams (HDS)
33 */
34export type GlobalEventHandler = (connection: DataStreamConnection, message: Record<any, any>) => void;
35/**
36 * @group HomeKit Data Streams (HDS)
37 */
38export type GlobalRequestHandler = (connection: DataStreamConnection, id: number, message: Record<any, any>) => void;
39/**
40 * @group HomeKit Data Streams (HDS)
41 */
42export interface DataStreamProtocolHandler {
43 eventHandler?: Record<string, EventHandler>;
44 requestHandler?: Record<string, RequestHandler>;
45}
46/**
47 * @group HomeKit Data Streams (HDS)
48 */
49export declare const enum Protocols {
50 CONTROL = "control",
51 TARGET_CONTROL = "targetControl",
52 DATA_SEND = "dataSend"
53}
54/**
55 * @group HomeKit Data Streams (HDS)
56 */
57export declare const enum Topics {
58 HELLO = "hello",
59 WHOAMI = "whoami",
60 OPEN = "open",
61 DATA = "data",
62 ACK = "ack",
63 CLOSE = "close"
64}
65/**
66 * @group HomeKit Data Streams (HDS)
67 */
68export declare enum HDSStatus {
69 SUCCESS = 0,
70 OUT_OF_MEMORY = 1,
71 TIMEOUT = 2,
72 HEADER_ERROR = 3,
73 PAYLOAD_ERROR = 4,
74 MISSING_PROTOCOL = 5,
75 PROTOCOL_SPECIFIC_ERROR = 6
76}
77/**
78 * @group HomeKit Data Streams (HDS)
79 */
80export declare const enum HDSProtocolSpecificErrorReason {
81 NORMAL = 0,
82 NOT_ALLOWED = 1,
83 BUSY = 2,
84 CANCELLED = 3,
85 UNSUPPORTED = 4,
86 UNEXPECTED_FAILURE = 5,
87 TIMEOUT = 6,
88 BAD_DATA = 7,
89 PROTOCOL_ERROR = 8,
90 INVALID_CONFIGURATION = 9
91}
92/**
93 * An error indicating a protocol level HDS error.
94 * E.g. it may be used to encode a {@link HDSStatus.PROTOCOL_SPECIFIC_ERROR} in the {@link Protocols.DATA_SEND} protocol.
95 * @group HomeKit Data Streams (HDS)
96 */
97export declare class HDSProtocolError extends Error {
98 reason: HDSProtocolSpecificErrorReason;
99 /**
100 * Initializes a new `HDSProtocolError`
101 * @param reason - The {@link HDSProtocolSpecificErrorReason}.
102 * Values MUST NOT be {@link HDSProtocolSpecificErrorReason.NORMAL}.
103 */
104 constructor(reason: HDSProtocolSpecificErrorReason);
105}
106/**
107 * @group HomeKit Data Streams (HDS)
108 */
109export type HDSFrame = {
110 header: Buffer;
111 cipheredPayload: Buffer;
112 authTag: Buffer;
113 plaintextPayload?: Buffer;
114};
115/**
116 * @group HomeKit Data Streams (HDS)
117 */
118export declare const enum MessageType {
119 EVENT = 1,
120 REQUEST = 2,
121 RESPONSE = 3
122}
123/**
124 * @group HomeKit Data Streams (HDS)
125 */
126export type DataStreamMessage = {
127 type: MessageType;
128 protocol: string;
129 topic: string;
130 id?: number;
131 status?: HDSStatus;
132 message: Record<any, any>;
133};
134/**
135 * @group HomeKit Data Streams (HDS)
136 */
137export declare const enum DataStreamServerEvent {
138 /**
139 * This event is emitted when a new client socket is received. At this point we have no idea to what
140 * hap session this connection will be matched.
141 */
142 CONNECTION_OPENED = "connection-opened",
143 /**
144 * This event is emitted when the socket of a connection gets closed.
145 */
146 CONNECTION_CLOSED = "connection-closed"
147}
148/**
149 * @group HomeKit Data Streams (HDS)
150 */
151export declare interface DataStreamServer {
152 on(event: "connection-opened", listener: (connection: DataStreamConnection) => void): this;
153 on(event: "connection-closed", listener: (connection: DataStreamConnection) => void): this;
154 emit(event: "connection-opened", connection: DataStreamConnection): boolean;
155 emit(event: "connection-closed", connection: DataStreamConnection): boolean;
156}
157/**
158 * DataStreamServer which listens for incoming tcp connections and handles identification of new connections
159 * @group HomeKit Data Streams (HDS)
160 */
161export declare class DataStreamServer extends EventEmitter {
162 static readonly version = "1.0";
163 private state;
164 private static accessoryToControllerInfo;
165 private static controllerToAccessoryInfo;
166 private tcpServer?;
167 private tcpPort?;
168 preparedSessions: PreparedDataStreamSession[];
169 private readonly connections;
170 private removeListenersOnceClosed;
171 private readonly internalEventEmitter;
172 constructor();
173 /**
174 * Registers a new event handler to handle incoming event messages.
175 * The handler is only called for a connection if for the give protocol no ProtocolHandler
176 * was registered on the connection level.
177 *
178 * @param protocol - name of the protocol to register the handler for
179 * @param event - name of the event (also referred to as topic. See {@link Topics} for some known ones)
180 * @param handler - function to be called for every occurring event
181 */
182 onEventMessage(protocol: string | Protocols, event: string | Topics, handler: GlobalEventHandler): this;
183 /**
184 * Removes a registered event handler.
185 *
186 * @param protocol - name of the protocol to unregister the handler for
187 * @param event - name of the event (also referred to as topic. See {@link Topics} for some known ones)
188 * @param handler - registered event handler
189 */
190 removeEventHandler(protocol: string | Protocols, event: string | Topics, handler: GlobalEventHandler): this;
191 /**
192 * Registers a new request handler to handle incoming request messages.
193 * The handler is only called for a connection if for the give protocol no ProtocolHandler
194 * was registered on the connection level.
195 *
196 * @param protocol - name of the protocol to register the handler for
197 * @param request - name of the request (also referred to as topic. See {@link Topics} for some known ones)
198 * @param handler - function to be called for every occurring request
199 */
200 onRequestMessage(protocol: string | Protocols, request: string | Topics, handler: GlobalRequestHandler): this;
201 /**
202 * Removes a registered request handler.
203 *
204 * @param protocol - name of the protocol to unregister the handler for
205 * @param request - name of the request (also referred to as topic. See {@link Topics} for some known ones)
206 * @param handler - registered request handler
207 */
208 removeRequestHandler(protocol: string | Protocols, request: string | Topics, handler: GlobalRequestHandler): this;
209 prepareSession(connection: HAPConnection, controllerKeySalt: Buffer, callback: PrepareSessionCallback): void;
210 private timeoutPreparedSession;
211 private checkTCPServerEstablished;
212 private listening;
213 private onConnection;
214 private handleSessionIdentification;
215 private handleMessageGlobally;
216 private connectionClosed;
217 private checkCloseable;
218 /**
219 * This method will fully stop the DataStreamServer
220 */
221 destroy(): void;
222 private closed;
223}
224/**
225 * @group HomeKit Data Streams (HDS)
226 */
227export type IdentificationCallback = (identifiedSession?: PreparedDataStreamSession) => void;
228/**
229 * @group HomeKit Data Streams (HDS)
230 */
231export declare const enum DataStreamConnectionEvent {
232 /**
233 * This event is emitted when the first HDSFrame is received from a new connection.
234 * The connection expects the handler to identify the connection by trying to match the decryption keys.
235 * If identification was successful the PreparedDataStreamSession should be supplied to the callback,
236 * otherwise undefined should be supplied.
237 */
238 IDENTIFICATION = "identification",
239 /**
240 * This event is emitted when no handler could be found for the given protocol of an event or request message.
241 */
242 HANDLE_MESSAGE_GLOBALLY = "handle-message-globally",
243 /**
244 * This event is emitted when the socket of the connection was closed.
245 */
246 CLOSED = "closed"
247}
248/**
249 * @group HomeKit Data Streams (HDS)
250 */
251export declare interface DataStreamConnection {
252 on(event: "identification", listener: (frame: HDSFrame, callback: IdentificationCallback) => void): this;
253 on(event: "handle-message-globally", listener: (message: DataStreamMessage) => void): this;
254 on(event: "closed", listener: () => void): this;
255 emit(event: "identification", frame: HDSFrame, callback: IdentificationCallback): boolean;
256 emit(event: "handle-message-globally", message: DataStreamMessage): boolean;
257 emit(event: "closed"): boolean;
258}
259/**
260 * @group HomeKit Data Streams (HDS)
261 */
262export declare const enum HDSConnectionErrorType {
263 ILLEGAL_STATE = 1,
264 CLOSED_SOCKET = 2,
265 MAX_PAYLOAD_LENGTH = 3
266}
267/**
268 * @group HomeKit Data Streams (HDS)
269 */
270export declare class HDSConnectionError extends Error {
271 readonly type: HDSConnectionErrorType;
272 constructor(message: string, type: HDSConnectionErrorType);
273}
274/**
275 * DataStream connection which holds any necessary state information, encryption and decryption keys, manages
276 * protocol handlers and also handles sending and receiving of data stream frames.
277 *
278 * @group HomeKit Data Streams (HDS)
279 */
280export declare class DataStreamConnection extends EventEmitter {
281 private static readonly MAX_PAYLOAD_LENGTH;
282 private socket;
283 private connection?;
284 readonly remoteAddress: string;
285 private state;
286 private accessoryToControllerEncryptionKey?;
287 private controllerToAccessoryEncryptionKey?;
288 private accessoryToControllerNonce;
289 private readonly accessoryToControllerNonceBuffer;
290 private controllerToAccessoryNonce;
291 private readonly controllerToAccessoryNonceBuffer;
292 private frameBuffer?;
293 private readonly hapConnectionClosedListener;
294 private protocolHandlers;
295 private responseHandlers;
296 private responseTimers;
297 private helloTimer?;
298 constructor(socket: Socket);
299 private handleHello;
300 /**
301 * Registers a new protocol handler to handle incoming messages.
302 * The same protocol cannot be registered multiple times.
303 *
304 * @param protocol - name of the protocol to register the handler for
305 * @param protocolHandler - object to be registered as protocol handler
306 */
307 addProtocolHandler(protocol: string | Protocols, protocolHandler: DataStreamProtocolHandler): boolean;
308 /**
309 * Removes a protocol handler if it is registered.
310 *
311 * @param protocol - name of the protocol to unregister the handler for
312 * @param protocolHandler - object which will be unregistered
313 */
314 removeProtocolHandler(protocol: string | Protocols, protocolHandler: DataStreamProtocolHandler): void;
315 /**
316 * Sends a new event message to the connected client.
317 *
318 * @param protocol - name of the protocol
319 * @param event - name of the event (also referred to as topic. See {@link Topics} for some known ones)
320 * @param message - message dictionary which gets sent along the event
321 */
322 sendEvent(protocol: string | Protocols, event: string | Topics, message?: Record<any, any>): void;
323 /**
324 * Sends a new request message to the connected client.
325 *
326 * @param protocol - name of the protocol
327 * @param request - name of the request (also referred to as topic. See {@link Topics} for some known ones)
328 * @param message - message dictionary which gets sent along the request
329 * @param callback - handler which gets supplied with an error object if the response didn't
330 * arrive in time or the status and the message dictionary from the response
331 */
332 sendRequest(protocol: string | Protocols, request: string | Topics, message: Record<any, any> | undefined, callback: ResponseHandler): void;
333 /**
334 * Send a new response message to a received request message to the client.
335 *
336 * @param protocol - name of the protocol
337 * @param response - name of the response (also referred to as topic. See {@link Topics} for some known ones)
338 * @param id - id from the request, to associate the response to the request
339 * @param status - status indication if the request was successful. A status of zero indicates success.
340 * @param message - message dictionary which gets sent along the response
341 */
342 sendResponse(protocol: string | Protocols, response: string | Topics, id: number, status?: HDSStatus, message?: Record<any, any>): void;
343 private onSocketData;
344 private decodeHDSFrames;
345 /**
346 * @private file-private API
347 */
348 decryptHDSFrame(frame: HDSFrame, keyOverwrite?: Buffer): boolean;
349 private decodePayloads;
350 private sendHDSFrame;
351 close(): void;
352 isConsideredClosed(): boolean;
353 private onHAPSessionClosed;
354 private onSocketError;
355 private onSocketClose;
356}
357//# sourceMappingURL=DataStreamServer.d.ts.map
\No newline at end of file