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_client.h
18 * @author Przemyslaw Dobrowolski (p.dobrowolsk@samsung.com)
20 * @brief This file is the header file for generic socket RPC client
22 #ifndef DPL_GENERIC_SOCKET_RPC_CLIENT_H
23 #define DPL_GENERIC_SOCKET_RPC_CLIENT_H
25 #include <dpl/rpc/abstract_rpc_connector.h>
26 #include <dpl/socket/abstract_socket.h>
31 template<typename SocketType>
32 class GenericSocketRPCClient :
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 *> InternalConnectionSet;
53 InternalConnectionSet m_internalConnectionSet;
55 virtual void OnEventReceived(
56 const DPL::Socket::AbstractSocketEvents::ConnectedEvent &event)
58 // Retrieve socket sender
59 SocketType *socket = static_cast<SocketType *>(event.GetSender());
61 WrtLogD("Connection with RPC server established");
63 // Is this connection still tracked ?
64 // It might have disappeared on close
65 typename InternalConnectionSet::iterator iterator =
66 m_internalConnectionSet.find(socket);
68 if (iterator == m_internalConnectionSet.end()) {
69 WrtLogD("RPC client connection socket disappeared");
73 // Open specific connection implementation
74 AbstractRPCConnection *connection = OpenSpecificConnection(socket);
76 // Remove internal connection
77 socket->EventSupport<DPL::Socket::AbstractSocketEvents::ConnectedEvent>
78 ::RemoveListener(this);
79 m_internalConnectionSet.erase(iterator);
81 // Retrieve ID once again
82 AbstractRPCConnectionID connectionID =
83 static_cast<AbstractRPCConnectionID>(socket);
86 DPL::Event::EventSupport<AbstractRPCConnectorEvents::
87 ConnectionEstablishedEvent>::
88 EmitEvent(AbstractRPCConnectorEvents::ConnectionEstablishedEvent(
89 connectionID, connection, EventSender(
90 this)), DPL::Event::EmitMode::Queued);
94 explicit GenericSocketRPCClient()
97 virtual ~GenericSocketRPCClient()
99 // Always close all connections
103 AbstractRPCConnectionID Open(const Address &socketAddress)
105 WrtLogD("Starting client: %s", socketAddress.ToString().c_str());
108 SocketType *socket = new SocketType();
110 // Add socket listeners
111 socket->EventSupport<DPL::Socket::AbstractSocketEvents::ConnectedEvent>
119 // Start connecting to server
120 socket->Connect(Address(socketAddress));
122 Catch(DPL::Socket::AbstractSocket::Exception::Base)
124 // Remove back socket listener
125 socket->EventSupport<DPL::Socket::AbstractSocketEvents::
126 ConnectedEvent>::RemoveListener(this);
129 WrtLogD("Cannot connect to: %s", socketAddress.ToString().c_str());
131 // Problem with client startup
132 ReThrowMsg(typename Exception::OpenFailed, socketAddress.ToString());
135 // Register new internal connection
136 m_internalConnectionSet.insert(socket);
140 "Client started on interface: %s",
141 socket->GetLocalAddress().ToString().c_str());
143 // Return unique identifier
144 return static_cast<AbstractRPCConnectionID>(socket);
147 void Close(AbstractRPCConnectionID connectionID)
149 WrtLogD("Closing client interface...");
151 // Get socket from ID
152 SocketType *socket = static_cast<SocketType *>(connectionID);
154 // Find corresponding internal connection
155 typename InternalConnectionSet::iterator iterator =
156 m_internalConnectionSet.find(socket);
158 if (iterator == m_internalConnectionSet.end()) {
165 // Remove internal socket
166 socket->EventSupport<DPL::Socket::AbstractSocketEvents::ConnectedEvent>
167 ::RemoveListener(this);
170 m_internalConnectionSet.erase(iterator);
178 while (!m_internalConnectionSet.empty()) {
179 Close(static_cast<AbstractRPCConnectionID>(*m_internalConnectionSet
187 #endif // DPL_GENERIC_SOCKET_RPC_CLIENT_H