-
Notifications
You must be signed in to change notification settings - Fork 1
/
PROTOCOL
140 lines (87 loc) · 4.92 KB
/
PROTOCOL
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
= Fluid Nexus Protocol =
== VERSION 1 ==
* 2 byte version
** For Version 1, this is 01
* 3 byte length of title
* 6 byte length of message
* 13 byte timestamp
* 32 byte md5 hash of title and message
* title
* message
== VERSON 2 ==
Since on Android we cannot get the user-defined service names from the API, we cannot use service advertisement and stigmergy to figure out which hashes to send. This was probably not scalable anyway. So we have to develop a protocol for discovering which hashes the other device has to determine which ones to request.
On Android it's also problematic for devices to be discoverable for any reasonable length of time. Additionally, it seems RFCOMM can only happen for paired devices. Thus, after the initial establishment of a connection and the pulling of hashes from the server, the client can switch roles and become a "server" for the other device.
=== Commands ===
TODO: add some errors
TODO: add type, mime-type, filename, and content length for binary data
0x10 HELO
0x20 Hash list
0x21 Hash list continuation
0x30 Hash request
0x40 Switch
0x41 Switch done
0xF0 Done
0xF1 Done; no more hashes to send
=== 0x10: HELO ===
The client sends this command to the server with a 2-byte hex value for the version (currently 0x02), which the server return to the client with no arguments, in order to estable the connection.
=== 0x20: Hash list ===
To determine which hashes the server has, the client sends this command to the server with no arguments. The server responds with data of the following format:
0xX 32 bytes
number of hashes hashes, multipled by the number being sent
(limited to 16
at a time)
=== 0x21: Hash list continuation ===
After receiving a set of hashes and (optionally) requesting data for a subset of them, the client may wish to get more hashes from the server. This command is sent with an argument "offset" of the following:
0xXXXX
hex offset that determines where in the sequence of hashes the server should start in its transmission. The server responds using the same format as with command 0x20. If there are no other hashes to be sent, the server responds with the command 0xF1.
=== 0x30: Hash request ===
The client sends this command to the server with a a 32-byte argument of the hash it wants to receive. The server responds in the manner as described in the ver1 protocol, with the following exceptions:
* the "version" field is now 0x02.
* "length" of title and "length" of message are now 3 byte and 6 byte _hex_ values respectively, sent as character strings.
=== 0x40: Switch ===
Command to let the server know that it should switch into a "client" mode, allowing it to send commands such as 0x20 to discover hashes from the former client.
=== 0xF0: Done ===
If at any point the client wishes to end the session it can send this command. The server responds in kind.
=== 0xF1: Done ===
If the server hash no more hashes to send, it responds with this command.
== VERSION 3 ==
We use Google's protocol buffers for data serialization. This should allow us to easily deal with optional values, binary data, and so on. Here's a potential outline of the commands and the protocol.
In all cases "size" is a four byte unsigned int.
The basic scheme of the protocol is as follows:
1. Client sends HELO to server, receives HELO from server in response.
2. Client sends its own list of hashes to server.
3. Server finds local hashes that are not in the list of hashes the client sent.
4. Server sends data of local hashes the client doesn't have.
Once this is done, the client can optionally send another command SWITCH that switches the direction of the protocol. Thus, after a SWITCH, the client expects to receive a list of hashes, and then sends new data back to the server.
In terms of how this plays out in terms of reading and writing:
Command Client Server
HELO Write Read
HELO Read Write
HASHES Write Read
MESSAGES Read Write
SWITCH Write Read
HASHES Read Write
MESSAGES Write Read
SWITCH Read Write
DONE Write Read
DONE Read Write
=== Commands ===
=== 0x10: HELO ===
unsigned char command
Send this command to initiate connection; the client expects to receive the same command in response.
=== 0x20: HASHES ===
unsigned char command
unsigned int size
void data
Using our protobuf "FluidNexusHashes", send our list of hashes.
=== 0x30: MESSAGES ===
unsigned char command
unsigned int size
void data
Using our protobuf "FluidNexusMessages", send our batch of data (that has already been pared down by exchanging hashes and determining which ones the other side doesn't have).
=== 0x80: SWITCH ===
unsigned char command
Command to switch from one mode to the other.
=== 0xF0: DONE ===
unsigned char command
Command to end the connection.