2 * Copyright (c) 2021 Samsung Electronics Co., Ltd.
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.
19 #include <dali/internal/network/common/network-performance-client.h>
26 #include <dali/internal/network/common/automation.h>
27 #include <dali/internal/network/common/network-performance-protocol.h>
28 #include <dali/internal/network/common/socket-interface.h>
38 const float MICROSECONDS_TO_SECOND = 1e-6;
39 const char UNKNOWN_CMD[] = "Command or parameter invalid, type help for list of commands\n";
42 * helper class to store data along with the automation callback.
44 class AutomationCallback : public CallbackBase
48 * instead of using templates, or having different callback classes for each callback
49 * we use a command id that decides which static function to call on the Automation class.
58 AutomationCallback(unsigned int clientId, ClientSendDataInterface& sendDataInterface)
59 : CallbackBase(reinterpret_cast<void*>(this),
60 NULL, // we get the dispatcher to call function directly
61 reinterpret_cast<CallbackBase::Dispatcher>(&AutomationCallback::Dispatcher)),
62 mSendDataInterface(sendDataInterface),
63 mCommandId(UNKNOWN_COMMAND),
68 void AssignSetPropertyCommand(std::string setPropertyCommand)
70 mCommandId = SET_PROPERTY;
71 mPropertyCommand = setPropertyCommand;
73 void AssignDumpSceneCommand()
75 mCommandId = DUMP_SCENE;
84 Automation::SetProperty(mPropertyCommand);
89 Automation::DumpScene(mClientId, &mSendDataInterface);
94 DALI_ASSERT_DEBUG(0 && "Unknown command");
99 static void Dispatcher(CallbackBase& base)
101 AutomationCallback& automationCallback(static_cast<AutomationCallback&>(base));
102 automationCallback.RunCallback();
106 std::string mPropertyCommand; ///< property command
107 ClientSendDataInterface& mSendDataInterface; ///< Abstract client send data interface
108 CommandId mCommandId; ///< command id
109 const unsigned int mClientId; ///< client id
112 } // unnamed namespace
114 NetworkPerformanceClient::NetworkPerformanceClient(pthread_t* thread,
115 SocketInterface* socket,
116 unsigned int clientId,
117 ClientSendDataInterface& sendDataInterface,
118 SocketFactoryInterface& socketFactory)
121 mMarkerBitmask(PerformanceMarker::FILTERING_DISABLED),
122 mSendDataInterface(sendDataInterface),
123 mSocketFactoryInterface(socketFactory),
125 mConsoleClient(false)
129 NetworkPerformanceClient::~NetworkPerformanceClient()
131 if(mSocket->SocketIsOpen())
133 mSocket->CloseSocket();
135 mSocketFactoryInterface.DestroySocket(mSocket);
138 unsigned int NetworkPerformanceClient::GetId() const
143 SocketInterface& NetworkPerformanceClient::GetSocket()
148 bool NetworkPerformanceClient::WriteSocket(const void* buffer, unsigned int bufferSizeInBytes)
150 return mSocket->Write(buffer, bufferSizeInBytes);
153 bool NetworkPerformanceClient::TransmitMarker(const PerformanceMarker& marker, const char* const description)
155 if(!marker.IsFilterEnabled(mMarkerBitmask))
161 // write out the time stamp
163 double usec = marker.GetTimeStamp().microseconds;
164 int size = snprintf(buffer, sizeof(buffer), "%.6f (seconds), %s\n", usec * MICROSECONDS_TO_SECOND, description);
166 return mSocket->Write(buffer, size);
169 // todo serialize the data
173 void NetworkPerformanceClient::ExitSelect()
175 mSocket->ExitSelect();
178 pthread_t* NetworkPerformanceClient::GetThread()
183 void NetworkPerformanceClient::ProcessCommand(char* buffer, unsigned int bufferSizeInBytes)
185 // if connected via console, then strip off the carriage return, and switch to console mode
186 if(buffer[bufferSizeInBytes - 1] == '\n')
188 buffer[bufferSizeInBytes - 1] = 0;
189 mConsoleClient = true;
191 unsigned int param(0);
192 std::string stringParam;
193 PerformanceProtocol::CommandId commandId(PerformanceProtocol::UNKNOWN_COMMAND);
195 bool ok = PerformanceProtocol::GetCommandId(buffer, bufferSizeInBytes, commandId, param, stringParam);
198 WriteSocket(UNKNOWN_CMD, sizeof(UNKNOWN_CMD));
201 std::string response;
205 case PerformanceProtocol::HELP_MESSAGE:
207 response = PerformanceProtocol::GetHelpMessage();
211 case PerformanceProtocol::ENABLE_TIME_MARKER_BIT_MASK:
213 mMarkerBitmask = static_cast<PerformanceMarker::MarkerFilter>(param);
214 response = "enable time marker ";
218 case PerformanceProtocol::DUMP_SCENE_GRAPH:
220 // this needs to be run on the main thread, use the trigger event....
221 AutomationCallback* callback = new AutomationCallback(mClientId, mSendDataInterface);
222 callback->AssignDumpSceneCommand();
224 // create a trigger event that automatically deletes itself after the callback has run in the main thread
225 TriggerEventInterface* interface = TriggerEventFactory::CreateTriggerEvent(callback, TriggerEventInterface::DELETE_AFTER_TRIGGER);
227 // asynchronous call, the call back will be run sometime later on the main thread
228 interface->Trigger();
232 case PerformanceProtocol::SET_PROPERTIES:
234 // this needs to be run on the main thread, use the trigger event....
235 AutomationCallback* callback = new AutomationCallback(mClientId, mSendDataInterface);
236 callback->AssignSetPropertyCommand(stringParam);
238 // create a trigger event that automatically deletes itself after the callback has run in the main thread
239 TriggerEventInterface* interface = TriggerEventFactory::CreateTriggerEvent(callback, TriggerEventInterface::DELETE_AFTER_TRIGGER);
241 // asynchronous call, the call back will be run sometime later on the main thread
242 interface->Trigger();
246 case PerformanceProtocol::LIST_METRICS_AVAILABLE:
247 case PerformanceProtocol::ENABLE_METRIC:
248 case PerformanceProtocol::DISABLE_METRIC:
250 response = "Metrics currently not supported";
255 response = UNKNOWN_CMD;
259 if(!response.empty())
261 // add a carriage return for console clients
266 WriteSocket(response.c_str(), response.length());
270 } // namespace Adaptor
272 } // namespace Internal