|
1 | 1 | /* Serial PABotBase Message Protocol |
2 | | - * |
| 2 | + * |
3 | 3 | * From: https://github.com/PokemonAutomation/ |
4 | | - * |
5 | | - * |
| 4 | + * |
| 5 | + * |
6 | 6 | * Pokemon Automation Bot-Base implements reliable data transmissions over |
7 | 7 | * serial communication. This is done by checksumming messages along with a |
8 | 8 | * protocol that is tolerant to data drops. |
9 | | - * |
| 9 | + * |
10 | 10 | * This file describes the message protocol. The data being transmitted is raw |
11 | 11 | * binary and not is readable text. |
12 | | - * |
13 | | - * |
| 12 | + * |
| 13 | + * |
14 | 14 | * Message Format: |
15 | 15 | * byte 0: Length of the entire message. (bits are inverted) |
16 | 16 | * byte 1: Message Type |
17 | 17 | * byte X: Optional data of variable length. |
18 | 18 | * Last 4 bytes: CRC32C of the entire message except these last 4 bytes. |
19 | | - * |
| 19 | + * |
20 | 20 | * Thus there are 6 bytes of overhead for each message. |
21 | | - * |
22 | | - * |
| 21 | + * |
| 22 | + * |
23 | 23 | * There are currently 4 categories of message types: |
24 | | - * |
| 24 | + * |
25 | 25 | * 1. Info: These are simple one-way messages. They do not need to be |
26 | 26 | * acked and may be dropped without adversely affecting anything. |
27 | | - * |
| 27 | + * |
28 | 28 | * 2. Ack/Response: These are messages sent in response to an earlier |
29 | 29 | * message that was received. |
30 | | - * |
| 30 | + * |
31 | 31 | * 3. Request: The sender requests the receiver to do something simple. |
32 | 32 | * The receiver must respond with an ack. |
33 | | - * |
| 33 | + * |
34 | 34 | * This is used for things that take no clock time. For example, querying |
35 | 35 | * for program identifiers, turning on/off LEDs, or setting flags in the |
36 | 36 | * program to change its behavior in the future. |
37 | | - * |
| 37 | + * |
38 | 38 | * 4. Command: The sender requests the receiver to do a large asynchronous |
39 | 39 | * operation. The receiver must ack this message. Once the command is |
40 | 40 | * finished, the receiver must send a request message back to the sender |
41 | 41 | * to indicate that the command is finished. |
42 | | - * |
| 42 | + * |
43 | 43 | * This is used for issuing button presses or other subroutines that |
44 | 44 | * consume time. |
45 | | - * |
46 | | - * |
| 45 | + * |
| 46 | + * |
47 | 47 | * General Protocol: |
48 | | - * |
| 48 | + * |
49 | 49 | * 1. Every time you send a new request/command message, you increment |
50 | 50 | * your sequence number (seqnum) by 1. |
51 | | - * |
| 51 | + * |
52 | 52 | * 2. If you receive an invalid message (bad length or bad checksum), ignore |
53 | 53 | * the first byte and attempt to parse the next byte as the start of a |
54 | 54 | * new message. |
55 | | - * |
| 55 | + * |
56 | 56 | * 3. If you receive a zero for the 1st byte of a message, ignore it and |
57 | 57 | * attempt to parse the next byte as the start of a new message. |
58 | | - * |
| 58 | + * |
59 | 59 | * 4. At any point, you can send a bunch of zero bytes. This will cause |
60 | 60 | * the receiver to re-synchronize. |
61 | | - * |
| 61 | + * |
62 | 62 | * 5. If you receive a request/command message, you must send the appropriate |
63 | 63 | * ack/response message using the same seqnum. |
64 | | - * |
| 64 | + * |
65 | 65 | * 6. If you receive a command message, you must first ack the message itself. |
66 | 66 | * Once the command is finished, you must send a request referencing the |
67 | 67 | * command to indicate that it is finished. You will receive an ack for |
68 | 68 | * this short (finishing) command, and if you don't, send it again until |
69 | 69 | * you do. If the command finishes immediately, you can skip the ack and |
70 | 70 | * just send the finish request. |
71 | | - * |
| 71 | + * |
72 | 72 | * 7. If you send a request/command message and don't get a response after |
73 | 73 | * a time limit, you should resend the message with the same seqnum. |
74 | | - * |
| 74 | + * |
75 | 75 | * 8. If you receive a request/command that has a seqnum ahead of what you |
76 | 76 | * are expecting, it means an earlier request/command was dropped. |
77 | 77 | * Do not process the request/command since you will lose ordering. |
78 | | - * |
| 78 | + * |
79 | 79 | * 9. If you receive a request/command that has an old seqnum, it is a |
80 | 80 | * retransmit. Send an ack for it, but don't process it again. (idempotency) |
81 | | - * |
82 | | - * |
| 81 | + * |
| 82 | + * |
83 | 83 | * Failure Analysis: |
84 | | - * |
| 84 | + * |
85 | 85 | * - Corrupted messages will either fail checksum or will have an invalid |
86 | 86 | * length/type. These are simply ignored and dropped. |
87 | | - * |
| 87 | + * |
88 | 88 | * - If either sender or receiver gets out-of-sync and loses track of |
89 | 89 | * message boundaries, it will eventually find the boundary again by |
90 | 90 | * simply trying to parse every byte as the start of a new message and |
91 | 91 | * verifying the length and CRC. |
92 | | - * |
| 92 | + * |
93 | 93 | * - If a request/command is dropped, no ack will be received. The sender |
94 | 94 | * will eventually send the command again. (#7) |
95 | | - * |
| 95 | + * |
96 | 96 | * - If an ack is dropped, the sender will eventually resend the |
97 | 97 | * request/command again. The receiver will see the duplicate |
98 | 98 | * request/command and ack it. But the receiver will not process it |
99 | 99 | * again to preserve idempotency. (#9) |
100 | | - * |
| 100 | + * |
101 | 101 | * The current protocol guarantees that all commands are processed in order |
102 | 102 | * exactly once. Requests are not guaranteed to process in order and may execute |
103 | 103 | * more than once so they should be idempotent. |
104 | | - * |
| 104 | + * |
105 | 105 | * The protocol also allows both sides to queue up requests and commands. |
106 | 106 | * In other words, it is possible to send multiple requests/commands at once |
107 | 107 | * without waiting for the individual acks. |
108 | | - * |
109 | | - * |
| 108 | + * |
| 109 | + * |
110 | 110 | * PABotBase Specifics: |
111 | | - * |
| 111 | + * |
112 | 112 | * - PABotBase can queue up to 4 commands. If it receives any commands |
113 | 113 | * while the queue is full, it drops it and responds with |
114 | 114 | * "PABB_MSG_ERROR_COMMAND_DROPPED". (Any command that results in a |
115 | 115 | * button press or a wait is a long command.) |
116 | | - * |
| 116 | + * |
117 | 117 | * - PABotBase can still handle other messages while it is running a long |
118 | 118 | * command. |
119 | | - * |
| 119 | + * |
120 | 120 | */ |
121 | 121 |
|
122 | 122 | #ifndef PokemonAutomation_SerialPABotBase_Protocol_H |
@@ -199,6 +199,11 @@ typedef struct{ |
199 | 199 | uint16_t error_code; |
200 | 200 | } PABB_PACK pabb_MsgInfoWARNING; |
201 | 201 |
|
| 202 | +#define PABB_MSG_ERROR_DISCONNECTED 0x08 |
| 203 | +typedef struct{ |
| 204 | + uint16_t error_code; |
| 205 | +} PABB_PACK pabb_MsgInfoDisconnected; |
| 206 | + |
202 | 207 | //////////////////////////////////////////////////////////////////////////////// |
203 | 208 | // Ack |
204 | 209 | #define PABB_MSG_ACK_COMMAND 0x10 |
@@ -308,10 +313,12 @@ typedef struct{ |
308 | 313 | //////////////////////////////////////////////////////////////////////////////// |
309 | 314 | // Commands |
310 | 315 |
|
| 316 | +#if 0 |
311 | 317 | #define PABB_MSG_COMMAND_END_PROGRAM_CALLBACK 0x80 |
312 | 318 | typedef struct{ |
313 | 319 | seqnum_t seqnum; |
314 | 320 | } PABB_PACK pabb_end_program_callback; |
| 321 | +#endif |
315 | 322 |
|
316 | 323 | #define PABB_MSG_COMMAND_SET_LED_STATE 0x81 |
317 | 324 | typedef struct{ |
|
0 commit comments