DDS  ver. 3.6
ServerChannelImpl.h
Go to the documentation of this file.
1 // Copyright 2014 GSI, Inc. All rights reserved.
2 //
3 //
4 //
5 
6 #ifndef DDS_ServerChannelImpl_h
7 #define DDS_ServerChannelImpl_h
8 
9 // DDS
10 #include "BaseChannelImpl.h"
11 #include "Version.h"
12 
13 namespace dds
14 {
15  namespace protocol_api
16  {
17  template <class T>
18  class CServerChannelImpl : public CBaseChannelImpl<T>
19  {
20  protected:
21  CServerChannelImpl<T>(boost::asio::io_context& _service, const channelTypeVector_t _requiredChannelTypes)
22  : CBaseChannelImpl<T>(_service, 0)
23  , m_requiredChannelTypes(_requiredChannelTypes)
24  {
25  // Register handshake callback
26  this->template registerHandler<cmdHANDSHAKE>(
27  [this](const SSenderInfo& _sender, SCommandAttachmentImpl<cmdHANDSHAKE>::ptr_t _attachment)
28  {
29  if (!processHandshake_channelTypeSupported(
30  static_cast<EChannelType>(_attachment->m_channelType), true, _sender.m_ID))
31  return;
32  if (!processHandshake_versionMatch(_attachment->m_version, true, _sender.m_ID))
33  return;
34  if (!processHandshake_sessionIDMatch(_attachment->m_sSID, true, _sender.m_ID))
35  return;
36 
37  this->m_protocolHeaderID = _sender.m_ID;
38  this->m_isHandshakeOK = true;
39  this->m_channelType = static_cast<EChannelType>(_attachment->m_channelType);
40 
41  // The following commands starts message processing which might have been queued before.
42  this->template pushMsg<cmdUNKNOWN>();
43 
44  // everything is OK, we can work with this agent
45  LOG(dds::misc::info) << "[" << this->socket().remote_endpoint().address().to_string()
46  << "] has successfully connected.";
47 
48  this->template pushMsg<cmdREPLY_HANDSHAKE_OK>(_sender.m_ID);
49 
50  // notify all subscribers about the event
51  this->dispatchHandlers(EChannelEvents::OnHandshakeOK, _sender);
52  });
53 
54  // Register handshake callback
55  // this->template registerHandler<cmdLOBBY_MEMBER_HANDSHAKE>(
56  // [this](const SSenderInfo& _sender,
57  // SCommandAttachmentImpl<cmdLOBBY_MEMBER_HANDSHAKE>::ptr_t _attachment) {
58  // if (!processHandshake_channelTypeSupported(
59  // static_cast<EChannelType>(_attachment->m_channelType), false,
60  // _sender.m_ID))
61  // return;
62  // if (!processHandshake_versionMatch(_attachment->m_version, false,
63  // _sender.m_ID))
64  // return;
65  // if (!processHandshake_sessionIDMatch(_attachment->m_sSID, false,
66  // _sender.m_ID))
67  // return;
68  //
69  // // everything is OK, we can work with this agent
70  // LOG(dds::misc::info)
71  // << "New lobby member [" << _sender.m_ID << "] has successfully
72  // connected.";
73  //
74  // SReplyCmd cmd =
75  // SReplyCmd("", (uint16_t)SReplyCmd::EStatusCode::OK, 0,
76  // (uint16_t)cmdLOBBY_MEMBER_HANDSHAKE);
77  // this->template pushMsg<cmdREPLY>(cmd, _sender.m_ID);
78  //
79  // // notify all subscribers about the event
80  // this->dispatchHandlers(EChannelEvents::OnLobbyMemberHandshakeOK, _sender);
81  // });
82  }
83 
85  {
86  }
87 
88  private:
89  bool processHandshake_channelTypeSupported(EChannelType _channelType, bool _lobbyLeader, uint64_t _senderID)
90  {
91  // Check that the client channel is actually supported
92  bool isSupportedChnl(false);
93  for (const auto& v : m_requiredChannelTypes)
94  {
95  isSupportedChnl = (_channelType == v);
96  if (isSupportedChnl)
97  break;
98  }
99 
100  if (!isSupportedChnl)
101  {
102  handshakeFailed("Unsupported channel type", _lobbyLeader, _senderID);
103  return false;
104  }
105  return true;
106  }
107 
108  bool processHandshake_versionMatch(uint16_t _version, bool _lobbyLeader, uint64_t _senderID)
109  {
110  // send shutdown if versions are incompatible
111  if (_version != DDS_PROTOCOL_VERSION)
112  {
113  std::stringstream ss;
114  ss << "Incompatible protocol version. Server: " << DDS_PROTOCOL_VERSION << " Client: " << _version;
115  handshakeFailed(ss.str(), _lobbyLeader, _senderID);
116  return false;
117  }
118  return true;
119  }
120 
121  bool processHandshake_sessionIDMatch(const std::string& _sessionID, bool _lobbyLeader, uint64_t _senderID)
122  {
123  // Check Session ID
124  if (this->m_sessionID.empty() || this->m_sessionID != _sessionID)
125  {
126  handshakeFailed("Incompatible Session ID", _lobbyLeader, _senderID);
127  return false;
128  }
129  return true;
130  }
131 
132  void handshakeFailed(const std::string& _reason, bool /*_lobbyLeader*/, uint64_t _senderID)
133  {
134  this->m_isHandshakeOK = false;
136  LOG(dds::misc::warning) << _reason << "; Client: " << this->remoteEndIDString();
137 
138  this->template pushMsg<cmdREPLY_HANDSHAKE_ERR>(SSimpleMsgCmd(_reason, dds::misc::fatal), _senderID);
139  // notify all subscribers about the event
140  this->dispatchHandlers(EChannelEvents::OnHandshakeFailed, SSenderInfo());
141  }
142 
143  private:
144  channelTypeVector_t m_requiredChannelTypes;
145  };
146  } // namespace protocol_api
147 } // namespace dds
148 
149 #endif
bool m_isHandshakeOK
Definition: BaseChannelImpl.h:978
Definition: BaseEventHandlersImpl.h:48
EChannelType
Definition: ProtocolDef.h:15
Definition: def.h:148
EChannelType m_channelType
Definition: BaseChannelImpl.h:979
std::shared_ptr< SEmptyCmd > ptr_t
Definition: CommandAttachmentImpl.h:64
std::string m_sessionID
Definition: BaseChannelImpl.h:980
#define LOG(severity)
Definition: Logger.h:34
Miscellaneous functions and helpers are located here.
Definition: AgentConnectionManager.h:13
std::string remoteEndIDString()
Definition: BaseChannelImpl.h:751
Definition: BaseChannelImpl.h:219
Definition: BaseChannelImpl.h:37
Definition: def.h:147
std::vector< EChannelType > channelTypeVector_t
Definition: ProtocolDef.h:21
Definition: def.h:150
boost::asio::ip::tcp::socket & socket()
Definition: BaseChannelImpl.h:319
uint64_t m_ID
Definition: BaseEventHandlersImpl.h:50