2 * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
8 * http://www.apache.org/licenses/LICENSE-2.0
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
17 * @file generic_socket_rpc_server.h
18 * @author Przemyslaw Dobrowolski (p.dobrowolsk@samsung.com)
20 * @brief This file is the header file for generic socket RPC server
22 #ifndef DPL_GENERIC_SOCKET_RPC_SERVER_H
23 #define DPL_GENERIC_SOCKET_RPC_SERVER_H
25 #include <dpl/rpc/abstract_rpc_connector.h>
26 #include <dpl/socket/abstract_socket.h>
31 template<typename SocketType>
32 class GenericSocketRPCServer :
33 public AbstractRPCConnector,
34 private DPL::Event::EventListener<DPL::Socket::AbstractSocketEvents::
41 DECLARE_EXCEPTION_TYPE(DPL::Exception, Base)
42 DECLARE_EXCEPTION_TYPE(Base, OpenFailed)
43 DECLARE_EXCEPTION_TYPE(Base, CloseFailed)
47 // Derived class implementations for connection managment
48 virtual AbstractRPCConnection *OpenSpecificConnection(SocketType *socket) =
52 typedef std::set<SocketType *> InternalInterfaceSet;
53 InternalInterfaceSet m_internalInterfacesSet;
55 virtual void OnEventReceived(
56 const DPL::Socket::AbstractSocketEvents::AcceptEvent &event)
58 // Retrieve socket sender
59 SocketType *server = static_cast<SocketType *>(event.GetSender());
61 // Is this interface still tracked ?
62 // It might have disappeared on close
63 typename InternalInterfaceSet::iterator iterator =
64 m_internalInterfacesSet.find(server);
66 if (iterator == m_internalInterfacesSet.end()) {
67 WrtLogD("RPC server interface socket disappeared");
71 // Accept incoming client
72 SocketType *client = static_cast<SocketType *>(server->Accept());
74 WrtLogD("Spontaneous accept on socket occurred");
78 WrtLogD("Client connected to server: %s",
79 client->GetRemoteAddress().ToString().c_str());
81 // Open specific connection implementation
82 AbstractRPCConnection *connection = OpenSpecificConnection(client);
84 // Retrieve ID once again
85 AbstractRPCConnectionID connectionID =
86 static_cast<AbstractRPCConnectionID>(server);
89 DPL::Event::EventSupport<AbstractRPCConnectorEvents::
90 ConnectionEstablishedEvent>::
91 EmitEvent(AbstractRPCConnectorEvents::ConnectionEstablishedEvent(
92 connectionID, connection, EventSender(
93 this)), DPL::Event::EmitMode::Queued);
97 explicit GenericSocketRPCServer()
100 virtual ~GenericSocketRPCServer()
102 // Always close connection
106 AbstractRPCConnectionID Open(const Address &socketAddress)
108 WrtLogD("Starting server: %s", socketAddress.ToString().c_str());
111 SocketType *socket = new SocketType();
113 // Add socket listener
114 socket->EventSupport<DPL::Socket::AbstractSocketEvents::AcceptEvent>::
122 // Bind socket address
123 socket->Bind(socketAddress);
128 Catch(DPL::Socket::AbstractSocket::Exception::Base)
130 // Remove back socket listener
131 socket->EventSupport<DPL::Socket::AbstractSocketEvents::AcceptEvent>
132 ::RemoveListener(this);
135 WrtLogD("Cannot start server: %s", socketAddress.ToString().c_str());
137 // Problem with server startup
138 ReThrowMsg(typename Exception::OpenFailed, socketAddress.ToString());
141 // Register new internal connection
142 m_internalInterfacesSet.insert(socket);
145 WrtLogD("Server started on interface: %s",
146 socket->GetLocalAddress().ToString().c_str());
148 // Return unique identifier
149 return static_cast<AbstractRPCConnectionID>(socket);
152 void Close(AbstractRPCConnectionID connectionID)
154 WrtLogD("Closing server interface...");
156 // Get socket from ID
157 SocketType *socket = static_cast<SocketType *>(connectionID);
159 // Find corresponding internal connection
160 typename InternalInterfaceSet::iterator iterator =
161 m_internalInterfacesSet.find(socket);
163 if (iterator == m_internalInterfacesSet.end()) {
170 // Remove socket listeners
171 socket->EventSupport<DPL::Socket::AbstractSocketEvents::AcceptEvent>::
172 RemoveListener(this);
175 m_internalInterfacesSet.erase(iterator);
183 while (!m_internalInterfacesSet.empty()) {
184 Close(static_cast<AbstractRPCConnectionID>(*m_internalInterfacesSet
192 #endif // DPL_GENERIC_SOCKET_RPC_SERVER_H