@@ -55,11 +55,10 @@ class DCNetService : public Service
55
55
void receiveEthFrame (const u8 *frame, u32 size) override ;
56
56
};
57
57
58
- template <typename SocketT>
59
58
class PPPSocket
60
59
{
61
60
public:
62
- PPPSocket (asio::io_context& io_context, const typename SocketT::endpoint_type & endpoint,
61
+ PPPSocket (asio::io_context& io_context, const asio::ip::tcp::endpoint & endpoint,
63
62
const std::string& endpointName = " " )
64
63
: socket(io_context)
65
64
{
@@ -71,7 +70,7 @@ class PPPSocket
71
70
receive ();
72
71
}
73
72
74
- ~PPPSocket () {
73
+ virtual ~PPPSocket () {
75
74
if (dumpfp != nullptr )
76
75
fclose (dumpfp);
77
76
}
@@ -86,8 +85,8 @@ class PPPSocket
86
85
doSend ();
87
86
}
88
87
89
- private :
90
- void receive ()
88
+ protected :
89
+ virtual void receive ()
91
90
{
92
91
socket.async_read_some (asio::buffer (recvBuffer),
93
92
[this ](const std::error_code& ec, size_t len)
@@ -172,7 +171,7 @@ class PPPSocket
172
171
#endif
173
172
}
174
173
175
- SocketT socket;
174
+ asio::ip::tcp::socket socket;
176
175
std::array<u8 , 1542 > recvBuffer;
177
176
std::array<u8 , 1542 > sendBuffer;
178
177
u32 sendBufSize = 0 ;
@@ -182,7 +181,55 @@ class PPPSocket
182
181
u64 dump_last_time_ms;
183
182
};
184
183
185
- using PPPTcpSocket = PPPSocket<asio::ip::tcp::socket>;
184
+ class PowerSmashPPPSocket : public PPPSocket
185
+ {
186
+ public:
187
+ PowerSmashPPPSocket (asio::io_context& io_context, const asio::ip::tcp::endpoint& endpoint,
188
+ const std::string& endpointName = " " )
189
+ : PPPSocket(io_context, endpoint, endpointName) {}
190
+
191
+ private:
192
+ void receive () override
193
+ {
194
+ socket.async_read_some (asio::buffer (&recvBuffer[recvBufSize], recvBuffer.size () - recvBufSize),
195
+ [this ](const std::error_code& ec, size_t len)
196
+ {
197
+ if (ec || len == 0 )
198
+ {
199
+ if (ec)
200
+ ERROR_LOG (NETWORK, " Receive error: %s" , ec.message ().c_str ());
201
+ close ();
202
+ return ;
203
+ }
204
+ recvBufSize += len;
205
+ while (recvBufSize != 0 )
206
+ {
207
+ u32 frameSize = 0 ;
208
+ for (u32 i = 1 ; i < recvBufSize; i++)
209
+ {
210
+ if (recvBuffer[i] == ' ~' ) {
211
+ frameSize = i + 1 ;
212
+ break ;
213
+ }
214
+ }
215
+ if (frameSize == 0 )
216
+ break ;
217
+ pppdump (recvBuffer.data (), frameSize, false );
218
+ // Power Smash requires both start and end Flag Sequences
219
+ if (recvBuffer[0 ] != ' ~' )
220
+ toModem.push (' ~' );
221
+ for (size_t i = 0 ; i < frameSize; i++)
222
+ toModem.push (recvBuffer[i]);
223
+ recvBufSize -= frameSize;
224
+ if (recvBufSize != 0 )
225
+ memmove (&recvBuffer[0 ], &recvBuffer[frameSize], recvBufSize);
226
+ }
227
+ receive ();
228
+ });
229
+ }
230
+
231
+ u32 recvBufSize = 0 ;
232
+ };
186
233
187
234
class EthSocket
188
235
{
@@ -609,11 +656,12 @@ class DCNetThread
609
656
610
657
std::thread thread;
611
658
std::unique_ptr<asio::io_context> io_context;
612
- std::unique_ptr<PPPTcpSocket > pppSocket;
659
+ std::unique_ptr<PPPSocket > pppSocket;
613
660
std::unique_ptr<EthSocket> ethSocket;
614
661
615
662
static constexpr uint16_t PPP_PORT = 7654 ;
616
663
static constexpr uint16_t TAP_PORT = 7655 ;
664
+ static constexpr uint16_t POWER_SMASH_PPP_PORT = 7656 ;
617
665
friend DCNetService;
618
666
};
619
667
static DCNetThread thread;
@@ -679,6 +727,7 @@ void DCNetService::receiveEthFrame(u8 const *frame, unsigned int len)
679
727
680
728
void DCNetThread::connect (const asio::ip::address& address, const std::string& apname)
681
729
{
730
+ const bool powerSmash = settings.content .gameId == " HDR-0113" ;
682
731
asio::ip::tcp::endpoint endpoint;
683
732
if (address.is_unspecified ())
684
733
{
@@ -689,6 +738,8 @@ void DCNetThread::connect(const asio::ip::address& address, const std::string& a
689
738
std::string port;
690
739
if (config::EmulateBBA)
691
740
port = std::to_string (TAP_PORT);
741
+ else if (powerSmash)
742
+ port = std::to_string (POWER_SMASH_PPP_PORT);
692
743
else
693
744
port = std::to_string (PPP_PORT);
694
745
asio::ip::tcp::resolver resolver (*io_context);
@@ -700,14 +751,22 @@ void DCNetThread::connect(const asio::ip::address& address, const std::string& a
700
751
throw FlycastException (" Host not found" );
701
752
endpoint = *it.begin ();
702
753
}
703
- else {
754
+ else
755
+ {
704
756
endpoint.address (address);
705
- endpoint.port (config::EmulateBBA ? TAP_PORT : PPP_PORT);
757
+ if (config::EmulateBBA)
758
+ endpoint.port (TAP_PORT);
759
+ else if (powerSmash)
760
+ endpoint.port (POWER_SMASH_PPP_PORT);
761
+ else
762
+ endpoint.port (PPP_PORT);
706
763
}
707
764
if (config::EmulateBBA)
708
765
ethSocket = std::make_unique<EthSocket>(*io_context, endpoint, apname);
766
+ else if (powerSmash)
767
+ pppSocket = std::make_unique<PowerSmashPPPSocket>(*io_context, endpoint, apname);
709
768
else
710
- pppSocket = std::make_unique<PPPTcpSocket >(*io_context, endpoint, apname);
769
+ pppSocket = std::make_unique<PPPSocket >(*io_context, endpoint, apname);
711
770
}
712
771
713
772
void DCNetThread::run ()
0 commit comments