OTX-Runtime for DotNet  
DiagManager Sample Program

Together with the DiagManager a utility program OpenTestSystem.Otx.DiagManager.Runner.exe to start the DiagManager is delivered, see Installation. With this utility the DiagManager server can be started easily. The program is a console application with command line parameters (arguments). The application will start an OpenTestSystem.Otx.DiagManager.Server inside its own process.

Note: Without the DiagManager no diagnostic communication is possible. For the usage of the OTX-Runtime API a DiagManager must be started explicit. Inside the OTX Development Environment the DiagManager will be started implicit if not already started.

Note: A started DiagManager server can be used by more than one application.

Note: The DiagManager utility program is only a sample application, which shows, how the DiagManager can be used. It shall not be used for productive target environments!

How to start the DiagManager?

The DiagManager utility program must be started with the following arguments. The order of the arguments is not relevant.

Syntax:

OpenTestSystem.Otx.DiagManager.Runner [-options]
Options:
-help
-?
Print this help message. This option must be used
exclusive without any other option, otherwise it will
be ignored.
-port=<PortNumber> [0..1]
Sets the port number for interprocess communication
via sockets. The default value is 8888. If the port
is set explicit, the pipe will be ignored.
-pipe=<PipeName> [0..1]
Sets the pipe name for interprocess communication via
pipes. The default value is "???".
-licenseKey=XXXX-XXXX-XXXX-XXXX-XXXX
Sets a valid license key to active DiagManagerServer. The license
key has the format "XXXX-XXXX-XXXX-XXXX-XXXX". A valid license
key must be available. Please ask the software supplier.
-MaxNumberOfConcurrentComChannels=<MaxNumberOfConcurrentComChannels> [0..1]
Sets maximum number of concurrent ComChannels for the CommandProcessor,
which can be open at the same time. If the number is exceeded,
ComChannels that are no longer used are automatically closed. The
default value is "28".
-DiagServiceHandleMapping=<DiagServiceHandleMapping> [0..1]
Switches the DiagService handle translation of the CommandProcessor
ON or OFF. Possible value are:
[
ON = 1,
OFF = 0
]
The default value is true. DiagService handle mapping is needed
to restore DiagService objects of closed and re-opend ComChannels
when the ComChannels limit is exceeded. The mapping takes time and
can be switched off, if it is not needed.
-kernelType=<KernelTypeEnum> [0..1]
Sets the type of the diagnostic runtime system. Possible
types are:
[
VwMcd = 0,
VwMcdSP = 1
]
The default value is 0 (VwMcd). If the option is not set
to a valid value, the default value will be used.
-kernelPath=<KernelPath> [1]
Sets the path to the binary of the diagnostic runtime
system. If the option is not set to a valid value, the
DiagManager returns an error.
-configPath=<ConfigPath> [1]
Sets the path to the configuration folder of the
diagnostic runtime system. If the option is not set to
a valid value, the DiagManager returns an error.
-pduApi=<D_PDU_VCI_NAME> [0..1]
Sets the PDU-API of the diagnostic runtime system.
-javaVmPath=<JavaVmPath> [0..1]
Sets the path to the Java VM which should be used for
Java Jobs by the diagnostic runtime system. If the
value is not set, the Java VM will be searched inside
the system PATH.
-logPath=<LogPath> [0..1]
Set the log path. The default log path is "[User]/
AppData/Roaming/OpenTestSystem/DiagManager/Tracing/".
-logLevel=<LogLevel> [0..1]
Set the log level (Off = 0, Error = 1, Critical = 2,
Warning = 3, Info = 4, Debug = 5, Trace = 6). The
default log level is 3.
-logConfig=<Filename> [0..1]
Set a logging configuration file. Inside the logging
configuration file the logPath and the logLevel can
be overwritten and extended, e.g. Special logLevel for
one component.
-killAll [0..1]
All started processes at any port or pipe name will
be killed. This option must be used exclusive without
any other option, otherwise it will be ignored. This
option should only be used to get a clean environment.
Please note, that this is not a regular exit!
Return values:
0 If the server was started successfully or all started
processes was killed or the help was displayed.
1 An error occurred. The error message is written into
the output. Possible errors:
- The given port number or pipe name is wrong or already
in use.
- Kernel path is wrong, does not exist or does not contain
a valid diagnostic runtime system.
- Configuration path is wrong, does not exist or does not
contain a valid configuration file. The configuration
file format depends on the selected diagnostic runtime
system.
- Log path is wrong or cannot be accessed.
- Log level is wrong.
- No process to kill exists, see -stopAll option.
- The server cannot be started, because of any other reason.

Examples:

OpenTestSystem.Otx.DiagManager.Runner -port=8888 -licenseKey=XXXX-XXXX-XXXX-XXXX-XXXX -kernelPath="C:/Program Files (x86)/Volkswagen/VW-MCD_14_0_0/MCD-Kernel" -configPath="C:/ProgramData/emotive/VW-MCD/config"

Code Sample

Sample code of the DiagManager utility program.

1 #include "../../diagmanager/OpenTestSystem.OtxDiagManager.Server/ServerFactory.h"
2 #include "../../diagmanager/OpenTestSystem.OtxDiagManager.Server/SocketUtil.h"
3 using namespace OpenTestSystem::Otx::DiagManager::Server;
4 #include "../../diagmanager/OpenTestSystem.OtxDiagManager.CommandProcessor/CommandDispatcher.h"
5 using OpenTestSystem::Otx::DiagManager::CommandProcessor::CommandDispatcher;
6 #include "../../diagmanager/OpenTestSystem.OtxDiagManager.CommandProcessor/CommandProcessor.h"
7 using OpenTestSystem::Otx::DiagManager::CommandProcessor::CommandProcessor;
8 
9 #include "IDiagRuntimeSystem.h"
10 #include "DefaultLogger.h"
11 #include "LogConfigBase.h"
12 #include "LogConfigSingleton.h"
13 #include "CrashHandler.h"
14 #include "CommonHelper.h"
15 #include "Parameter.h"
16 #include "Result.h"
17 #include "ProtoGen/ResultCodesPb.pb.h"
18 #include "ProtoGen/CommandTypesPb.pb.h"
19 #include "ProtoGen/NoneOtxDiagApiCommandsPb.pb.h"
21 
22 #include <filesystem.h>
23 namespace fs = filesystem;
24 
25 #include <string>
26 #include <string.h>
27 
28 #include <fstream>
29 #include <iostream>
30 #include <vector>
31 #define MAX_PATH 256
32 #define LINUX_PIPE_PREFIX "/tmp/OpenTestSystem/pipe/"
33 
34 #ifdef _WIN32
35 #include <Windows.h>
36 #include <process.h>
37 #include <Tlhelp32.h>
38 #include <winbase.h>
39 std::string GetLastErrorAsString();
40 HMODULE DiagRuntimeSystemDLL = NULL;
41 
42 #elif __linux__
43 #include <unistd.h>
44 #include <sys/types.h>
45 #include <dirent.h>
46 #include <signal.h>
47 #ifdef USE_VWMCD_LINK_LIBRARY
48  #ifdef USE_VWMCDSP
49  #include <VwMcdSPDiagRuntimeSystem.h>
50  typedef OpenTestSystem::Otx::DiagManager::DiagRuntimeSystem::VwMcdSPDiagRuntimeSystem VwMcdDiagRuntimeSystem;
51  #else
52  #include <VwMcdDiagRuntimeSystem.h>
53  typedef OpenTestSystem::Otx::DiagManager::DiagRuntimeSystem::VwMcdDiagRuntimeSystem VwMcdDiagRuntimeSystem;
54  #endif
55 #else
56 #include <dlfcn.h>
57 void* handle;
58 #endif // USE_VWMCD_LINK_LIBRARY
59 #endif
60 static std::string fileNameCurrent = "";
61 static bool isDebug = false;
62 
63 static const std::string HelpKey = "-help";
64 static const std::string QuestionMarkKey = "-?";
65 static const std::string PortKey = "-port";
66 static const std::string PipeKey = "-pipe";
67 static const std::string KernelPathKey = "-kernelPath";
68 static const std::string KernelTypeKey = "-kernelType";
69 static const std::string ConfigPathKey = "-configPath";
70 static const std::string JavaVmPathKey = "-javaVmPath";
71 static const std::string LogPathKey = "-logPath";
72 static const std::string LogLevelKey = "-logLevel";
73 static const std::string LogConfigKey = "-logConfig";
74 static const std::string KillAllKey = "-killAll";
75 static const std::string MaxNumberOfConcurrentComChannelsKey = "-MaxNumberOfConcurrentComChannels";
76 static const std::string DiagServiceHandleMappingKey = "-DiagServiceHandleMapping";
77 static const std::string DebugKey = "-debug";
78 static const std::string PduApiKey = "-pduApi";
79 static const std::string LicenseKey = "-licenseKey";
80 
81 enum KernelTypes
82 {
83  VwMcd = 0,
84  VwMcdSP = 1,
85  ProdisMcd = 2 // This may not needed in future.
86 };
87 
88 void SetDefaultArgumentsForRunner(std::map<std::string, std::string>& arguments);
89 void PrintUsage();
90 bool KillAllProccesses();
91 bool UpdateArgumentsByCommandLine(int argc, char** argv, std::map<std::string, std::string>& arguments);
92 bool SetupLogger(std::string& logPath, int logLevel, std::string& logConfig);
93 bool SetupLogger(std::string &logPath, int logLevel, std::string &logConfig, std::string portNumber, std::string pipeName);
94 bool SetupCommandProcessor(CommandProcessor* commandProcessor, std::map<std::string, std::string> & arguments);
95 bool SetPathForVariableEnvironment(std::string kernelPath, std::string configPath, std::string javavmPath);
96 IDiagRuntimeSystem* CreateDiagRuntimeSystemInstance(const char * projectName, const char * vehicleInfo, const char* kernelPath, KernelTypes kernelType = KernelTypes::VwMcd);
97 void PrintDebugTextToConsole(std::string message);
98 std::string RemoveOldMcdHomeFromPathEnv();
99 int SetVariableEnvironment(const std::string& env);
100 void PrintAvaiablePduApi(IDiagRuntimeSystem* drs);
101 void SwitchPduApi(IDiagRuntimeSystem* drs, const std::string& shortName);
102 
103 #ifdef WIN32
104 void Check32And64BitConflict(std::string kernelPath);
105 bool IsWow64();
106 bool Is32BitRunner();
107 bool Is32BitKernelExist(std::string kernelPath);
108 bool Is64BitKernelExist(std::string kernelPath);
109 #endif // WIN32
110 
111 
112 int main(int argc, char** argv)
113 {
114  /*MessageBox(0, NULL, "Diag Runner", MB_OK | MB_ICONQUESTION);*/ // used for debugging
115  ILog log("OpenTestSystem::Otx::DiagManager::Runner");
116  CommandProcessor cmdProcessor;
117  std::string kernelPath, configPath, javavmPath;
118  std::string logPath, logConfig;
119  std::string licenseKey;
120  int kernelType;
121  int logLevel;
122  std::map<std::string, std::string> arguments;
123  SetDefaultArgumentsForRunner(arguments);
124 
125  try {
126  fileNameCurrent = std::string(argv[0]);
127 
128 #ifdef _WIN32
129  fileNameCurrent = fileNameCurrent.substr(fileNameCurrent.find_last_of('\\') + 1);
130 
131 #elif __linux__
132  // fileNameCurrent = fileNameCurrent.substr(fileNameCurrent.find_last_of('\/') + 1); // warning: unknown escape sequence: '\/'
133  fileNameCurrent = fileNameCurrent.substr(fileNameCurrent.find_last_of('/') + 1);
134 #endif
135 
136  if (argc == 1 || (argc == 2 && (argv[1] == HelpKey || argv[1] == QuestionMarkKey)))
137  {
138  PrintUsage();
139  return EXIT_SUCCESS;
140  }
141 
142  PrintDebugTextToConsole("Initializing...");
143  if (argc == 2 && argv[1] == KillAllKey)
144  {
145  PrintDebugTextToConsole("Killing all proccesses...!");
146  KillAllProccesses();
147  PrintDebugTextToConsole("Killed all proccesses!");
148 
149  return EXIT_SUCCESS;
150  }
151 
152  PrintDebugTextToConsole("Updating arguments...!");
153  UpdateArgumentsByCommandLine(argc, argv, arguments);
154 
155  logPath = arguments[LogPathKey];
156  logConfig = arguments[LogConfigKey];
157  logLevel = atoi(arguments[LogLevelKey].c_str());
158 
159  PrintDebugTextToConsole("Setting up the logger...");
160  if (!SetupLogger(logPath, logLevel, logConfig, arguments[PortKey], arguments[PipeKey]))
161  {
162  PrintDebugTextToConsole("Setting up the logger failed!");
163  return EXIT_FAILURE;
164  }
165 
166  kernelPath = arguments[KernelPathKey];
167  configPath = arguments[ConfigPathKey];
168  javavmPath = arguments[JavaVmPathKey];
169  licenseKey = arguments[LicenseKey];
170 
171  PrintDebugTextToConsole("Setting the environment variable path...");
172  if (!SetPathForVariableEnvironment(kernelPath, configPath, javavmPath))
173  {
174  log.Error("Setting the environment variable path failed!");
175  PrintDebugTextToConsole("Setting the environment variable path failed!");
176  return EXIT_FAILURE;
177  }
178 
179  PrintDebugTextToConsole("Setting up the command processor...");
180  if (!SetupCommandProcessor(&cmdProcessor, arguments))
181  {
182  log.Error("Setting up the command processor failed!");
183  PrintDebugTextToConsole("Setting up the command processor failed!");
184  return EXIT_FAILURE;
185  }
186 
187  kernelType = atoi(arguments[KernelTypeKey].c_str());
188 
189  Server* sv = NULL;
190 
191  ServerFactory sFactory;
192  if (!arguments[PortKey].empty())
193  {
194  int port = atoi(arguments[PortKey].c_str());
195 
196  if (port < 1)
197  {
198  log.Error("The port is wrong!!!");
199  PrintDebugTextToConsole("The port is wrong!!!");
200 
201  return EXIT_FAILURE;
202  }
203 
204  if (OpenTestSystem::Otx::DiagManager::Server::SocketUtil::CheckPortInUse(port))
205  {
206  std::string message = "The port " + std::to_string(port) + " is in used.";
207  log.Error(message);
208  PrintDebugTextToConsole(message);
209 
210  return EXIT_FAILURE;
211  }
212 
213  sFactory.SetSocketPort(port);
214 
215  PrintDebugTextToConsole("Creating server with port " + std::to_string(port) + "...");
216  sv = sFactory.Create(ServerType::Socket);
217  }
218  else if (!arguments[PipeKey].empty())
219  {
220  sFactory.SetPipeName(arguments[PipeKey]);
221  PrintDebugTextToConsole("Creating server with pipe " + arguments[PipeKey] + "...");
222  sv = sFactory.Create(ServerType::Pipe);
223  }
224 
225  if (sv)
226  {
227  sv->SetDebugMode(isDebug);
228  sv->SetRuntimeSystemCreationHandler([kernelPath, kernelType, &cmdProcessor, &arguments]() {
229  PrintDebugTextToConsole("Setting up the DiagRuntimeSystem...");
230  IDiagRuntimeSystem* diagRuntime = CreateDiagRuntimeSystemInstance("", "", kernelPath.c_str(), (KernelTypes)kernelType);
231  cmdProcessor.SetRuntimeSystem(diagRuntime);
232  std::string pduApi = arguments[PduApiKey];
233  if (!pduApi.empty())
234  {
235  ::SwitchPduApi(diagRuntime, pduApi);
236  }
237 
238  return diagRuntime;
239  });
240 
241  if (!licenseKey.empty())
242  {
243  sv->SetLicenseKey(licenseKey);
244  }
245  else
246  {
247  PrintDebugTextToConsole("A license key is required to activate DiagManager.");
248  }
249 
250  sv->SetCommandProcessor(&cmdProcessor);
251  PrintDebugTextToConsole("The server is ready.");
252  sv->Start(isDebug);
253  PrintDebugTextToConsole("The server is stopped.");
254 #ifdef _WIN32
255  // Please answer questions if you uncomment below code
256  // Why terminate the process?
257  // Why exit code is FAILURE?
258  //TerminateProcess(GetCurrentProcess(), 1);
259 #elif __linux__
260  //kill(::getpid() , SIGKILL);
261 #endif
262  }
263  }
264  catch (std::exception& ex)
265  {
266  std::string message = "Error: " + std::string(ex.what());
267  log.Error(ex.what());
268  PrintDebugTextToConsole(message);
269  PrintUsage();
270 
271  return EXIT_FAILURE;
272  }
273  return EXIT_SUCCESS;
274 }
275 
276 
277 IDiagRuntimeSystem* CreateDiagRuntimeSystemInstance(const char * projectName, const char * vehicleInfo, const char* kernelPath, KernelTypes kernelType)
278 {
279 #ifdef _WIN32
280  // represents vwmcd version 17.50.x.x
281  std::string DiagRuntimeSystem_17_50_FileName = "OpenTestSystem.Otx.DiagManager.DiagRuntimeSystem.VwMcd_VC142.dll";
282  // represents vwmcdsp version 17.50.0.x.x
283  std::string DiagRuntimeSystemSP_17_50_FileName = "OpenTestSystem.Otx.DiagManager.DiagRuntimeSystem.VwMcdSP_VC142.dll";
284  // represents vwmcd version 9.00.x.x to 14.00.x.x
285  std::string DiagRuntimeSystem_09_00_FileName = "OpenTestSystem.Otx.DiagManager.DiagRuntimeSystem.dll";
286  // represents vwmcdsp version 9.00.x.x to 14.00.x.x
287  std::string DiagRuntimeSystemSP_09_00_FileName = "OpenTestSystem.Otx.DiagManager.DiagRuntimeSystem.VwMcd90SP.dll";
288  // represents Prodis mcd
289  std::string DiagRuntimeSystem_Prodis_FileName = "OpenTestSystem.Otx.DiagManager.DiagRuntimeSystem.ProdisMcd.dll";
290  // represents Actia mcd
291  std::string DiagRuntimeSystem_Actia_FileName = "OpenTestSystem.Otx.DiagManager.DiagRuntimeSystem.ActiaMcd.dll";
292  // represents Siemens mcd
293  std::string DiagRuntimeSystem_Siemens_FileName = "OpenTestSystem.Otx.DiagManager.DiagRuntimeSystem.SiemensMcd.dll";
294 
295  // Default use mcd version 17.50.x.x
296  std::string DiagRuntimeSystemFileName = DiagRuntimeSystem_17_50_FileName;
297  std::string kernelTypeStr = "VwMcd1750";
298  if (kernelType == KernelTypes::VwMcdSP)
299  {
300  kernelTypeStr = "VwMcd1750SP";
301  DiagRuntimeSystemFileName = DiagRuntimeSystemSP_17_50_FileName;
302  }
303 
304  if (fs::exists(std::string(kernelPath) + "/McdKernel_vc120.dll")
305  || fs::exists(std::string(kernelPath) + "/McdKernel_vc120_64.dll")) // check vwmcd 90
306  {
307  if (kernelType == KernelTypes::VwMcdSP)
308  {
309  kernelTypeStr = "VwMcd90SP";
310  DiagRuntimeSystemFileName = DiagRuntimeSystemSP_09_00_FileName;
311  }
312  else
313  {
314  kernelTypeStr = "VwMcd90";
315  DiagRuntimeSystemFileName = DiagRuntimeSystem_09_00_FileName;
316  }
317  }
318  else if (fs::exists(std::string(kernelPath) + "/ProdisMcdKernel_vc142.dll")
319  || fs::exists(std::string(kernelPath) + "/ProdisMcdKernel_vc142_64.dll"))
320  {
321  kernelTypeStr = "ProdisMcd";
322  DiagRuntimeSystemFileName = DiagRuntimeSystem_Prodis_FileName;
323  }
324  else if (fs::exists(std::string(kernelPath) + "/DiagServer.dll"))
325  {
326  kernelTypeStr = "ActiaMcd";
327  DiagRuntimeSystemFileName = DiagRuntimeSystem_Actia_FileName;
328  }
329  else if (fs::exists(std::string(kernelPath) + "/dkernel-core-vw.dll"))
330  {
331  kernelTypeStr = "SiemensMcd";
332  DiagRuntimeSystemFileName = DiagRuntimeSystem_Siemens_FileName;
333  }
334 
335  PrintDebugTextToConsole("The Kernel Type is " + kernelTypeStr + ".");
336  if (DiagRuntimeSystemDLL == NULL)
337  {
338  DiagRuntimeSystemDLL = ::LoadLibrary(DiagRuntimeSystemFileName.c_str());
339  }
340 
341  if (DiagRuntimeSystemDLL == NULL)
342  {
343  std::string errorMessage = GetLastErrorAsString();
344  PrintDebugTextToConsole(errorMessage);
345  Check32And64BitConflict(std::string(kernelPath));
346 
347  return nullptr;
348  }
349  typedef IDiagRuntimeSystem* (__cdecl* typeCreateDiagRuntimeSystem)(const char * projectName, const char * vehicleInfo);
350  typeCreateDiagRuntimeSystem createFunction = reinterpret_cast<typeCreateDiagRuntimeSystem>(::GetProcAddress(DiagRuntimeSystemDLL, "CreateDiagRuntimeSystem"));
351 
352  if (createFunction == nullptr)
353  return nullptr;
354 
355  return createFunction(projectName, vehicleInfo);
356 #elif __linux__
357  #ifdef USE_VWMCD_LINK_LIBRARY
358  return new VwMcdDiagRuntimeSystem(projectName, vehicleInfo);
359  #else
360  if (!handle && kernelType == KernelTypes::VwMcd)
361  {
362  PrintDebugTextToConsole("Kernel Type is VwMcd");
363  handle = dlopen("libOpenTestSystem.Otx.DiagManager.DiagRuntimeSystem.VwMcd.so", RTLD_NOW);
364  }
365  else if (!handle && kernelType == KernelTypes::VwMcdSP)
366  {
367  PrintDebugTextToConsole("Kernel Type is VwMcdSP");
368  handle = dlopen("libOpenTestSystem.Otx.DiagManager.DiagRuntimeSystem.VwMcdSP.so", RTLD_NOW);
369  }
370 
371  if (!handle) {
372  /* fail to load the library */
373  std::cout << dlerror() << std::endl;
374  return nullptr;
375  }
376  typedef IDiagRuntimeSystem* typeCreateDiagRuntimeSystem(const char* projectName, const char* vehicleInfo);
377  typeCreateDiagRuntimeSystem* createFunction = reinterpret_cast<typeCreateDiagRuntimeSystem*>(dlsym(handle, "CreateDiagRuntimeSystem"));
378 
379  if (!createFunction)
380  {
381  dlclose(handle);
382  return nullptr;
383  }
384  IDiagRuntimeSystem* digRuntimeSystem = createFunction(projectName, vehicleInfo);
385  dlclose(handle);
386  createFunction = NULL;
387  return digRuntimeSystem;
388  #endif
389 #endif
390 }
391 
392 #ifdef WIN32
393 void Check32And64BitConflict(std::string kernelPath)
394 {
395  try
396  {
397  bool isRunner32 = Is32BitRunner();
398  bool isKernel32Exist = Is32BitKernelExist(kernelPath);
399  bool isKernel64Exist = Is64BitKernelExist(kernelPath);
400 
401  if (isRunner32 != isKernel32Exist
402  && isRunner32 == isKernel64Exist)
403  {
404  std::string runnerBit = isRunner32 ? "32" : "64";
405  std::string kernelBit = isKernel32Exist ? "32" : "64";
406  std::string errorMessage = "Conflict between DiagManager Runner ("+runnerBit+") and MCD-Kernel ("+kernelBit+").";
407 
408  PrintDebugTextToConsole(errorMessage);
409  }
410  }
411  catch (...) {}
412 }
413 
414 bool IsWow64()
415 {
416  BOOL bIsWow64 = FALSE;
417 
418  typedef BOOL(WINAPI* LPFN_ISWOW64PROCESS) (HANDLE, PBOOL);
419  LPFN_ISWOW64PROCESS fnIsWow64Process;
420  fnIsWow64Process = (LPFN_ISWOW64PROCESS)GetProcAddress(GetModuleHandle(TEXT("kernel32")), "IsWow64Process");
421 
422  if (NULL != fnIsWow64Process)
423  {
424  if (!fnIsWow64Process(GetCurrentProcess(), &bIsWow64))
425  {
426  return "";
427  }
428  }
429 
430  return bIsWow64 == TRUE ? true : false;
431 }
432 
433 bool Is32BitRunner()
434 {
435  SYSTEM_INFO systemInfo = { 0 };
436  GetNativeSystemInfo(&systemInfo);
437 
438  // x86 environment
439  if (systemInfo.wProcessorArchitecture == PROCESSOR_ARCHITECTURE_INTEL)
440  return true;
441 
442  // Check if the process is an x86 process that is running on x64 environment.
443  // IsWow64 returns true if the process is an x86 process
444  return IsWow64();
445 }
446 
447 bool Is32BitKernelExist(std::string kernelPath)
448 {
449  return (fs::exists(std::string(kernelPath) + "/McdKernel_vc120.dll")
450  || fs::exists(std::string(kernelPath) + "/McdKernel_vc142.dll"));
451 }
452 
453 bool Is64BitKernelExist(std::string kernelPath)
454 {
455  return (fs::exists(std::string(kernelPath) + "/McdKernel_vc120_64.dll")
456  || fs::exists(std::string(kernelPath) + "/McdKernel_vc142_64.dll"));
457 }
458 
459 #endif // WIN32
460 
461 std::string GetAppDataPath()
462 {
463  char homedir[MAX_PATH];
464 
465 #ifdef _WIN32
466  snprintf(homedir, MAX_PATH, "%s", getenv("APPDATA"));
467 
468 #elif __ANDROID__
469  snprintf(homedir, MAX_PATH, "%s", getenv("TMPDIR"));
470 
471 #else
472  if (getenv("TEMP") != NULL)
473  {
474  snprintf(homedir, MAX_PATH, "%s", getenv("TEMP"));
475  }
476  else
477  {
478  if (getenv("TMP") != NULL)
479  {
480  snprintf(homedir, MAX_PATH, "%s", getenv("TMP"));
481  }
482  else
483  {
484  if (getenv("TMPDIR") != NULL)
485  {
486  snprintf(homedir, MAX_PATH, "%s", getenv("TMPDIR"));
487  }
488  else
489  {
490  snprintf(homedir, MAX_PATH, "%s", "/tmp");
491  }
492  }
493  }
494 
495 #endif
496  std::string appdata;
497  char* c = strdup(homedir);
498  if (c)
499  {
500  appdata = c;
501  std::free(c);
502  }
503  return appdata;
504 }
505 
506 
507 void SetDefaultArgumentsForRunner(std::map<std::string, std::string>& arguments)
508 {
509  std::string defaultLogPath = fs::path(GetAppDataPath()).append("OpenTestSystem").append(CommonHelper::Get().GetSortVersion()).append("DiagManager").append("Logging").string();
510  arguments[PortKey] = "8888";
511  arguments[PipeKey] = "???";
512  arguments[KernelPathKey] = "";
513  arguments[ConfigPathKey] = "";
514  arguments[JavaVmPathKey] = "";
515  arguments[LogPathKey] = defaultLogPath;
516  arguments[LogLevelKey] = "3";
517  arguments[LogConfigKey] = "";
518  arguments[KernelTypeKey] = KernelTypes::VwMcd;
519  arguments[MaxNumberOfConcurrentComChannelsKey] = "28";
520  arguments[DiagServiceHandleMappingKey] = "1";
521  arguments[PduApiKey] = "";
522  arguments[LicenseKey] = "";
523 }
524 
525 
526 bool UpdateArgumentsByCommandLine(int argc, char** argv, std::map<std::string, std::string>& arguments)
527 {
528  for (int i = 1; i < argc; i++)
529  {
530  std::string argument = argv[i];
531  std::string key;
532  const size_t idx = argument.find('=');
533 
534  if (std::string::npos != idx)
535  {
536  key = argument.substr(0, idx);
537  auto iter = arguments.find(key);
538 
539  if (iter == arguments.end())
540  {
541  PrintUsage();
542 
543  return false;
544  }
545 
546  if (strcmp(key.c_str(), PortKey.c_str()) == 0)
547  {
548  arguments[PipeKey] = "";
549  }
550  else if (strcmp(key.c_str(), PipeKey.c_str()) == 0)
551  {
552  arguments[PortKey] = "";
553  }
554 
555  std::string value = argument.substr(idx + 1, argument.length() - idx);
556  arguments[key] = value;
557  }
558  else if (strcmp(argument.c_str(), DebugKey.c_str()) == 0)
559  {
560  isDebug = true;
561  }
562  }
563 
564  return true;
565 }
566 
567 bool SetupLogger(std::string& logPath, int logLevel, std::string& logConfig)
568 {
569  return SetupLogger(logPath, logLevel, logConfig, "", "");
570 }
571 
572 bool SetupLogger(std::string &logPath, int logLevel, std::string &logConfig, std::string portNumber, std::string pipeName)
573 {
574  char seperated;
575 
576 #ifdef _WIN32
577  seperated = '\\';
578 
579 #elif __linux__
580  seperated = '/';
581 
582 #endif
583  if (!logPath.empty())
584  {
585  try
586  {
587  fs::create_directories(logPath);
588 
589  if (logPath[logPath.length() - 1] != seperated)
590  {
591  logPath.push_back(seperated);
592  }
593 
594  const std::string fileName = "DiagManagerRunner.log";
595  DefaultLogger * log = new DefaultLogger(logPath, fileName);
596  log->SetDiagManagerInfo(portNumber, pipeName);
597  DefaultLogger::Set(log);
598  CrashHandler::InstallCrashHandler(logPath, fileName);
599 
600  }
601  catch (...)
602  {
603  std::cout << std::endl;
604  PrintDebugTextToConsole("Error: The path \"" + logPath + "\" not found!");
605  return false;
606  }
607  }
608 
609  if (logLevel > -1 && logLevel < 7 && logLevel != 3)
610  {
611  LogConfigBase * logConfig = new LogConfigBase();
612  logConfig->SetDefaultLevel((ILog::Level)logLevel);
613  LogConfigSingleton::Set(std::shared_ptr<ILogConfig>(logConfig));
614  }
615 
616  if (!logConfig.empty())
617  {
618  }
619 
620  return true;
621 }
622 
623 bool SetupCommandProcessor(CommandProcessor* commandProcessor, std::map<std::string, std::string>& arguments)
624 {
625  try
626  {
627  int MaxNumberOfConcurrentComChannels = atoi(arguments[MaxNumberOfConcurrentComChannelsKey].c_str());
628  int DiagServiceHandleMapping = atoi(arguments[DiagServiceHandleMappingKey].c_str());
629 
630  // CommandProcessor sets the CommandDispatcher
631  auto commandDispatcher = std::make_unique<CommandDispatcher>();
632  auto* comChannelManager = commandDispatcher->GetComChannelManager();
633  comChannelManager->SetMaxChannels(MaxNumberOfConcurrentComChannels);
634  commandProcessor->SetCommandDispatcher(std::move(commandDispatcher));
635  PrintDebugTextToConsole("MaxNumberOfConcurrentComChannels: " + std::to_string(MaxNumberOfConcurrentComChannels));
636 
637  // CommandProcessor sets the DiagServiceHandleMapping
638  if (DiagServiceHandleMapping == 1)
639  {
640  commandProcessor->StartDiagServiceHandleMapping();
641  }
642  PrintDebugTextToConsole("DiagServiceHandleMapping: " + std::string(DiagServiceHandleMapping ? "on" : "off"));
643  }
644  catch (std::exception& e)
645  {
646  PrintDebugTextToConsole(e.what());
647  return false;
648  }
649  return true;
650 }
651 
652 int SetVariableEnvironment(const std::string& env)
653 {
654  char* envString = new char[env.length() + 1];
655  strncpy(envString, env.c_str(), env.length());
656  envString[env.length()] = '\0'; // the '\0' at the end of the string when it initializes the array
657 
658  size_t pos = env.find('=');
659  std::string envName = env.substr(0, pos);
660  std::string envPath = env.substr(pos + 1, env.length());
661 
662  std::string textConsole = "Setting the environment variable \"" +
663  envName +
664  "\" with the path \"" +
665  envPath + "\"";
666 
667  PrintDebugTextToConsole(textConsole);
668  int ret = putenv(envString);
669 
670  textConsole = "The environment variable \"" +
671  envName +
672  "\" path is set to \"" +
673  envPath + "\"";
674  PrintDebugTextToConsole(textConsole);
675 
676  delete[] envString;
677 
678  return ret;
679 }
680 
681 bool SetPathForVariableEnvironment(std::string kernelPath, std::string configPath, std::string javavmPath)
682 {
683  std::string seperated = "";
684 
685 #ifdef _WIN32
686  seperated = ";";
687 
688 #elif __linux__
689  seperated = ":";
690 
691 #endif
692  if (!kernelPath.empty())
693  {
694  if (!fs::exists(kernelPath))
695  {
696  PrintDebugTextToConsole("Error: The path \"" + kernelPath + "\" not found!");
697  return false;
698  }
699 
700  //std::string pathEnvs = RemoveOldMcdHomeFromPathEnv();
701  PrintDebugTextToConsole("Find PATH environment");
702  std::string pathEnvs = getenv("PATH");
703  std::string home;
704  PrintDebugTextToConsole("Set kernelPath to environment system");
705 
706  if (fs::exists(std::string(kernelPath) + "/ProdisMcdKernel_vc142.dll")
707  || fs::exists(std::string(kernelPath) + "/ProdisMcdKernel_vc142_64.dll"))
708  {
709  home = "PRODIS_MCD_HOME=" + kernelPath;
710  }
711  else if (fs::exists(std::string(kernelPath) + "/dkernel-core-vw.dll"))
712  {
713  home = "SIEMENS_MCD_HOME=" + kernelPath;
714  }
715  else {
716  home = "VW_MCD_HOME=" + kernelPath;
717  }
718  SetVariableEnvironment(home);
719 
720  std::string newPath(kernelPath);
721  newPath.append(seperated);
722  newPath.append(pathEnvs);
723  std::string path = "PATH=" + newPath;
724  SetVariableEnvironment(path);
725  }
726 
727  if (!configPath.empty())
728  {
729  if (!fs::exists(configPath))
730  {
731  PrintDebugTextToConsole("Error: The path \"" + configPath + "\" not found!");
732  return false;
733  }
734 
735  PrintDebugTextToConsole("Set configPath to environment system");
736  std::string config ;
737  if (fs::exists(std::string(kernelPath) + "/ProdisMcdKernel_vc142.dll")
738  || fs::exists(std::string(kernelPath) + "/ProdisMcdKernel_vc142_64.dll"))
739  {
740  config = "PRODIS_MCD_CONFIG=" + configPath;
741  }
742  else if (fs::exists(std::string(kernelPath) + "/dkernel-core-vw.dll"))
743  {
744  config = "SIEMENS_MCD_CONFIG=" + configPath;
745  }
746  else {
747  config = "VW_MCD_CONFIG=" + configPath;
748  }
749  SetVariableEnvironment(config);
750  }
751 
752  if (!javavmPath.empty())
753  {
754  if (!fs::exists(javavmPath))
755  {
756  PrintDebugTextToConsole("Error: The path \"" + javavmPath + "\" not found!");
757 
758  return false;
759  }
760 
761  std::string pathEnvs = getenv("PATH");
762 
763  std::string newPath(javavmPath);
764  newPath.append(seperated);
765  newPath.append(pathEnvs);
766  std::string path = "PATH=" + newPath;
767  SetVariableEnvironment(path.c_str());
768  }
769 
770  return true;
771 }
772 
773 // Gap/Lack #12995
774 std::string RemoveOldMcdHomeFromPathEnv()
775 {
776  std::string oldMcdHomePath = getenv("VW_MCD_HOME");
777  std::string pathEnvs = getenv("PATH");
778  std::size_t pos = pathEnvs.find(oldMcdHomePath);
779  if (pos != std::string::npos)
780  {
781  pathEnvs.erase(pos, oldMcdHomePath.length());
782  }
783 
784  return pathEnvs;
785 }
786 
787 void PrintAvaiablePduApi(IDiagRuntimeSystem* drs)
788 {
789  if (!isDebug) return;
790 
791  std::cout << "Possible PDU-API name are: [" << std::endl;
792  Command cmd;
793  cmd.SetCommandType(CommandTypesPb::GetPduApiNameList);
794 
795  std::shared_ptr<Parameter> pHandle = std::make_shared<Parameter>();
796  cmd.AddParameter(1, pHandle);
797 
798  Result* result = drs->Execute(cmd);
799 
800  int resuldCode = result->GetResultCode();
801  if (resuldCode == ResultCodesPb::Success)
802  {
803  auto pduNameList =result->GetParameter(1)->GetValueAsList();
804  for (Parameter pduNameParam : pduNameList) {
805  std::cout << " " << pduNameParam.GetValueAsString() << std::endl;
806  }
807  }
808  std::cout << "]" << std::endl;
809  delete result;
810 }
811 
812 void SwitchPduApi(IDiagRuntimeSystem* drs, const std::string& shortName)
813 {
814  PrintDebugTextToConsole("Switch to '" + shortName + "' PDU-API");
815  std::shared_ptr<SwitchPduApiPb> pb = std::make_shared<SwitchPduApiPb>();
816  pb->set_pduapishortname(shortName);
817 
818  Command cmd;
819  cmd.SetCommandType(CommandTypesPb::SwitchPduApi);
820 
821  std::string bytes;
822  pb->SerializeToString(&bytes);
823 
824  std::shared_ptr<Parameter> pHandle = std::make_shared<Parameter>();
825  pHandle->SetBytesValue(bytes);
826  cmd.AddParameter(1, pHandle);
827 
828  Result* result = drs->Execute(cmd);
829 
830  int resuldCode = result->GetResultCode();
831  if (resuldCode == ResultCodesPb::Failed)
832  {
833  int errorcode;
834  ExceptionTypesPb type;
835  std::string message;
836  result->GetExceptionData(errorcode, type, message);
837 
838  delete result;
839  PrintAvaiablePduApi(drs);
840  throw std::runtime_error(message.c_str());
841  }
842  delete result;
843 }
844 
845 #ifdef __linux__
846 std::vector<pid_t> getAllProcIdByName(std::string procName)
847 {
848  std::vector<pid_t> listProcesses;
849  // Open the /proc directory
850  DIR *dp = opendir("/proc");
851 
852  if (dp != NULL)
853  {
854  // Enumerate all entries in directory until process found
855  //struct dirent *dirp;
856 
857  while (struct dirent* dirp = readdir(dp))
858  {
859  // Skip non-numeric entries
860  int id = atoi(dirp->d_name);
861 
862  if (id > 0)
863  {
864  // Read contents of virtual /proc/{pid}/cmdline file
865  std::string cmdPath = std::string("/proc/") + dirp->d_name + "/cmdline";
866  std::ifstream cmdFile(cmdPath.c_str());
867  std::string cmdLine;
868  std::getline(cmdFile, cmdLine);
869 
870  if (!cmdLine.empty())
871  {
872  // Keep first cmdline item which contains the program path
873  size_t pos = cmdLine.find('\0');
874 
875  if (pos != std::string::npos)
876  {
877  cmdLine = cmdLine.substr(0, pos);
878  }
879 
880  // Keep program name only, removing the path
881  pos = cmdLine.rfind('/');
882 
883  if (pos != std::string::npos)
884  {
885  cmdLine = cmdLine.substr(pos + 1);
886  }
887 
888  // Compare against requested process name
889  if (procName == cmdLine)
890  {
891  listProcesses.push_back(id);
892  }
893  }
894  }
895  }
896  }
897 
898  closedir(dp);
899 
900  return listProcesses;
901 }
902 #endif
903 
904 bool KillAllProccesses()
905 {
906  bool result = false;
907 
908 #ifdef _WIN32
909  DWORD processCurrent = GetCurrentProcessId();
910  HANDLE snap = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
911  PROCESSENTRY32 pe32;
912 
913  pe32.dwSize = sizeof(PROCESSENTRY32);
914 
915  if (!Process32First(snap, &pe32))
916  {
917  CloseHandle(snap);
918 
919  return false;
920  }
921 
922  do
923  {
924  if (processCurrent != pe32.th32ProcessID && strcmp(pe32.szExeFile, fileNameCurrent.c_str()) == 0)
925  {
926  HANDLE hProcess = OpenProcess(PROCESS_TERMINATE, FALSE, pe32.th32ProcessID);
927 
928  if (hProcess == NULL)
929  {
930  continue;
931  }
932 
933  result = TerminateProcess(hProcess, 1);
934 
935  CloseHandle(hProcess);
936  }
937  } while (Process32Next(snap, &pe32));
938 
939  CloseHandle(snap);
940 
941 #elif __linux__
942  pid_t processCurrent = ::getpid();
943  std::vector<pid_t> processesFound = getAllProcIdByName(fileNameCurrent);
944 
945  if (processesFound.size() > 1)
946  {
947  for (auto process = processesFound.begin(); process != processesFound.end(); ++process)
948  {
949  if (*process != processCurrent && *process)
950  {
951  kill(*process, SIGTERM);
952  }
953  }
954  }
955 
956  try
957  {
958  std::string directory = std::string(LINUX_PIPE_PREFIX);
959  if (fs::exists(directory))
960  {
961  fs::remove_all(directory);
962  }
963  }
964  catch (std::exception& e)
965  {
966  }
967 #endif
968 
969  return result;
970 }
971 
972 
973 #ifdef _WIN32
974 std::string GetLastErrorAsString()
975 {
976  //Get the error message ID, if any.
977  DWORD errorMessageID = ::GetLastError();
978  if (errorMessageID == 0) {
979  return std::string(); //No error message has been recorded
980  }
981 
982  LPSTR messageBuffer = nullptr;
983 
984  //Ask Win32 to give us the string version of that message ID.
985  //The parameters we pass in, tell Win32 to create the buffer that holds the message for us (because we don't yet know how long the message string will be).
986  size_t size = FormatMessageA(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS,
987  NULL, errorMessageID, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), (LPSTR)&messageBuffer, 0, NULL);
988 
989  //Copy the error message into a std::string.
990  std::string message(messageBuffer, size);
991 
992  //Free the Win32's string's buffer.
993  LocalFree(messageBuffer);
994 
995  return message;
996 }
997 #endif
998 void PrintUsage()
999 {
1000  std::cout << "" << std::endl;
1001  std::cout << "Creates and starts a new process with the OTX DiagManager server." << std::endl;
1002  std::cout << "" << std::endl;
1003  std::cout << "The OTX DiagManager (short DiagManager) is a software component between" << std::endl;
1004  std::cout << "diagnostic applications and various, interchangeable diagnostic runtime" << std::endl;
1005  std::cout << "systems. The DiagManager is part of the OTX-Runtime API, but it can also" << std::endl;
1006  std::cout << "be used stand-alone." << std::endl;
1007  std::cout << "" << std::endl;
1008  std::cout << "OpenTestSystem.Otx.DiagManager.Runner [-options]" << std::endl;
1009  std::cout << "" << std::endl;
1010  std::cout << " -help" << std::endl;
1011  std::cout << " -?" << std::endl;
1012  std::cout << " Print this help message. This option must be used" << std::endl;
1013  std::cout << " exclusive without any other option, otherwise it will" << std::endl;
1014  std::cout << " be ignored." << std::endl;
1015  std::cout << "" << std::endl;
1016  std::cout << " -debug" << std::endl;
1017  std::cout << " If set, debug messages will be written into the" << std::endl;
1018  std::cout << " standard i/o." << std::endl;
1019  std::cout << "" << std::endl;
1020  std::cout << " -port=<PortNumber> [0..1]" << std::endl;
1021  std::cout << " Sets the port number for interprocess communication" << std::endl;
1022  std::cout << " via sockets. The default value is 8888. If the port" << std::endl;
1023  std::cout << " is set explicit, the pipe will be ignored." << std::endl;
1024  std::cout << "" << std::endl;
1025  std::cout << " -pipe=<PipeName> [0..1]" << std::endl;
1026  std::cout << " Sets the pipe name for interprocess communication via" << std::endl;
1027  std::cout << " pipes. The default value is \"???\"." << std::endl;
1028  std::cout << "" << std::endl;
1029  std::cout << " -MaxNumberOfConcurrentComChannels=<MaxNumberOfConcurrentComChannels> [0..1]" << std::endl;
1030  std::cout << " Sets max number of concurrent ComChannels for the CommandProcessor." << std::endl;
1031  std::cout << " Sets maximum number of concurrent ComChannels for the CommandProcessor," << std::endl;
1032  std::cout << " which can be open at the same time. If the number is exceeded," << std::endl;
1033  std::cout << " ComChannels that are no longer used are automatically closed. The" << std::endl;
1034  std::cout << " default value is \"28\"." << std::endl;
1035  std::cout << "" << std::endl;
1036  std::cout << " -DiagServiceHandleMapping=<DiagServiceHandleMapping> [0..1]" << std::endl;
1037  std::cout << " Switches the DiagService handle translation of the CommandProcessor" << std::endl;
1038  std::cout << " ON or OFF. Possible value are:" << std::endl;
1039  std::cout << " [" << std::endl;
1040  std::cout << " OFF = 0," << std::endl;
1041  std::cout << " ON = 1" << std::endl;
1042  std::cout << " ]" << std::endl;
1043  std::cout << " The default value is ON. DiagService handle mapping is needed" << std::endl;
1044  std::cout << " to restore DiagService objects of closed and re-opend ComChannels" << std::endl;
1045  std::cout << " when the ComChannels limit is exceeded. The mapping takes time and" << std::endl;
1046  std::cout << " can be switched off, if it is not needed." << std::endl;
1047  std::cout << "" << std::endl;
1048  std::cout << " -kernelType=<KernelTypeEnum> [0..1]" << std::endl;
1049  std::cout << " Sets the type of the diagnostic runtime system. Possible" << std::endl;
1050  std::cout << " types are:" << std::endl;
1051  std::cout << " [" << std::endl;
1052  std::cout << " VwMcd = 0," << std::endl;
1053  std::cout << " VwMcdSP = 1," << std::endl;
1054  std::cout << " ProdisMCD = 2" << std::endl;
1055  std::cout << " ]" << std::endl;
1056  std::cout << " The default value is 0 (VwMcd). If the option is not set" << std::endl;
1057  std::cout << " to a valid value, the default value will be used." << std::endl;
1058  std::cout << "" << std::endl;
1059  std::cout << " -kernelPath=<KernelPath> [1]" << std::endl;
1060  std::cout << " Sets the path to the binary of the diagnostic runtime" << std::endl;
1061  std::cout << " system. If the option is not set to a valid value, the" << std::endl;
1062  std::cout << " DiagManager returns an error." << std::endl;
1063  std::cout << "" << std::endl;
1064  std::cout << " -configPath=<ConfigPath> [1]" << std::endl;
1065  std::cout << " Sets the path to the configuration folder of the" << std::endl;
1066  std::cout << " diagnostic runtime system. If the option is not set to" << std::endl;
1067  std::cout << " a valid value, the DiagManager returns an error." << std::endl;
1068  std::cout << "" << std::endl;
1069  std::cout << " -pduApi=<D_PDU_VCI_NAME> [0..1]" << std::endl;
1070  std::cout << " Sets the PDU-API of the diagnostic runtime system." << std::endl;
1071  std::cout << "" << std::endl;
1072  std::cout << " -javaVmPath=<JavaVmPath> [0..1]" << std::endl;
1073  std::cout << " Sets the path to the Java VM which should be used for" << std::endl;
1074  std::cout << " Java Jobs by the diagnostic runtime system. If the" << std::endl;
1075  std::cout << " value is not set, the Java VM will be searched inside" << std::endl;
1076  std::cout << " the system PATH." << std::endl;
1077  std::cout << "" << std::endl;
1078  std::cout << " -logPath=<LogPath> [0..1]" << std::endl;
1079  std::cout << " Sets the log path. The default log path is \"[User]/" << std::endl;
1080  std::cout << " AppData/Roaming/OpenTestSystem/[Version]/DiagManager/Logging/\"." << std::endl;
1081  std::cout << "" << std::endl;
1082  std::cout << " -logLevel=<LogLevel> [0..1]" << std::endl;
1083  std::cout << " Sets the log level (Off = 0, Error = 1, Critical = 2," << std::endl;
1084  std::cout << " Warning = 3, Info = 4, Debug = 5, Trace = 6). The" << std::endl;
1085  std::cout << " default log level is 3." << std::endl;
1086  std::cout << "" << std::endl;
1087  std::cout << " -licenseKey=<LicenseKey> [1]" << std::endl;
1088  std::cout << " Sets the license key to activate DiagManager" << std::endl;
1089  std::cout << " If the option is not set to a valid value, the" << std::endl;
1090  std::cout << " DiagManager cannot be activated." << std::endl;
1091  std::cout << "" << std::endl;
1092  std::cout << " -killAll [0..1]" << std::endl;
1093  std::cout << " All started processes at any port or pipe name will" << std::endl;
1094  std::cout << " be killed. This option must be used exclusively without" << std::endl;
1095  std::cout << " any other option, otherwise it will be ignored. This" << std::endl;
1096  std::cout << " option should only be used to get a clean environment." << std::endl;
1097  std::cout << " Please note, that this is not a regular exit!" << std::endl;
1098  std::cout << "" << std::endl;
1099  std::cout << "Return values:" << std::endl;
1100  std::cout << "" << std::endl;
1101  std::cout << " 0 If the server was started successfully or all started" << std::endl;
1102  std::cout << " processes was killed or the help was displayed." << std::endl;
1103  std::cout << " 1 An error occurred. The error message is written into" << std::endl;
1104  std::cout << " the output. Possible errors:" << std::endl;
1105  std::cout << " - The given port number or the pipe name is wrong or already" << std::endl;
1106  std::cout << " in use." << std::endl;
1107  std::cout << " - The Kernel path is wrong, does not exist or does not contain" << std::endl;
1108  std::cout << " a valid diagnostic runtime system." << std::endl;
1109  std::cout << " - The Configuration path is wrong, does not exist or does not" << std::endl;
1110  std::cout << " contain a valid configuration file. The configuration" << std::endl;
1111  std::cout << " file format depends on the selected diagnostic runtime" << std::endl;
1112  std::cout << " system." << std::endl;
1113  std::cout << " - The Log path is wrong or cannot be accessed." << std::endl;
1114  std::cout << " - The Log level is wrong." << std::endl;
1115  std::cout << " - No process to kill exists, see -stopAll option." << std::endl;
1116  std::cout << " - The server cannot be started because of any other reason." << std::endl;
1117  std::cout << "" << std::endl;
1118 }
1119 
1120 void PrintDebugTextToConsole(std::string message)
1121 {
1122  if (isDebug)
1123  {
1124  std::cout << message << std::endl;
1125  }
1126 }
Namespace containing all common methods for the DiagManage