2 * Copyright (c) 2022 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>
27 #include <dali/internal/network/common/automation.h>
28 #include <dali/internal/network/common/network-performance-protocol.h>
29 #include <dali/internal/network/common/socket-interface.h>
39 const float MICROSECONDS_TO_SECOND = 1e-6;
40 const char UNKNOWN_CMD[] = "Command or parameter invalid, type help for list of commands\n";
43 * helper class to store data along with the automation callback.
45 class AutomationCallback : public CallbackBase
49 * instead of using templates, or having different callback classes for each callback
50 * we use a command id that decides which static function to call on the Automation class.
60 AutomationCallback(unsigned int clientId, ClientSendDataInterface& sendDataInterface)
61 : CallbackBase(reinterpret_cast<void*>(this),
62 NULL, // we get the dispatcher to call function directly
63 reinterpret_cast<CallbackBase::Dispatcher>(&AutomationCallback::Dispatcher)),
64 mSendDataInterface(sendDataInterface),
65 mCommandId(UNKNOWN_COMMAND),
70 void AssignSetPropertyCommand(std::string setPropertyCommand)
72 mCommandId = SET_PROPERTY;
73 mCommandString = setPropertyCommand;
76 void AssignDumpSceneCommand()
78 mCommandId = DUMP_SCENE;
81 void AssignCustomCommand(std::string&& customCommand)
83 mCommandId = CUSTOM_COMMAND;
84 mCommandString = std::move(customCommand);
93 Automation::SetProperty(mCommandString);
98 Automation::DumpScene(mClientId, &mSendDataInterface);
103 Automation::SetCustomCommand(mCommandString);
108 DALI_ASSERT_DEBUG(0 && "Unknown command");
113 static void Dispatcher(CallbackBase& base)
115 AutomationCallback& automationCallback(static_cast<AutomationCallback&>(base));
116 automationCallback.RunCallback();
120 std::string mCommandString; ///< command string for property or custom command
121 ClientSendDataInterface& mSendDataInterface; ///< Abstract client send data interface
122 CommandId mCommandId; ///< command id
123 const unsigned int mClientId; ///< client id
127 * @brief Helper to ensure the AutomationCallback method we want is called in the main thread
130 void TriggerOnMainThread(unsigned int clientId, ClientSendDataInterface& sendDataInterface, T&& lambda)
132 // this needs to be run on the main thread, use the trigger event....
133 AutomationCallback* callback = new AutomationCallback(clientId, sendDataInterface);
136 // create a trigger event that automatically deletes itself after the callback has run in the main thread
137 TriggerEventInterface* interface = TriggerEventFactory::CreateTriggerEvent(callback, TriggerEventInterface::DELETE_AFTER_TRIGGER);
139 // asynchronous call, the call back will be run sometime later on the main thread
140 interface->Trigger();
143 } // unnamed namespace
145 NetworkPerformanceClient::NetworkPerformanceClient(pthread_t* thread,
146 SocketInterface* socket,
147 unsigned int clientId,
148 ClientSendDataInterface& sendDataInterface,
149 SocketFactoryInterface& socketFactory)
152 mMarkerBitmask(PerformanceMarker::FILTERING_DISABLED),
153 mSendDataInterface(sendDataInterface),
154 mSocketFactoryInterface(socketFactory),
156 mConsoleClient(false)
160 NetworkPerformanceClient::~NetworkPerformanceClient()
162 if(mSocket->SocketIsOpen())
164 mSocket->CloseSocket();
166 mSocketFactoryInterface.DestroySocket(mSocket);
169 unsigned int NetworkPerformanceClient::GetId() const
174 SocketInterface& NetworkPerformanceClient::GetSocket()
179 bool NetworkPerformanceClient::WriteSocket(const void* buffer, unsigned int bufferSizeInBytes)
181 return mSocket->Write(buffer, bufferSizeInBytes);
184 bool NetworkPerformanceClient::TransmitMarker(const PerformanceMarker& marker, const char* const description)
186 if(!marker.IsFilterEnabled(mMarkerBitmask))
192 // write out the time stamp
194 double usec = marker.GetTimeStamp().microseconds;
195 int size = snprintf(buffer, sizeof(buffer), "%.6f (seconds), %s\n", usec * MICROSECONDS_TO_SECOND, description);
197 return mSocket->Write(buffer, size);
200 // todo serialize the data
204 void NetworkPerformanceClient::ExitSelect()
206 mSocket->ExitSelect();
209 pthread_t* NetworkPerformanceClient::GetThread()
214 void NetworkPerformanceClient::ProcessCommand(char* buffer, unsigned int bufferSizeInBytes)
216 // if connected via console, then strip off the carriage return, and switch to console mode
217 if(buffer[bufferSizeInBytes - 1] == '\n')
219 buffer[bufferSizeInBytes - 1] = 0;
220 mConsoleClient = true;
222 unsigned int param(0);
223 std::string stringParam;
224 PerformanceProtocol::CommandId commandId(PerformanceProtocol::UNKNOWN_COMMAND);
226 bool ok = PerformanceProtocol::GetCommandId(buffer, bufferSizeInBytes, commandId, param, stringParam);
229 WriteSocket(UNKNOWN_CMD, sizeof(UNKNOWN_CMD));
232 std::string response;
236 case PerformanceProtocol::HELP_MESSAGE:
238 response = PerformanceProtocol::GetHelpMessage();
242 case PerformanceProtocol::ENABLE_TIME_MARKER_BIT_MASK:
244 mMarkerBitmask = static_cast<PerformanceMarker::MarkerFilter>(param);
245 response = "enable time marker ";
249 case PerformanceProtocol::DUMP_SCENE_GRAPH:
251 TriggerOnMainThread(mClientId, mSendDataInterface, [&](AutomationCallback* callback){callback->AssignDumpSceneCommand();});
255 case PerformanceProtocol::SET_PROPERTIES:
257 TriggerOnMainThread(mClientId, mSendDataInterface, [&](AutomationCallback* callback){callback->AssignSetPropertyCommand(stringParam);});
258 response = "Completed";
262 case PerformanceProtocol::CUSTOM_COMMAND:
264 TriggerOnMainThread(mClientId, mSendDataInterface, [&](AutomationCallback* callback){callback->AssignCustomCommand(std::move(stringParam));});
265 response = "Completed";
269 case PerformanceProtocol::LIST_METRICS_AVAILABLE:
270 case PerformanceProtocol::ENABLE_METRIC:
271 case PerformanceProtocol::DISABLE_METRIC:
273 response = "Metrics currently not supported";
278 response = UNKNOWN_CMD;
282 if(!response.empty())
284 // add a carriage return for console clients
289 WriteSocket(response.c_str(), response.length());
293 } // namespace Adaptor
295 } // namespace Internal