Skip to content

Commit 3be08a9

Browse files
committed
Handle disconnects by the Switch.
1 parent 3b96223 commit 3be08a9

File tree

5 files changed

+70
-40
lines changed

5 files changed

+70
-40
lines changed

ClientSource/Connection/PABotBase.cpp

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -534,6 +534,14 @@ void PABotBase::on_recv_message(BotBaseMessage message){
534534
}
535535
return;
536536
}
537+
case PABB_MSG_ERROR_DISCONNECTED:{
538+
m_logger.log("The console has disconnected the controller.", COLOR_RED);
539+
m_error_message = "Disconnected by console.";
540+
m_error.store(true, std::memory_order_release);
541+
std::lock_guard<std::mutex> lg0(m_sleep_lock);
542+
m_cv.notify_all();
543+
return;
544+
}
537545
case PABB_MSG_REQUEST_COMMAND_FINISHED:{
538546
process_command_finished<pabb_MsgRequestCommandFinished>(std::move(message));
539547
return;

ClientSource/Libraries/MessageConverter.cpp

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -123,6 +123,17 @@ int register_message_converters_framework_errors(){
123123
return ss.str();
124124
}
125125
);
126+
register_message_converter(
127+
PABB_MSG_ERROR_DISCONNECTED,
128+
[](const std::string& body){
129+
std::ostringstream ss;
130+
ss << "PABB_MSG_ERROR_DISCONNECTED - ";
131+
if (body.size() != sizeof(pabb_MsgInfoDisconnected)){ ss << "(invalid size)" << std::endl; return ss.str(); }
132+
const auto* params = (const pabb_MsgInfoDisconnected*)body.c_str();
133+
ss << "error code = " << params->error_code;
134+
return ss.str();
135+
}
136+
);
126137
return 0;
127138
}
128139
int register_message_converters_framework_acks(){
@@ -329,6 +340,7 @@ int register_message_converters_framework_requests(){
329340
return ss.str();
330341
}
331342
);
343+
#if 0
332344
register_message_converter(
333345
PABB_MSG_COMMAND_END_PROGRAM_CALLBACK,
334346
[](const std::string& body){
@@ -340,6 +352,7 @@ int register_message_converters_framework_requests(){
340352
return ss.str();
341353
}
342354
);
355+
#endif
343356
register_message_converter(
344357
PABB_MSG_COMMAND_SET_LED_STATE,
345358
[](const std::string& body){

Common/SerialPABotBase/SerialPABotBase_Protocol.h

Lines changed: 46 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -1,122 +1,122 @@
11
/* Serial PABotBase Message Protocol
2-
*
2+
*
33
* From: https://github.com/PokemonAutomation/
4-
*
5-
*
4+
*
5+
*
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:
111-
*
111+
*
112112
* - PABotBase can queue up to 4 commands. If it receives any commands
113113
* while the queue is full, it drops it and responds with
114114
* "PABB_MSG_ERROR_COMMAND_DROPPED". (Any command that results in a
115115
* button press or a wait is a long command.)
116-
*
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
@@ -199,6 +199,11 @@ typedef struct{
199199
uint16_t error_code;
200200
} PABB_PACK pabb_MsgInfoWARNING;
201201

202+
#define PABB_MSG_ERROR_DISCONNECTED 0x08
203+
typedef struct{
204+
uint16_t error_code;
205+
} PABB_PACK pabb_MsgInfoDisconnected;
206+
202207
////////////////////////////////////////////////////////////////////////////////
203208
// Ack
204209
#define PABB_MSG_ACK_COMMAND 0x10
@@ -308,10 +313,12 @@ typedef struct{
308313
////////////////////////////////////////////////////////////////////////////////
309314
// Commands
310315

316+
#if 0
311317
#define PABB_MSG_COMMAND_END_PROGRAM_CALLBACK 0x80
312318
typedef struct{
313319
seqnum_t seqnum;
314320
} PABB_PACK pabb_end_program_callback;
321+
#endif
315322

316323
#define PABB_MSG_COMMAND_SET_LED_STATE 0x81
317324
typedef struct{

SerialPrograms/Source/CommonFramework/Globals.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@ namespace PokemonAutomation{
2525
const bool IS_BETA_VERSION = true;
2626
const int PROGRAM_VERSION_MAJOR = 0;
2727
const int PROGRAM_VERSION_MINOR = 52;
28-
const int PROGRAM_VERSION_PATCH = 1;
28+
const int PROGRAM_VERSION_PATCH = 2;
2929

3030
const std::string PROGRAM_VERSION_BASE =
3131
"v" + std::to_string(PROGRAM_VERSION_MAJOR) +

SerialPrograms/Source/NintendoSwitch/Controllers/SerialPABotBase/NintendoSwitch_SerialPABotBase_WirelessController.cpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -241,7 +241,9 @@ void SerialPABotBase_WirelessController::status_thread(){
241241
error = "Unknown error.";
242242
}
243243
if (!error.empty()){
244+
stop();
244245
m_handle.set_status_line1(error, COLOR_RED);
246+
break;
245247
}
246248

247249
// cout << "lock()" << endl;

0 commit comments

Comments
 (0)