11/* Serial PABotBase Message Protocol
2- *
2+ *
33 * From: https://github.com/PokemonAutomation/
44 *
55 *
66 * Pokemon Automation Bot-Base implements reliable data transmissions over
77 * serial communication. This is done by checksumming messages along with a
88 * protocol that is tolerant to data drops.
9- *
9+ *
1010 * This file describes the message protocol. The data being transmitted is raw
1111 * binary and not is readable text.
12- *
13- *
12+ *
13+ *
1414 * Message Format:
1515 * byte 0: Length of the entire message. (bits are inverted)
1616 * byte 1: Message Type
1717 * byte X: Optional data of variable length.
1818 * Last 4 bytes: CRC32C of the entire message except these last 4 bytes.
19- *
19+ *
2020 * Thus there are 6 bytes of overhead for each message.
21- *
22- *
21+ *
22+ *
2323 * There are currently 4 categories of message types:
24- *
24+ *
2525 * 1. Info: These are simple one-way messages. They do not need to be
2626 * acked and may be dropped without adversely affecting anything.
27- *
27+ *
2828 * 2. Ack/Response: These are messages sent in response to an earlier
2929 * message that was received.
30- *
30+ *
3131 * 3. Request: The sender requests the receiver to do something simple.
3232 * The receiver must respond with an ack.
33- *
33+ *
3434 * This is used for things that take no clock time. For example, querying
3535 * for program identifiers, turning on/off LEDs, or setting flags in the
3636 * program to change its behavior in the future.
37- *
37+ *
3838 * 4. Command: The sender requests the receiver to do a large asynchronous
3939 * operation. The receiver must ack this message. Once the command is
4040 * finished, the receiver must send a request message back to the sender
4141 * to indicate that the command is finished.
42- *
42+ *
4343 * This is used for issuing button presses or other subroutines that
4444 * consume time.
45- *
46- *
45+ *
46+ *
4747 * General Protocol:
48- *
48+ *
4949 * 1. Every time you send a new request/command message, you increment
5050 * your sequence number (seqnum) by 1.
51- *
51+ *
5252 * 2. If you receive an invalid message (bad length or bad checksum), ignore
5353 * the first byte and attempt to parse the next byte as the start of a
5454 * new message.
55- *
55+ *
5656 * 3. If you receive a zero for the 1st byte of a message, ignore it and
5757 * attempt to parse the next byte as the start of a new message.
58- *
58+ *
5959 * 4. At any point, you can send a bunch of zero bytes. This will cause
6060 * the receiver to re-synchronize.
61- *
61+ *
6262 * 5. If you receive a request/command message, you must send the appropriate
6363 * ack/response message using the same seqnum.
64- *
64+ *
6565 * 6. If you receive a command message, you must first ack the message itself.
6666 * Once the command is finished, you must send a request referencing the
6767 * command to indicate that it is finished. You will receive an ack for
6868 * this short (finishing) command, and if you don't, send it again until
6969 * you do. If the command finishes immediately, you can skip the ack and
7070 * just send the finish request.
71- *
71+ *
7272 * 7. If you send a request/command message and don't get a response after
7373 * a time limit, you should resend the message with the same seqnum.
74- *
74+ *
7575 * 8. If you receive a request/command that has a seqnum ahead of what you
7676 * are expecting, it means an earlier request/command was dropped.
7777 * Do not process the request/command since you will lose ordering.
78- *
78+ *
7979 * 9. If you receive a request/command that has an old seqnum, it is a
8080 * retransmit. Send an ack for it, but don't process it again. (idempotency)
81- *
82- *
81+ *
82+ *
8383 * Failure Analysis:
84- *
84+ *
8585 * - Corrupted messages will either fail checksum or will have an invalid
8686 * length/type. These are simply ignored and dropped.
87- *
87+ *
8888 * - If either sender or receiver gets out-of-sync and loses track of
8989 * message boundaries, it will eventually find the boundary again by
9090 * simply trying to parse every byte as the start of a new message and
9191 * verifying the length and CRC.
92- *
92+ *
9393 * - If a request/command is dropped, no ack will be received. The sender
9494 * will eventually send the command again. (#7)
95- *
95+ *
9696 * - If an ack is dropped, the sender will eventually resend the
9797 * request/command again. The receiver will see the duplicate
9898 * request/command and ack it. But the receiver will not process it
9999 * again to preserve idempotency. (#9)
100- *
100+ *
101101 * The current protocol guarantees that all commands are processed in order
102102 * exactly once. Requests are not guaranteed to process in order and may execute
103103 * more than once so they should be idempotent.
104- *
104+ *
105105 * The protocol also allows both sides to queue up requests and commands.
106106 * In other words, it is possible to send multiple requests/commands at once
107107 * without waiting for the individual acks.
108- *
109- *
108+ *
109+ *
110110 * PABotBase Specifics:
111111 *
112- * - PABotBase can queue up to 4 commands. If it receives any commands
113- * while the queue is full, it drops it and responds with
114- * "PABB_MSG_ERROR_COMMAND_DROPPED". (Any command that results in a
115- * button press or a wait is a long command.)
116- *
112+ * - PABotBase can queue 4 commands. Some implementations can handle
113+ * more. If it receives any commands while the queue is full, it drops
114+ * it and responds with "PABB_MSG_ERROR_COMMAND_DROPPED".
115+ * (Any command that results in a button press or a wait is a long command.)
116+ *
117117 * - PABotBase can still handle other messages while it is running a long
118118 * command.
119- *
119+ *
120120 */
121121
122122#ifndef PokemonAutomation_SerialPABotBase_Protocol_H
125125#include <stdbool.h>
126126#include <stdint.h>
127127
128- #ifdef __cplusplus
129- extern "C" {
130- #endif
131-
132128#if _WIN32
133129#pragma pack(push, 1)
134130#define PABB_PACK
135- #else
131+ #elif __GNUC__
136132#define PABB_PACK __attribute__((packed))
133+ #else
134+ #define PABB_PACK
135+ #endif
136+
137+ #ifdef __cplusplus
138+ extern "C" {
137139#endif
138140
139141////////////////////////////////////////////////////////////////////////////////
@@ -246,7 +248,6 @@ typedef struct{
246248typedef struct {
247249 uint8_t tag ;
248250 uint32_t data ;
249- #define PABB_MSG_INFO_I32_TAG_SCHEDULE_THROTTLED 0xff
250251} PABB_PACK pabb_MsgInfoI32 ;
251252
252253#define PABB_MSG_INFO_DATA 0x21
@@ -257,6 +258,7 @@ typedef struct{
257258#define PABB_MSG_INFO_STRING 0x23
258259
259260#define PABB_MSG_INFO_I32_LABEL 0x24
261+ #define PABB_MSG_INFO_H32_LABEL 0x25
260262typedef struct {
261263 uint32_t value ;
262264} PABB_PACK pabb_MsgInfoI32Label ;
@@ -326,28 +328,25 @@ typedef struct{
326328////////////////////////////////////////////////////////////////////////////////
327329// Commands
328330
329- #if 0
330- #define PABB_MSG_COMMAND_END_PROGRAM_CALLBACK 0x80
331- typedef struct {
332- seqnum_t seqnum ;
333- } PABB_PACK pabb_end_program_callback ;
334- #endif
331+ // These are no longer supported by anything.
335332
333+ #if 0
336334#define PABB_MSG_COMMAND_SET_LED_STATE 0x81
337335typedef struct {
338336 seqnum_t seqnum ;
339337 bool on ;
340338} PABB_PACK pabb_MsgCommandSetLeds ;
339+ #endif
341340
342341////////////////////////////////////////////////////////////////////////////////
343342////////////////////////////////////////////////////////////////////////////////
344343
345- #if _WIN32
346- #pragma pack(pop)
347- #endif
348-
349344#ifdef __cplusplus
350345}
351346#endif
352347
348+ #if _WIN32
349+ #pragma pack(pop)
350+ #endif
351+
353352#endif
0 commit comments