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