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_rpc_connection.cpp
18 * @author Przemyslaw Dobrowolski (p.dobrowolsk@samsung.com)
20 * @brief This file is the implementation file of generic RPC connection
23 #include <dpl/rpc/generic_rpc_connection.h>
24 #include <dpl/log/wrt_log.h>
25 #include <dpl/aligned.h>
30 namespace // anonymous
49 unsigned char data[1];
51 } // namespace Protocol
52 } // namespace anonymous
54 GenericRPCConnection::GenericRPCConnection(
55 AbstractWaitableInputOutput *inputOutput) :
56 m_inputOutput(inputOutput)
58 WrtLogD("Opening generic RPC...");
59 WaitableInputOutputExecutionContextSupport::Open(inputOutput);
60 WrtLogD("Generic RPC opened");
63 GenericRPCConnection::~GenericRPCConnection()
65 // Ensure RPC is closed
66 WrtLogD("Closing generic RPC...");
67 WaitableInputOutputExecutionContextSupport::Close();
68 WrtLogD("Generic RPC closed");
71 void GenericRPCConnection::AsyncCall(const RPCFunction &function)
73 WrtLogD("Executing async call");
76 BinaryQueue serializedCall = function.Serialize();
79 Protocol::AsyncCall call;
80 call.size = static_cast<unsigned short>(serializedCall.Size());
81 call.type = Protocol::PacketType_AsyncCall;
83 m_outputStream.AppendCopy(&call, sizeof(Protocol::Header));
84 m_outputStream.AppendMoveFrom(serializedCall);
86 // Try to feed output with data
91 Catch(WaitableInputOutputExecutionContextSupport::Exception::NotOpened)
93 // Error occurred while feeding
94 ReThrow(AbstractRPCConnection::Exception::AsyncCallFailed);
98 void GenericRPCConnection::Ping()
100 WrtLogD("Executing ping call");
103 Protocol::AsyncCall call;
105 call.type = Protocol::PacketType_PingPong;
107 m_outputStream.AppendCopy(&call, sizeof(Protocol::Header));
109 // Try to feed output with data
114 Catch(WaitableInputOutputExecutionContextSupport::Exception::NotOpened)
116 // Error occurred while feeding
117 ReThrow(AbstractRPCConnection::Exception::PingFailed);
121 void GenericRPCConnection::OnInputStreamRead()
123 WrtLogD("Interpreting %i bytes buffer", m_inputStream.Size());
125 // Enough bytes to read at least one header ?
126 if (m_inputStream.Size() >= sizeof(Protocol::Header)) {
127 // Begin consuming as much packets as it is possible
128 while (m_inputStream.Size() >= sizeof(Protocol::Header)) {
129 Protocol::Header header;
130 m_inputStream.Flatten(&header, sizeof(header));
132 if (m_inputStream.Size() >= sizeof(Protocol::Header) +
135 WrtLogD("Will parse packet of type: %i", header.type);
137 // Allocate new packet (header + real packet data)
138 void *binaryPacket = malloc(
139 sizeof(Protocol::Header) + header.size);
141 if (binaryPacket == NULL) {
142 throw std::bad_alloc();
145 // Get it from stream
146 m_inputStream.FlattenConsume(
148 sizeof(Protocol::Header) +
151 // Parse specific packet
152 switch (header.type) {
153 case Protocol::PacketType_AsyncCall:
157 // No need to delete packet data, we can use it
158 call.AppendUnmanaged(binaryPacket,
159 sizeof(Protocol::Header) + header.size,
160 &BinaryQueue::BufferDeleterFree,
163 // ...but just remove protocol header
164 call.Consume(sizeof(Protocol::Header));
166 WrtLogD("Async call of size: %i parsed", header.size);
168 // Call async call event listeners
169 DPL::Event::EventSupport<AbstractRPCConnectionEvents::
171 EmitEvent(AbstractRPCConnectionEvents::AsyncCallEvent(
172 RPCFunction(call), EventSender(
173 this)), DPL::Event::EmitMode::Queued);
177 case Protocol::PacketType_PingPong:
179 // Reply with ping/pong
182 // Do not need packet data
185 WrtLogD("Ping pong replied");
190 WrtLogD("Warning: Unknown packet type");
195 WrtLogD("Too few bytes to read packet");
200 WrtLogD("Too few bytes to read header");
204 void GenericRPCConnection::OnInputStreamClosed()
207 DPL::Event::EventSupport<AbstractRPCConnectionEvents::ConnectionClosedEvent>
209 EmitEvent(AbstractRPCConnectionEvents::ConnectionClosedEvent(
210 EventSender(this)), DPL::Event::EmitMode::Queued);
213 void GenericRPCConnection::OnInputStreamBroken()
216 DPL::Event::EventSupport<AbstractRPCConnectionEvents::ConnectionBrokenEvent>
218 EmitEvent(AbstractRPCConnectionEvents::ConnectionBrokenEvent(
219 EventSender(this)), DPL::Event::EmitMode::Queued);