Performs the [RequestServerInfo]([ServerInfo](buttplug_core::message::RequestServerInfo) / [ServerInfo](buttplug_core::message::ServerInfo) handshake, as specified in the [Buttplug Protocol Spec](https://buttplug-spec.docs.buttplug.io). This is the first thing that must happens upon connection to the server, in order to make sure the server can speak the same protocol version as the client.
(&self, msg: message::RequestServerInfoV4)
| 411 | /// happens upon connection to the server, in order to make sure the server can speak the same |
| 412 | /// protocol version as the client. |
| 413 | fn perform_handshake(&self, msg: message::RequestServerInfoV4) -> ButtplugServerResultFuture { |
| 414 | // Check current state for handshake validity |
| 415 | { |
| 416 | let state = self.state.read().expect("State lock poisoned"); |
| 417 | match &*state { |
| 418 | ConnectionState::Connected { .. } => { |
| 419 | return ButtplugHandshakeError::HandshakeAlreadyHappened.into(); |
| 420 | } |
| 421 | ConnectionState::Disconnected | ConnectionState::PingedOut => { |
| 422 | return ButtplugHandshakeError::ReconnectDenied.into(); |
| 423 | } |
| 424 | ConnectionState::AwaitingHandshake => { |
| 425 | // This is the expected state, continue with handshake |
| 426 | } |
| 427 | } |
| 428 | } |
| 429 | |
| 430 | info!( |
| 431 | "Performing server handshake check with client {} at message version {}.{}", |
| 432 | msg.client_name(), |
| 433 | msg.protocol_version_major(), |
| 434 | msg.protocol_version_minor() |
| 435 | ); |
| 436 | |
| 437 | if BUTTPLUG_CURRENT_API_MAJOR_VERSION < msg.protocol_version_major() { |
| 438 | return ButtplugHandshakeError::MessageSpecVersionMismatch( |
| 439 | BUTTPLUG_CURRENT_API_MAJOR_VERSION, |
| 440 | msg.protocol_version_major(), |
| 441 | ) |
| 442 | .into(); |
| 443 | } |
| 444 | |
| 445 | // Only start the ping timer after we've received the handshake. |
| 446 | let ping_timer = self.ping_timer.clone(); |
| 447 | |
| 448 | // Due to programming/spec errors in prior versions of the protocol, anything before v4 expected |
| 449 | // that it would be back a matching api version of the server. The correct response is to send back whatever the |
| 450 | let output_version = if (msg.protocol_version_major() as u32) < 4 { |
| 451 | msg.protocol_version_major() |
| 452 | } else { |
| 453 | BUTTPLUG_CURRENT_API_MAJOR_VERSION |
| 454 | }; |
| 455 | let out_msg = |
| 456 | message::ServerInfoV4::new(&self.server_name, output_version, 0, self.max_ping_time); |
| 457 | |
| 458 | // protocol_version_major() returns ButtplugMessageSpecVersion directly |
| 459 | let spec_version = msg.protocol_version_major(); |
| 460 | let client_name = msg.client_name().to_owned(); |
| 461 | let state = self.state.clone(); |
| 462 | |
| 463 | async move { |
| 464 | ping_timer.start_ping_timer().await; |
| 465 | { |
| 466 | let mut state_guard = state.write().expect("State lock poisoned"); |
| 467 | *state_guard = ConnectionState::Connected { |
| 468 | client_name, |
| 469 | spec_version, |
| 470 | }; |
no test coverage detected