DDS  ver. 2.0
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_service& _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(MiscCommon::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,
58 
59  if (!processHandshake_channelTypeSupported(
60  static_cast<EChannelType>(_attachment->m_channelType), false, _sender.m_ID))
61  return;
62  if (!processHandshake_versionMatch(_attachment->m_version, false, _sender.m_ID))
63  return;
64  if (!processHandshake_sessionIDMatch(_attachment->m_sSID, false, _sender.m_ID))
65  return;
66 
67  // everything is OK, we can work with this agent
69  << "New lobby member [" << _sender.m_ID << "] has successfully connected.";
70 
71  this->template pushMsg<cmdREPLY_LOBBY_MEMBER_HANDSHAKE_OK>(_sender.m_ID);
72 
73  // notify all subscribers about the event
74  this->dispatchHandlers(EChannelEvents::OnLobbyMemberHandshakeOK, _sender);
75  });
76  }
77 
79  {
80  }
81 
82  private:
83  bool processHandshake_channelTypeSupported(EChannelType _channelType, bool _lobbyLeader, uint64_t _senderID)
84  {
85  // Check that the client channel is actually supported
86  bool isSupportedChnl(false);
87  for (const auto& v : m_requiredChannelTypes)
88  {
89  isSupportedChnl = (_channelType == v);
90  if (isSupportedChnl)
91  break;
92  }
93 
94  if (!isSupportedChnl)
95  {
96  handshakeFailed("Unsupported channel type", _lobbyLeader, _senderID);
97  return false;
98  }
99  return true;
100  }
101 
102  bool processHandshake_versionMatch(uint16_t _version, bool _lobbyLeader, uint64_t _senderID)
103  {
104  // send shutdown if versions are incompatible
105  if (_version != DDS_PROTOCOL_VERSION)
106  {
107  std::stringstream ss;
108  ss << "Incompatible protocol version. Server: " << DDS_PROTOCOL_VERSION << " Client: " << _version;
109  handshakeFailed(ss.str(), _lobbyLeader, _senderID);
110  return false;
111  }
112  return true;
113  }
114 
115  bool processHandshake_sessionIDMatch(const std::string& _sessionID, bool _lobbyLeader, uint64_t _senderID)
116  {
117  // Check Session ID
118  if (this->m_sessionID.empty() || this->m_sessionID != _sessionID)
119  {
120  handshakeFailed("Incompatible Session ID", _lobbyLeader, _senderID);
121  return false;
122  }
123  return true;
124  }
125 
126  void handshakeFailed(const std::string& _reason, bool _lobbyLeader, uint64_t _senderID)
127  {
128  this->m_isHandshakeOK = false;
130  LOG(MiscCommon::warning) << _reason << "; Client: " << this->remoteEndIDString();
131 
132  if (_lobbyLeader)
133  {
134  this->template pushMsg<cmdREPLY_HANDSHAKE_ERR>(SSimpleMsgCmd(_reason, MiscCommon::fatal),
135  _senderID);
136  // notify all subscribers about the event
137  this->dispatchHandlers(EChannelEvents::OnHandshakeFailed, SSenderInfo());
138  }
139  else
140  {
141  this->template pushMsg<cmdREPLY_LOBBY_MEMBER_HANDSHAKE_ERR>(
142  SSimpleMsgCmd(_reason, MiscCommon::fatal), _senderID);
143  // notify all subscribers about the event
145  }
146  }
147 
148  private:
149  channelTypeVector_t m_requiredChannelTypes;
150  };
151  }
152 }
153 
154 #endif
bool m_isHandshakeOK
Definition: BaseChannelImpl.h:966
Definition: def.h:151
Definition: BaseEventHandlersImpl.h:48
EChannelType
Definition: ProtocolDef.h:15
EChannelType m_channelType
Definition: BaseChannelImpl.h:967
std::shared_ptr< SEmptyCmd > ptr_t
Definition: CommandAttachmentImpl.h:66
std::string m_sessionID
Definition: BaseChannelImpl.h:968
#define LOG(severity)
Definition: Logger.h:54
Definition: SimpleMsgCmd.h:16
Definition: dds-agent/src/AgentConnectionManager.h:18
std::string remoteEndIDString()
Definition: BaseChannelImpl.h:733
Definition: def.h:153
Definition: BaseChannelImpl.h:205
Definition: BaseChannelImpl.h:43
std::vector< EChannelType > channelTypeVector_t
Definition: ProtocolDef.h:22
boost::asio::ip::tcp::socket & socket()
Definition: BaseChannelImpl.h:304
Definition: def.h:150
uint64_t m_protocolHeaderID
Definition: BaseChannelImpl.h:969