UNPKG

13.5 kBTypeScriptView Raw
1import { EventEmitter } from "events";
2import { AccessoriesResponse, CharacteristicsReadRequest, CharacteristicsReadResponse, CharacteristicsWriteRequest, CharacteristicsWriteResponse, CharacteristicValue, Nullable, ResourceRequest, VoidCallback } from "../types";
3import { AccessoryInfo, PairingInformation, PermissionTypes } from "./model/AccessoryInfo";
4import { HAPConnection, HAPUsername } from "./util/eventedhttp";
5/**
6 * TLV error codes for the `TLVValues.ERROR_CODE` field.
7 *
8 * @group HAP Accessory Server
9 */
10export declare const enum TLVErrorCode {
11 UNKNOWN = 1,
12 INVALID_REQUEST = 2,
13 AUTHENTICATION = 2,// setup code or signature verification failed
14 BACKOFF = 3,// // client must look at retry delay tlv item
15 MAX_PEERS = 4,// server cannot accept any more pairings
16 MAX_TRIES = 5,// server reached maximum number of authentication attempts
17 UNAVAILABLE = 6,// server pairing method is unavailable
18 BUSY = 7
19}
20/**
21 * @group HAP Accessory Server
22 */
23export declare const enum HAPStatus {
24 /**
25 * Success of the request.
26 */
27 SUCCESS = 0,
28 /**
29 * The request was rejected due to insufficient privileges.
30 */
31 INSUFFICIENT_PRIVILEGES = -70401,
32 /**
33 * Operation failed due to some communication failure with the characteristic.
34 */
35 SERVICE_COMMUNICATION_FAILURE = -70402,
36 /**
37 * The resource is busy. Try again.
38 */
39 RESOURCE_BUSY = -70403,
40 /**
41 * Cannot write a read-only characteristic ({@link Perms.PAIRED_WRITE} not defined).
42 */
43 READ_ONLY_CHARACTERISTIC = -70404,
44 /**
45 * Cannot read from a write-only characteristic ({@link Perms.PAIRED_READ} not defined).
46 */
47 WRITE_ONLY_CHARACTERISTIC = -70405,
48 /**
49 * Event notifications are not supported for the requested characteristic ({@link Perms.NOTIFY} not defined).
50 */
51 NOTIFICATION_NOT_SUPPORTED = -70406,
52 /**
53 * The device is out of resources to process the request.
54 */
55 OUT_OF_RESOURCE = -70407,
56 /**
57 * The operation timed out.
58 */
59 OPERATION_TIMED_OUT = -70408,
60 /**
61 * The given resource does not exist.
62 */
63 RESOURCE_DOES_NOT_EXIST = -70409,
64 /**
65 * Received an invalid value in the given request for the given characteristic.
66 */
67 INVALID_VALUE_IN_REQUEST = -70410,
68 /**
69 * Insufficient authorization.
70 */
71 INSUFFICIENT_AUTHORIZATION = -70411,
72 /**
73 * Operation not allowed in the current state.
74 */
75 NOT_ALLOWED_IN_CURRENT_STATE = -70412
76}
77/**
78 * Determines if the given status code is a known {@link HAPStatus} error code.
79 *
80 * @group HAP Accessory Server
81 */
82export declare function IsKnownHAPStatusError(status: HAPStatus): boolean;
83/**
84 * Those status codes are the one listed as appropriate for the HAP spec!
85 *
86 * When the response is a client error 4xx or server error 5xx, the response
87 * must include a status {@link HAPStatus} property.
88 *
89 * When the response is a MULTI_STATUS EVERY entry in the characteristics property MUST include a status property (even success).
90 *
91 * @group HAP Accessory Server
92 */
93export declare const enum HAPHTTPCode {
94 OK = 200,
95 NO_CONTENT = 204,
96 MULTI_STATUS = 207,
97 BAD_REQUEST = 400,// e.g. malformed request
98 NOT_FOUND = 404,
99 UNPROCESSABLE_ENTITY = 422,// for well-formed requests tha contain invalid http parameters (semantics are wrong and not syntax)
100 INTERNAL_SERVER_ERROR = 500,
101 SERVICE_UNAVAILABLE = 503
102}
103/**
104 * When in a request is made to the pairing endpoints, and mime type is 'application/pairing+tlv8'
105 * one should use the below status codes.
106 *
107 * @group HAP Accessory Server
108 */
109export declare const enum HAPPairingHTTPCode {
110 OK = 200,
111 BAD_REQUEST = 400,// e.g. bad tlv, state errors, etc
112 METHOD_NOT_ALLOWED = 405,
113 TOO_MANY_REQUESTS = 429,// e.g. attempt to pair while already pairing
114 CONNECTION_AUTHORIZATION_REQUIRED = 470,// didn't do pair-verify step
115 INTERNAL_SERVER_ERROR = 500
116}
117/**
118 * @group HAP Accessory Server
119 */
120export type IdentifyCallback = VoidCallback;
121/**
122 * @group HAP Accessory Server
123 */
124export type HAPHttpError = {
125 httpCode: HAPHTTPCode;
126 status: HAPStatus;
127};
128/**
129 * @group HAP Accessory Server
130 */
131export type PairingsCallback<T = void> = (error: TLVErrorCode | 0, data?: T) => void;
132/**
133 * @group HAP Accessory Server
134 */
135export type AddPairingCallback = PairingsCallback;
136/**
137 * @group HAP Accessory Server
138 */
139export type RemovePairingCallback = PairingsCallback;
140/**
141 * @group HAP Accessory Server
142 */
143export type ListPairingsCallback = PairingsCallback<PairingInformation[]>;
144/**
145 * @group HAP Accessory Server
146 */
147export type PairCallback = VoidCallback;
148/**
149 * @group HAP Accessory Server
150 */
151export type AccessoriesCallback = (error: HAPHttpError | undefined, result?: AccessoriesResponse) => void;
152/**
153 * @group HAP Accessory Server
154 */
155export type ReadCharacteristicsCallback = (error: HAPHttpError | undefined, response?: CharacteristicsReadResponse) => void;
156/**
157 * @group HAP Accessory Server
158 */
159export type WriteCharacteristicsCallback = (error: HAPHttpError | undefined, response?: CharacteristicsWriteResponse) => void;
160/**
161 * @group HAP Accessory Server
162 */
163export type ResourceRequestCallback = (error: HAPHttpError | undefined, resource?: Buffer) => void;
164/**
165 * @group HAP Accessory Server
166 */
167export declare const enum HAPServerEventTypes {
168 /**
169 * Emitted when the server is fully set up and ready to receive connections.
170 */
171 LISTENING = "listening",
172 /**
173 * Emitted when a client wishes for this server to identify itself before pairing. You must call the
174 * callback to respond to the client with success.
175 */
176 IDENTIFY = "identify",
177 ADD_PAIRING = "add-pairing",
178 REMOVE_PAIRING = "remove-pairing",
179 LIST_PAIRINGS = "list-pairings",
180 /**
181 * This event is emitted when a client completes the "pairing" process and exchanges encryption keys.
182 * Note that this does not mean the "Add Accessory" process in iOS has completed.
183 * You must call the callback to complete the process.
184 */
185 PAIR = "pair",
186 /**
187 * This event is emitted when a client requests the complete representation of Accessory data for
188 * this Accessory (for instance, what services, characteristics, etc. are supported) and any bridged
189 * Accessories in the case of a Bridge Accessory. The listener must call the provided callback function
190 * when the accessory data is ready. We will automatically JSON.stringify the data.
191 */
192 ACCESSORIES = "accessories",
193 /**
194 * This event is emitted when a client wishes to retrieve the current value of one or more characteristics.
195 * The listener must call the provided callback function when the values are ready. iOS clients can typically
196 * wait up to 10 seconds for this call to return. We will automatically JSON.stringify the data (which must
197 * be an array) and wrap it in an object with a top-level "characteristics" property.
198 */
199 GET_CHARACTERISTICS = "get-characteristics",
200 /**
201 * This event is emitted when a client wishes to set the current value of one or more characteristics and/or
202 * subscribe to one or more events. The 'events' param is an initially-empty object, associated with the current
203 * connection, on which you may store event registration keys for later processing. The listener must call
204 * the provided callback when the request has been processed.
205 */
206 SET_CHARACTERISTICS = "set-characteristics",
207 REQUEST_RESOURCE = "request-resource",
208 CONNECTION_CLOSED = "connection-closed"
209}
210/**
211 * @group HAP Accessory Server
212 */
213export declare interface HAPServer {
214 on(event: "listening", listener: (port: number, address: string) => void): this;
215 on(event: "identify", listener: (callback: IdentifyCallback) => void): this;
216 on(event: "add-pairing", listener: (connection: HAPConnection, username: HAPUsername, publicKey: Buffer, permission: PermissionTypes, callback: AddPairingCallback) => void): this;
217 on(event: "remove-pairing", listener: (connection: HAPConnection, username: HAPUsername, callback: RemovePairingCallback) => void): this;
218 on(event: "list-pairings", listener: (connection: HAPConnection, callback: ListPairingsCallback) => void): this;
219 on(event: "pair", listener: (username: HAPUsername, clientLTPK: Buffer, callback: PairCallback) => void): this;
220 on(event: "accessories", listener: (connection: HAPConnection, callback: AccessoriesCallback) => void): this;
221 on(event: "get-characteristics", listener: (connection: HAPConnection, request: CharacteristicsReadRequest, callback: ReadCharacteristicsCallback) => void): this;
222 on(event: "set-characteristics", listener: (connection: HAPConnection, request: CharacteristicsWriteRequest, callback: WriteCharacteristicsCallback) => void): this;
223 on(event: "request-resource", listener: (resource: ResourceRequest, callback: ResourceRequestCallback) => void): this;
224 on(event: "connection-closed", listener: (connection: HAPConnection) => void): this;
225 emit(event: "listening", port: number, address: string): boolean;
226 emit(event: "identify", callback: IdentifyCallback): boolean;
227 emit(event: "add-pairing", connection: HAPConnection, username: HAPUsername, publicKey: Buffer, permission: PermissionTypes, callback: AddPairingCallback): boolean;
228 emit(event: "remove-pairing", connection: HAPConnection, username: HAPUsername, callback: RemovePairingCallback): boolean;
229 emit(event: "list-pairings", connection: HAPConnection, callback: ListPairingsCallback): boolean;
230 emit(event: "pair", username: HAPUsername, clientLTPK: Buffer, callback: PairCallback): boolean;
231 emit(event: "accessories", connection: HAPConnection, callback: AccessoriesCallback): boolean;
232 emit(event: "get-characteristics", connection: HAPConnection, request: CharacteristicsReadRequest, callback: ReadCharacteristicsCallback): boolean;
233 emit(event: "set-characteristics", connection: HAPConnection, request: CharacteristicsWriteRequest, callback: WriteCharacteristicsCallback): boolean;
234 emit(event: "request-resource", resource: ResourceRequest, callback: ResourceRequestCallback): boolean;
235 emit(event: "connection-closed", connection: HAPConnection): boolean;
236}
237/**
238 * The actual HAP server that iOS devices talk to.
239 *
240 * Notes
241 * -----
242 * It turns out that the IP-based version of HomeKit's HAP protocol operates over a sort of pseudo-HTTP.
243 * Accessories are meant to host a TCP socket server that initially behaves exactly as an HTTP/1.1 server.
244 * So iOS devices will open up a long-lived connection to this server and begin issuing HTTP requests.
245 * So far, this conforms with HTTP/1.1 Keepalive. However, after the "pairing" process is complete, the
246 * connection is expected to be "upgraded" to support full-packet encryption of both HTTP headers and data.
247 * This encryption is NOT SSL. It is a customized ChaCha20+Poly1305 encryption layer.
248 *
249 * Additionally, this "HTTP Server" supports sending "event" responses at any time without warning. The iOS
250 * device simply keeps the connection open after it's finished with HTTP request/response traffic, and while
251 * the connection is open, the server can elect to issue "EVENT/1.0 200 OK" HTTP-style responses. These are
252 * typically sent to inform the iOS device of a characteristic change for the accessory (like "Door was Unlocked").
253 *
254 * See {@link EventedHTTPServer} for more detail on the implementation of this protocol.
255 *
256 * @group HAP Accessory Server
257 */
258export declare class HAPServer extends EventEmitter {
259 private accessoryInfo;
260 private httpServer;
261 private unsuccessfulPairAttempts;
262 allowInsecureRequest: boolean;
263 constructor(accessoryInfo: AccessoryInfo);
264 listen(port?: number, host?: string): void;
265 stop(): void;
266 destroy(): void;
267 /**
268 * Send an even notification for given characteristic and changed value to all connected clients.
269 * If `originator` is specified, the given {@link HAPConnection} will be excluded from the broadcast.
270 *
271 * @param aid - The accessory id of the updated characteristic.
272 * @param iid - The instance id of the updated characteristic.
273 * @param value - The newly set value of the characteristic.
274 * @param originator - If specified, the connection will not get an event message.
275 * @param immediateDelivery - The HAP spec requires some characteristics to be delivery immediately.
276 * Namely, for the {@link Characteristic.ButtonEvent} and the {@link Characteristic.ProgrammableSwitchEvent} characteristics.
277 */
278 sendEventNotifications(aid: number, iid: number, value: Nullable<CharacteristicValue>, originator?: HAPConnection, immediateDelivery?: boolean): void;
279 private onListening;
280 private handleRequestOnHAPConnection;
281 private handleConnectionClosed;
282 private getHandler;
283 /**
284 * UNPAIRED Accessory identification.
285 */
286 private handleIdentifyRequest;
287 private handlePairSetup;
288 private handlePairSetupM1;
289 private handlePairSetupM3;
290 private handlePairSetupM5;
291 private handlePairSetupM5_2;
292 private handlePairSetupM5_3;
293 private handlePairVerify;
294 private handlePairVerifyM1;
295 private handlePairVerifyM3;
296 private handlePairings;
297 private handleAccessories;
298 private handleCharacteristics;
299 private handlePrepareWrite;
300 private handleResource;
301}
302//# sourceMappingURL=HAPServer.d.ts.map
\No newline at end of file