-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathHomewayProtocol.fbs
More file actions
228 lines (167 loc) · 8.16 KB
/
HomewayProtocol.fbs
File metadata and controls
228 lines (167 loc) · 8.16 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
// The namepspace must start the same as our python package. That's because
// we bundle the output directly with the package. Some of the classes (like WebStreamMgs)
// reference the namespace in the generated logic, and it will break if it doesn't match.
namespace homeway.Proto;
//
// Enums
//
// Indicates what type of compression is used for the data, if any.
enum DataCompression:byte { None = 0, Brotli=1, Zlib=2, ZStandard=3 }
// Possible types of paths.
enum PathTypes:byte { None=0, Relative=1, Absolute=2 }
// Possible values of the web socket data type.
// The ordering is weird to match the websocket standard.
enum WebSocketDataTypes:byte { Text=1, Binary=2, Close=8, None=126}
// Possible message priority types.
enum MessagePriority:byte { Critical=1, High=5, Normal=10, Low=15, Background=20 }
// Defines which type of summon was requested. Used for telemetry on the server.
enum SummonMethods:byte { Unknown=1, FastPath=2, Broadcast=3 }
// Defines a special type of call that will be directed to the Home Assistant APIs directly.
enum HaApiTarget:byte { None=1, Core=2, Supervisor=3 }
// Defines different types of plugins, like one running as a HA container addon or running standalone.
enum AddonTypes:byte { Unknown=1, HaAddon=2, StandaloneCli=3, StandaloneDocker=4 }
//
// Helper Tables
//
// Represents a http header.
table HttpHeader {
key:string;
value:string;
}
// Represents context for http calls that only needs to be sent on the initial request.
table HttpInitialContext {
// The url path of the request - or - an absolute URL.
path:string;
// Indicates is the http path is either relative or absolute .
path_type:PathTypes = Relative;
// The http request method. Required for the first request message.
method:string;
// The hostname where the request came from.
host:string;
// Optional - Any http headers in the request.
headers:[HttpHeader];
// If set, this call is direct to the HA APIs, rather than to the normal http root.
api_target:HaApiTarget = None;
// Optional - The IP address the request was originally from.
forwarded_for_ip:string;
}
//
// Message Context Tables
//
// A message that represents an initial handshake message from the plugin to the service.
table HandshakeSyn {
// The unique ID of the plugin trying to connect.
plugin_id:string;
// Indicates if the plugin is just visiting this server because it has been summoned.
// This happens when a shared connection hits a server the plugin isn't connected to,
// for a short period of time the plugin will dual connect to two servers.
is_primary_connection:bool;
// The version of the plugin. Matches the github release version.
plugin_version:string;
// If known, this is the local device IP of the device.
// This is passed to apps so they can more easily discover the plugin during setup.
local_device_ip:string;
// If known, this is the port the local http proxy is running on.
local_http_proxy_port:uint;
// A not secrete but harder to know key to ensure the id identity.
key:string;
// A RSA challenge that will allow the client to validate it's talking to an authentic server.
// This is a random string generated by the client and encrypted with the public key.
rsa_challenge:[uint8];
// The key version this client is using and is expecting to use for decryption.
ras_challenge_version:byte;
// A private key associated to this plugin id. Once it's set by plugin, it must be supplied on all connections to allow the
// connection. This prevents incorrect clients from trying to connect as this instance.
private_key:string;
// Optional - If the connection is due to a summon, this indicates which type.
summon_method:SummonMethods = Unknown;
// Specifies the type of addon
addon_type:AddonTypes = Unknown;
// Specifies which type of compression the client wants for receiving data (other than None). Note that the client can send different types per stream.
// This defaults to zlib, because all clients must support at least zlib. But ideally they use zstandard if they can.
receive_compression_type:DataCompression = Zlib;
}
// A message that's sent in response to the handshake sync. The connection isn't established until this handshake is complete.
table HandshakeAck {
// Indicates if this client was accepted or not.
accepted:bool;
// If accepted, a list of accounts connected to this plugin.
connected_accounts:[string];
// If not accepted, this error indicates why.
error:string;
// If not accepted, this can optionally indicate how long the client should back off before
// trying to connect again.
backoff_seconds:ulong;
// If not accepted, this indicates if the plugin must be updated.
requires_plugin_update:bool;
// The active Api key
api_key:string;
// The returned decrypted RSA challenge phrase. The decryption is done with the server's private key that only Homeway services know.
rsa_challenge_result:string;
}
// A message that is sent to clients when they are trying to be summoned by another server.
// The summon system allows the plugin to be shared with user all around the world fast and seamless.
table Summon {
// The absolute URL of the server that's requesting a connection.
server_connect_url:string;
// Indicates which summon type was used, so the connecting server can know.
summon_method:SummonMethods = Unknown;
}
// The core message used to stream bi-directionally stream data. This stream system is used for
// http calls, long http calls (webcam streams), and websockets.
table WebStreamMsg {
// Indicates the stream this data is in reference to.
// All values are valid, except 0.
stream_id:uint = 0;
// These flags indicate state updates.
// The is open msg should only be set on the first request to the client.
// The is close flag indicates the stream should be shutdown. This can be sent by either side and once set both sides should not send any more messages.
// This is data transmission done flag indicates if all of the data has been sent from the flow direction and no more will be sent.
// The is control flags only flag indicates if there's more data in the message, or if it's just control flags.
is_open_msg:bool = false;
is_close_msg:bool = false;
is_data_transmission_done:bool = false;
is_control_flags_only:bool = true;
// Optional - If set, this value is the full size of the data that will be sent for this stream.
// Any value < 0 means unset.
full_stream_data_size:long = -1;
// The message data.
data:[uint8];
// Indicates what type of compression is used
data_compression:DataCompression = None;
// Required if using compression - how large the uncompressed data is.
original_data_size:ulong = 0;
// Required for the first message of a stream to send the http context.
http_initial_context:HttpInitialContext;
// Required for the first message, indicates if the stream is a websocket or http stream
is_websocket_stream:bool = false;
// Optional - The http status code. Required for the first response message.
status_code:uint16;
// Required for websocket data messages, indicates the type of data.
websocket_data_type:WebSocketDataTypes = None;
// Optional - If the message priority is defined, it might be considered when processing messages.
// This is mostly used to make sure that important page elements that the user sees first load the fastest.
msg_priority:MessagePriority = Normal;
// If set, this indicates that the request failed due to a connection failure from the plugin to the requested URL.
// This allows us to differentiate between connection errors and plugin errors.
close_due_to_request_connection_failure:bool = false;
// Perf metrics that are optionally added.
// These are intended to be sent by the plugin, right now they are only send for multipart streams.
body_read_time_high_water_mark_ms:uint16 = 0;
socket_send_time_high_water_mark_ms:uint16 = 0;
multipart_reads_per_second:uint8 = 0;
}
// Holds all possible types of messages.
union MessageContext
{
HandshakeSyn,
HandshakeAck,
WebStreamMsg,
Summon
}
// The main, root message
table StreamMessage {
// The message context holds the main dynamic body of the message.
context:MessageContext;
}
root_type StreamMessage;