OTX-Runtime for C++  
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"
4 #include "../../diagmanager/OpenTestSystem.OtxDiagManager.CommandProcessor/CommandDispatcher.h"
6 #include "../../diagmanager/OpenTestSystem.OtxDiagManager.CommandProcessor/CommandProcessor.h"
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 defined(__linux__) || defined(__QNXNTO__)
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>
51  #else
52  #include <VwMcdDiagRuntimeSystem.h>
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 defined(__linux__) || defined(__QNXNTO__)
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 
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 defined(__linux__) || defined(__QNXNTO__)
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 defined(__linux__) || defined(__QNXNTO__)
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 #else
390  return nullptr;
391 #endif
392 }
393 
394 #ifdef WIN32
395 void Check32And64BitConflict(std::string kernelPath)
396 {
397  try
398  {
399  bool isRunner32 = Is32BitRunner();
400  bool isKernel32Exist = Is32BitKernelExist(kernelPath);
401  bool isKernel64Exist = Is64BitKernelExist(kernelPath);
402 
403  if (isRunner32 != isKernel32Exist
404  && isRunner32 == isKernel64Exist)
405  {
406  std::string runnerBit = isRunner32 ? "32" : "64";
407  std::string kernelBit = isKernel32Exist ? "32" : "64";
408  std::string errorMessage = "Conflict between DiagManager Runner ("+runnerBit+") and MCD-Kernel ("+kernelBit+").";
409 
410  PrintDebugTextToConsole(errorMessage);
411  }
412  }
413  catch (...) {}
414 }
415 
416 bool IsWow64()
417 {
418  BOOL bIsWow64 = FALSE;
419 
420  typedef BOOL(WINAPI* LPFN_ISWOW64PROCESS) (HANDLE, PBOOL);
421  LPFN_ISWOW64PROCESS fnIsWow64Process;
422  fnIsWow64Process = (LPFN_ISWOW64PROCESS)GetProcAddress(GetModuleHandle(TEXT("kernel32")), "IsWow64Process");
423 
424  if (NULL != fnIsWow64Process)
425  {
426  if (!fnIsWow64Process(GetCurrentProcess(), &bIsWow64))
427  {
428  return "";
429  }
430  }
431 
432  return bIsWow64 == TRUE ? true : false;
433 }
434 
435 bool Is32BitRunner()
436 {
437  SYSTEM_INFO systemInfo = { 0 };
438  GetNativeSystemInfo(&systemInfo);
439 
440  // x86 environment
441  if (systemInfo.wProcessorArchitecture == PROCESSOR_ARCHITECTURE_INTEL)
442  return true;
443 
444  // Check if the process is an x86 process that is running on x64 environment.
445  // IsWow64 returns true if the process is an x86 process
446  return IsWow64();
447 }
448 
449 bool Is32BitKernelExist(std::string kernelPath)
450 {
451  return (fs::exists(std::string(kernelPath) + "/McdKernel_vc120.dll")
452  || fs::exists(std::string(kernelPath) + "/McdKernel_vc142.dll"));
453 }
454 
455 bool Is64BitKernelExist(std::string kernelPath)
456 {
457  return (fs::exists(std::string(kernelPath) + "/McdKernel_vc120_64.dll")
458  || fs::exists(std::string(kernelPath) + "/McdKernel_vc142_64.dll"));
459 }
460 
461 #endif // WIN32
462 
463 std::string GetAppDataPath()
464 {
465  char homedir[MAX_PATH] = { '\0' };
466 
467 #ifdef _WIN32
468  snprintf(homedir, MAX_PATH, "%s", getenv("APPDATA"));
469 
470 #elif __ANDROID__
471  snprintf(homedir, MAX_PATH, "%s", getenv("TMPDIR"));
472 
473 #else
474  if (getenv("TEMP") != NULL)
475  {
476  snprintf(homedir, MAX_PATH, "%s", getenv("TEMP"));
477  }
478  else
479  {
480  if (getenv("TMP") != NULL)
481  {
482  snprintf(homedir, MAX_PATH, "%s", getenv("TMP"));
483  }
484  else
485  {
486  if (getenv("TMPDIR") != NULL)
487  {
488  snprintf(homedir, MAX_PATH, "%s", getenv("TMPDIR"));
489  }
490  else
491  {
492  snprintf(homedir, MAX_PATH, "%s", "/tmp");
493  }
494  }
495  }
496 
497 #endif
498  std::string appdata = homedir;
499  return appdata;
500 }
501 
502 
503 void SetDefaultArgumentsForRunner(std::map<std::string, std::string>& arguments)
504 {
505  std::string defaultLogPath = fs::path(GetAppDataPath()).append("OpenTestSystem").append(CommonHelper::Get().GetSortVersion()).append("DiagManager").append("Logging").string();
506  arguments[PortKey] = "8888";
507  arguments[PipeKey] = "???";
508  arguments[KernelPathKey] = "";
509  arguments[ConfigPathKey] = "";
510  arguments[JavaVmPathKey] = "";
511  arguments[LogPathKey] = defaultLogPath;
512  arguments[LogLevelKey] = "3";
513  arguments[LogConfigKey] = "";
514  arguments[KernelTypeKey] = KernelTypes::VwMcd;
515  arguments[MaxNumberOfConcurrentComChannelsKey] = "28";
516  arguments[DiagServiceHandleMappingKey] = "1";
517  arguments[PduApiKey] = "";
518  arguments[LicenseKey] = "";
519 }
520 
521 
522 bool UpdateArgumentsByCommandLine(int argc, char** argv, std::map<std::string, std::string>& arguments)
523 {
524  for (int i = 1; i < argc; i++)
525  {
526  std::string argument = argv[i];
527  std::string key;
528  const size_t idx = argument.find('=');
529 
530  if (std::string::npos != idx)
531  {
532  key = argument.substr(0, idx);
533  auto iter = arguments.find(key);
534 
535  if (iter == arguments.end())
536  {
537  PrintUsage();
538 
539  return false;
540  }
541 
542  if (strcmp(key.c_str(), PortKey.c_str()) == 0)
543  {
544  arguments[PipeKey] = "";
545  }
546  else if (strcmp(key.c_str(), PipeKey.c_str()) == 0)
547  {
548  arguments[PortKey] = "";
549  }
550 
551  std::string value = argument.substr(idx + 1, argument.length() - idx);
552  arguments[key] = value;
553  }
554  else if (strcmp(argument.c_str(), DebugKey.c_str()) == 0)
555  {
556  isDebug = true;
557  }
558  }
559 
560  return true;
561 }
562 
563 bool SetupLogger(std::string& logPath, int logLevel, std::string& logConfig)
564 {
565  return SetupLogger(logPath, logLevel, logConfig, "", "");
566 }
567 
568 bool SetupLogger(std::string &logPath, int logLevel, std::string &logConfig, std::string portNumber, std::string pipeName)
569 {
570  char seperated;
571 
572 #ifdef _WIN32
573  seperated = '\\';
574 
575 #elif defined(__linux__) || defined(__QNXNTO__)
576  seperated = '/';
577 
578 #endif
579  if (!logPath.empty())
580  {
581  try
582  {
583  fs::create_directories(logPath);
584 
585  if (logPath[logPath.length() - 1] != seperated)
586  {
587  logPath.push_back(seperated);
588  }
589 
590  const std::string fileName = "DiagManagerRunner.log";
591  DefaultLogger * log = new DefaultLogger(logPath, fileName);
592  log->SetDiagManagerInfo(portNumber, pipeName);
593  DefaultLogger::Set(log);
594  CrashHandler::InstallCrashHandler(logPath, fileName);
595 
596  }
597  catch (...)
598  {
599  std::cout << std::endl;
600  PrintDebugTextToConsole("Error: The path \"" + logPath + "\" not found!");
601  return false;
602  }
603  }
604 
605  if (logLevel > -1 && logLevel < 7 && logLevel != 3)
606  {
607  LogConfigBase * logConfig = new LogConfigBase();
608  logConfig->SetDefaultLevel((ILog::Level)logLevel);
609  LogConfigSingleton::Set(std::shared_ptr<ILogConfig>(logConfig));
610  }
611 
612  if (!logConfig.empty())
613  {
614  }
615 
616  return true;
617 }
618 
619 bool SetupCommandProcessor(CommandProcessor* commandProcessor, std::map<std::string, std::string>& arguments)
620 {
621  try
622  {
623  int MaxNumberOfConcurrentComChannels = atoi(arguments[MaxNumberOfConcurrentComChannelsKey].c_str());
624  int DiagServiceHandleMapping = atoi(arguments[DiagServiceHandleMappingKey].c_str());
625 
626  // CommandProcessor sets the CommandDispatcher
627  auto commandDispatcher = std::make_unique<CommandDispatcher>();
628  auto* comChannelManager = commandDispatcher->GetComChannelManager();
629  comChannelManager->SetMaxChannels(MaxNumberOfConcurrentComChannels);
630  commandProcessor->SetCommandDispatcher(std::move(commandDispatcher));
631  PrintDebugTextToConsole("MaxNumberOfConcurrentComChannels: " + std::to_string(MaxNumberOfConcurrentComChannels));
632 
633  // CommandProcessor sets the DiagServiceHandleMapping
634  if (DiagServiceHandleMapping == 1)
635  {
636  commandProcessor->StartDiagServiceHandleMapping();
637  }
638  PrintDebugTextToConsole("DiagServiceHandleMapping: " + std::string(DiagServiceHandleMapping ? "on" : "off"));
639  }
640  catch (std::exception& e)
641  {
642  PrintDebugTextToConsole(e.what());
643  return false;
644  }
645  return true;
646 }
647 
648 int SetVariableEnvironment(const std::string& env)
649 {
650  char* envString = new char[env.length() + 1];
651  strncpy(envString, env.c_str(), env.length());
652  envString[env.length()] = '\0'; // the '\0' at the end of the string when it initializes the array
653 
654  size_t pos = env.find('=');
655  std::string envName = env.substr(0, pos);
656  std::string envPath = env.substr(pos + 1, env.length());
657 
658  std::string textConsole = "Setting the environment variable \"" +
659  envName +
660  "\" with the path \"" +
661  envPath + "\"";
662 
663  PrintDebugTextToConsole(textConsole);
664  int ret = putenv(envString);
665 
666  textConsole = "The environment variable \"" +
667  envName +
668  "\" path is set to \"" +
669  envPath + "\"";
670  PrintDebugTextToConsole(textConsole);
671 
672  delete[] envString;
673 
674  return ret;
675 }
676 
677 bool SetPathForVariableEnvironment(std::string kernelPath, std::string configPath, std::string javavmPath)
678 {
679  std::string seperated = "";
680 
681 #ifdef _WIN32
682  seperated = ";";
683 
684 #elif defined(__linux__) || defined(__QNXNTO__)
685  seperated = ":";
686 
687 #endif
688  if (!kernelPath.empty())
689  {
690  if (!fs::exists(kernelPath))
691  {
692  PrintDebugTextToConsole("Error: The path \"" + kernelPath + "\" not found!");
693  return false;
694  }
695 
696  //std::string pathEnvs = RemoveOldMcdHomeFromPathEnv();
697  PrintDebugTextToConsole("Find PATH environment");
698  std::string pathEnvs = getenv("PATH");
699  std::string home;
700  PrintDebugTextToConsole("Set kernelPath to environment system");
701 
702  if (fs::exists(std::string(kernelPath) + "/ProdisMcdKernel_vc142.dll")
703  || fs::exists(std::string(kernelPath) + "/ProdisMcdKernel_vc142_64.dll"))
704  {
705  home = "PRODIS_MCD_HOME=" + kernelPath;
706  }
707  else if (fs::exists(std::string(kernelPath) + "/dkernel-core-vw.dll"))
708  {
709  home = "SIEMENS_MCD_HOME=" + kernelPath;
710  }
711  else {
712  home = "VW_MCD_HOME=" + kernelPath;
713  }
714  SetVariableEnvironment(home);
715 
716  std::string newPath(kernelPath);
717  newPath.append(seperated);
718  newPath.append(pathEnvs);
719  std::string path = "PATH=" + newPath;
720  SetVariableEnvironment(path);
721  }
722 
723  if (!configPath.empty())
724  {
725  if (!fs::exists(configPath))
726  {
727  PrintDebugTextToConsole("Error: The path \"" + configPath + "\" not found!");
728  return false;
729  }
730 
731  PrintDebugTextToConsole("Set configPath to environment system");
732  std::string config ;
733  if (fs::exists(std::string(kernelPath) + "/ProdisMcdKernel_vc142.dll")
734  || fs::exists(std::string(kernelPath) + "/ProdisMcdKernel_vc142_64.dll"))
735  {
736  config = "PRODIS_MCD_CONFIG=" + configPath;
737  }
738  else if (fs::exists(std::string(kernelPath) + "/dkernel-core-vw.dll"))
739  {
740  config = "SIEMENS_MCD_CONFIG=" + configPath;
741  }
742  else {
743  config = "VW_MCD_CONFIG=" + configPath;
744  }
745  SetVariableEnvironment(config);
746  }
747 
748  if (!javavmPath.empty())
749  {
750  if (!fs::exists(javavmPath))
751  {
752  PrintDebugTextToConsole("Error: The path \"" + javavmPath + "\" not found!");
753 
754  return false;
755  }
756 
757  std::string pathEnvs = getenv("PATH");
758 
759  std::string newPath(javavmPath);
760  newPath.append(seperated);
761  newPath.append(pathEnvs);
762  std::string path = "PATH=" + newPath;
763  SetVariableEnvironment(path.c_str());
764  }
765 
766  return true;
767 }
768 
769 // Gap/Lack #12995
770 std::string RemoveOldMcdHomeFromPathEnv()
771 {
772  std::string oldMcdHomePath = getenv("VW_MCD_HOME");
773  std::string pathEnvs = getenv("PATH");
774  std::size_t pos = pathEnvs.find(oldMcdHomePath);
775  if (pos != std::string::npos)
776  {
777  pathEnvs.erase(pos, oldMcdHomePath.length());
778  }
779 
780  return pathEnvs;
781 }
782 
783 void PrintAvaiablePduApi(IDiagRuntimeSystem* drs)
784 {
785  if (!isDebug) return;
786 
787  std::cout << "Possible PDU-API name are: [" << std::endl;
788  Command cmd;
789  cmd.SetCommandType(CommandTypesPb::GetPduApiNameList);
790 
791  std::shared_ptr<Parameter> pHandle = std::make_shared<Parameter>();
792  cmd.AddParameter(1, pHandle);
793 
794  std::unique_ptr<Result> result(drs->Execute(cmd));
795 
796  int resuldCode = result->GetResultCode();
797  if (resuldCode == ResultCodesPb::Success)
798  {
799  auto pduNameList =result->GetParameter(1)->GetValueAsList();
800  for (Parameter pduNameParam : pduNameList) {
801  std::cout << " " << pduNameParam.GetValueAsString() << std::endl;
802  }
803  }
804  std::cout << "]" << std::endl;
805 }
806 
807 void SwitchPduApi(IDiagRuntimeSystem* drs, const std::string& shortName)
808 {
809  PrintDebugTextToConsole("Switch to '" + shortName + "' PDU-API");
810  std::shared_ptr<SwitchPduApiPb> pb = std::make_shared<SwitchPduApiPb>();
811  pb->set_pduapishortname(shortName);
812 
813  Command cmd;
814  cmd.SetCommandType(CommandTypesPb::SwitchPduApi);
815 
816  std::string bytes;
817  pb->SerializeToString(&bytes);
818 
819  std::shared_ptr<Parameter> pHandle = std::make_shared<Parameter>();
820  pHandle->SetBytesValue(bytes);
821  cmd.AddParameter(1, pHandle);
822 
823  std::unique_ptr<Result> result(drs->Execute(cmd));
824 
825  int resuldCode = result->GetResultCode();
826  if (resuldCode == ResultCodesPb::Failed)
827  {
828  int errorcode;
829  ExceptionTypesPb type;
830  std::string message;
831  result->GetExceptionData(errorcode, type, message);
832 
833  PrintAvaiablePduApi(drs);
834  throw std::runtime_error(message.c_str());
835  }
836 }
837 
838 #if defined(__linux__) || defined(__QNXNTO__)
839 std::vector<pid_t> getAllProcIdByName(std::string procName)
840 {
841  std::vector<pid_t> listProcesses;
842  // Open the /proc directory
843  DIR *dp = opendir("/proc");
844 
845  if (dp != NULL)
846  {
847  // Enumerate all entries in directory until process found
848  //struct dirent *dirp;
849 
850  while (struct dirent* dirp = readdir(dp))
851  {
852  // Skip non-numeric entries
853  int id = atoi(dirp->d_name);
854 
855  if (id > 0)
856  {
857  // Read contents of virtual /proc/{pid}/cmdline file
858  std::string cmdPath = std::string("/proc/") + dirp->d_name + "/cmdline";
859  std::ifstream cmdFile(cmdPath.c_str());
860  std::string cmdLine;
861  std::getline(cmdFile, cmdLine);
862 
863  if (!cmdLine.empty())
864  {
865  // Keep first cmdline item which contains the program path
866  size_t pos = cmdLine.find('\0');
867 
868  if (pos != std::string::npos)
869  {
870  cmdLine = cmdLine.substr(0, pos);
871  }
872 
873  // Keep program name only, removing the path
874  pos = cmdLine.rfind('/');
875 
876  if (pos != std::string::npos)
877  {
878  cmdLine = cmdLine.substr(pos + 1);
879  }
880 
881  // Compare against requested process name
882  if (procName == cmdLine)
883  {
884  listProcesses.push_back(id);
885  }
886  }
887  }
888  }
889  }
890 
891  closedir(dp);
892 
893  return listProcesses;
894 }
895 #endif
896 
897 bool KillAllProccesses()
898 {
899  bool result = false;
900 
901 #ifdef _WIN32
902  DWORD processCurrent = GetCurrentProcessId();
903  HANDLE snap = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
904  PROCESSENTRY32 pe32;
905 
906  pe32.dwSize = sizeof(PROCESSENTRY32);
907 
908  if (!Process32First(snap, &pe32))
909  {
910  CloseHandle(snap);
911 
912  return false;
913  }
914 
915  do
916  {
917  if (processCurrent != pe32.th32ProcessID && strcmp(pe32.szExeFile, fileNameCurrent.c_str()) == 0)
918  {
919  HANDLE hProcess = OpenProcess(PROCESS_TERMINATE, FALSE, pe32.th32ProcessID);
920 
921  if (hProcess == NULL)
922  {
923  continue;
924  }
925 
926  result = TerminateProcess(hProcess, 1);
927 
928  CloseHandle(hProcess);
929  }
930  } while (Process32Next(snap, &pe32));
931 
932  CloseHandle(snap);
933 
934 #elif defined(__linux__) || defined(__QNXNTO__)
935  pid_t processCurrent = ::getpid();
936  std::vector<pid_t> processesFound = getAllProcIdByName(fileNameCurrent);
937 
938  if (processesFound.size() > 1)
939  {
940  for (auto process = processesFound.begin(); process != processesFound.end(); ++process)
941  {
942  if (*process != processCurrent && *process)
943  {
944  kill(*process, SIGTERM);
945  }
946  }
947  }
948 
949  try
950  {
951  std::string directory = std::string(LINUX_PIPE_PREFIX);
952  if (fs::exists(directory))
953  {
954  fs::remove_all(directory);
955  }
956  }
957  catch (std::exception& e)
958  {
959  }
960 #endif
961 
962  return result;
963 }
964 
965 
966 #ifdef _WIN32
967 std::string GetLastErrorAsString()
968 {
969  //Get the error message ID, if any.
970  DWORD errorMessageID = ::GetLastError();
971  if (errorMessageID == 0) {
972  return std::string(); //No error message has been recorded
973  }
974 
975  LPSTR messageBuffer = nullptr;
976 
977  //Ask Win32 to give us the string version of that message ID.
978  //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).
979  size_t size = FormatMessageA(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS,
980  NULL, errorMessageID, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), (LPSTR)&messageBuffer, 0, NULL);
981 
982  //Copy the error message into a std::string.
983  std::string message(messageBuffer, size);
984 
985  //Free the Win32's string's buffer.
986  LocalFree(messageBuffer);
987 
988  return message;
989 }
990 #endif
991 void PrintUsage()
992 {
993  std::cout << "" << std::endl;
994  std::cout << "Creates and starts a new process with the OTX DiagManager server." << std::endl;
995  std::cout << "" << std::endl;
996  std::cout << "The OTX DiagManager (short DiagManager) is a software component between" << std::endl;
997  std::cout << "diagnostic applications and various, interchangeable diagnostic runtime" << std::endl;
998  std::cout << "systems. The DiagManager is part of the OTX-Runtime API, but it can also" << std::endl;
999  std::cout << "be used stand-alone." << std::endl;
1000  std::cout << "" << std::endl;
1001  std::cout << "OpenTestSystem.Otx.DiagManager.Runner [-options]" << std::endl;
1002  std::cout << "" << std::endl;
1003  std::cout << " -help" << std::endl;
1004  std::cout << " -?" << std::endl;
1005  std::cout << " Print this help message. This option must be used" << std::endl;
1006  std::cout << " exclusive without any other option, otherwise it will" << std::endl;
1007  std::cout << " be ignored." << std::endl;
1008  std::cout << "" << std::endl;
1009  std::cout << " -debug" << std::endl;
1010  std::cout << " If set, debug messages will be written into the" << std::endl;
1011  std::cout << " standard i/o." << std::endl;
1012  std::cout << "" << std::endl;
1013  std::cout << " -port=<PortNumber> [0..1]" << std::endl;
1014  std::cout << " Sets the port number for interprocess communication" << std::endl;
1015  std::cout << " via sockets. The default value is 8888. If the port" << std::endl;
1016  std::cout << " is set explicit, the pipe will be ignored." << std::endl;
1017  std::cout << "" << std::endl;
1018  std::cout << " -pipe=<PipeName> [0..1]" << std::endl;
1019  std::cout << " Sets the pipe name for interprocess communication via" << std::endl;
1020  std::cout << " pipes. The default value is \"???\"." << std::endl;
1021  std::cout << "" << std::endl;
1022  std::cout << " -MaxNumberOfConcurrentComChannels=<MaxNumberOfConcurrentComChannels> [0..1]" << std::endl;
1023  std::cout << " Sets max number of concurrent ComChannels for the CommandProcessor." << std::endl;
1024  std::cout << " Sets maximum number of concurrent ComChannels for the CommandProcessor," << std::endl;
1025  std::cout << " which can be open at the same time. If the number is exceeded," << std::endl;
1026  std::cout << " ComChannels that are no longer used are automatically closed. The" << std::endl;
1027  std::cout << " default value is \"28\"." << std::endl;
1028  std::cout << "" << std::endl;
1029  std::cout << " -DiagServiceHandleMapping=<DiagServiceHandleMapping> [0..1]" << std::endl;
1030  std::cout << " Switches the DiagService handle translation of the CommandProcessor" << std::endl;
1031  std::cout << " ON or OFF. Possible value are:" << std::endl;
1032  std::cout << " [" << std::endl;
1033  std::cout << " OFF = 0," << std::endl;
1034  std::cout << " ON = 1" << std::endl;
1035  std::cout << " ]" << std::endl;
1036  std::cout << " The default value is ON. DiagService handle mapping is needed" << std::endl;
1037  std::cout << " to restore DiagService objects of closed and re-opend ComChannels" << std::endl;
1038  std::cout << " when the ComChannels limit is exceeded. The mapping takes time and" << std::endl;
1039  std::cout << " can be switched off, if it is not needed." << std::endl;
1040  std::cout << "" << std::endl;
1041  std::cout << " -kernelType=<KernelTypeEnum> [0..1]" << std::endl;
1042  std::cout << " Sets the type of the diagnostic runtime system. Possible" << std::endl;
1043  std::cout << " types are:" << std::endl;
1044  std::cout << " [" << std::endl;
1045  std::cout << " VwMcd = 0," << std::endl;
1046  std::cout << " VwMcdSP = 1," << std::endl;
1047  std::cout << " ProdisMCD = 2" << std::endl;
1048  std::cout << " ]" << std::endl;
1049  std::cout << " The default value is 0 (VwMcd). If the option is not set" << std::endl;
1050  std::cout << " to a valid value, the default value will be used." << std::endl;
1051  std::cout << "" << std::endl;
1052  std::cout << " -kernelPath=<KernelPath> [1]" << std::endl;
1053  std::cout << " Sets the path to the binary of the diagnostic runtime" << std::endl;
1054  std::cout << " system. If the option is not set to a valid value, the" << std::endl;
1055  std::cout << " DiagManager returns an error." << std::endl;
1056  std::cout << "" << std::endl;
1057  std::cout << " -configPath=<ConfigPath> [1]" << std::endl;
1058  std::cout << " Sets the path to the configuration folder of the" << std::endl;
1059  std::cout << " diagnostic runtime system. If the option is not set to" << std::endl;
1060  std::cout << " a valid value, the DiagManager returns an error." << std::endl;
1061  std::cout << "" << std::endl;
1062  std::cout << " -pduApi=<D_PDU_VCI_NAME> [0..1]" << std::endl;
1063  std::cout << " Sets the PDU-API of the diagnostic runtime system." << std::endl;
1064  std::cout << "" << std::endl;
1065  std::cout << " -javaVmPath=<JavaVmPath> [0..1]" << std::endl;
1066  std::cout << " Sets the path to the Java VM which should be used for" << std::endl;
1067  std::cout << " Java Jobs by the diagnostic runtime system. If the" << std::endl;
1068  std::cout << " value is not set, the Java VM will be searched inside" << std::endl;
1069  std::cout << " the system PATH." << std::endl;
1070  std::cout << "" << std::endl;
1071  std::cout << " -logPath=<LogPath> [0..1]" << std::endl;
1072  std::cout << " Sets the log path. The default log path is \"[User]/" << std::endl;
1073  std::cout << " AppData/Roaming/OpenTestSystem/[Version]/DiagManager/Logging/\"." << std::endl;
1074  std::cout << "" << std::endl;
1075  std::cout << " -logLevel=<LogLevel> [0..1]" << std::endl;
1076  std::cout << " Sets the log level (Off = 0, Error = 1, Critical = 2," << std::endl;
1077  std::cout << " Warning = 3, Info = 4, Debug = 5, Trace = 6). The" << std::endl;
1078  std::cout << " default log level is 3." << std::endl;
1079  std::cout << "" << std::endl;
1080  std::cout << " -licenseKey=<LicenseKey> [1]" << std::endl;
1081  std::cout << " Sets the license key to activate DiagManager" << std::endl;
1082  std::cout << " If the option is not set to a valid value, the" << std::endl;
1083  std::cout << " DiagManager cannot be activated." << std::endl;
1084  std::cout << "" << std::endl;
1085  std::cout << " -killAll [0..1]" << std::endl;
1086  std::cout << " All started processes at any port or pipe name will" << std::endl;
1087  std::cout << " be killed. This option must be used exclusively without" << std::endl;
1088  std::cout << " any other option, otherwise it will be ignored. This" << std::endl;
1089  std::cout << " option should only be used to get a clean environment." << std::endl;
1090  std::cout << " Please note, that this is not a regular exit!" << std::endl;
1091  std::cout << "" << std::endl;
1092  std::cout << "Return values:" << std::endl;
1093  std::cout << "" << std::endl;
1094  std::cout << " 0 If the server was started successfully or all started" << std::endl;
1095  std::cout << " processes was killed or the help was displayed." << std::endl;
1096  std::cout << " 1 An error occurred. The error message is written into" << std::endl;
1097  std::cout << " the output. Possible errors:" << std::endl;
1098  std::cout << " - The given port number or the pipe name is wrong or already" << std::endl;
1099  std::cout << " in use." << std::endl;
1100  std::cout << " - The Kernel path is wrong, does not exist or does not contain" << std::endl;
1101  std::cout << " a valid diagnostic runtime system." << std::endl;
1102  std::cout << " - The Configuration path is wrong, does not exist or does not" << std::endl;
1103  std::cout << " contain a valid configuration file. The configuration" << std::endl;
1104  std::cout << " file format depends on the selected diagnostic runtime" << std::endl;
1105  std::cout << " system." << std::endl;
1106  std::cout << " - The Log path is wrong or cannot be accessed." << std::endl;
1107  std::cout << " - The Log level is wrong." << std::endl;
1108  std::cout << " - No process to kill exists, see -stopAll option." << std::endl;
1109  std::cout << " - The server cannot be started because of any other reason." << std::endl;
1110  std::cout << "" << std::endl;
1111 }
1112 
1113 void PrintDebugTextToConsole(std::string message)
1114 {
1115  if (isDebug)
1116  {
1117  std::cout << message << std::endl;
1118  }
1119 }
The interchangeable CommandDispatcher contains methods to optimize the access to the diagnostic runti...
Definition: CommandDispatcher.h:67
The interchangeable CommandProcessor contains methods to optimize the access to the diagnostic runtim...
Definition: CommandProcessor.h:39
This class is used for communication between layers.
Definition: Command.h:24
void SetCommandType(int commandType)
Set Command Type.
Definition: Command.cpp:74
DiagManager default logger
Definition: DefaultLogger.h:31
Interface which a DiagRuntimeSystem must be implemented
Definition: IDiagRuntimeSystem.h:21
virtual Common::Result * Execute(const Common::Command &command)=0
DiagRuntimeSystem executes the command synchronously
Log levels
Definition: ILog.h:42
DiagManager default logger configuration
Definition: LogConfigBase.h:22
void SetDefaultLevel(ILog::Level level)
Sets the default log level
Definition: LogConfigBase.cpp:42
Contains methods for accessing the VW-MCD
Definition: VwMcdDiagRuntimeSystem.h:31
Contains methods for accessing the VW-MCD
Definition: VwMcdSPDiagRuntimeSystem.h:26
Creates the DiagManager server
Definition: ServerFactory.h:53
void SetSocketPort(const int &port)
Sets the port of the server of server type SOCKET
Definition: ServerFactory.cpp:41
void SetPipeName(const std::string &pipeName)
Sets the pipe name of the server of server type PIPE
Definition: ServerFactory.cpp:45
Server * Create(ServerType serverType)
Creates DiagManager server of the given server type
Definition: ServerFactory.cpp:17
Contains methods for the DiagManager server
Definition: Server.h:33
void SetCommandProcessor(OpenTestSystem::Otx::DiagManager::Common::ICommandProcessor *processor)
Sets the CommandProcessor for the DiagManager server
Definition: Server.cpp:75
virtual int Start()
Starts the DiagManager server
Definition: Server.cpp:48
static bool CheckPortInUse(unsigned short port)
Checks, if the given port is currently in use
Definition: SocketUtil.cpp:6
Namespace containing all common methods for the DiagManager
Namespace containing all methods for the DiagManager server
Definition: ClientInfo.h:12