The DiagManager utility program must be started with the following arguments. The order of the arguments is not relevant.
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.
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;
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"
17 #include "ProtoGen/ResultCodesPb.pb.h"
18 #include "ProtoGen/CommandTypesPb.pb.h"
19 #include "ProtoGen/NoneOtxDiagApiCommandsPb.pb.h"
22 #include <filesystem.h>
23 namespace fs = filesystem;
38 std::string GetLastErrorAsString();
39 HMODULE DiagRuntimeSystemDLL = NULL;
43 #include <sys/types.h>
46 #ifdef USE_VWMCD_LINK_LIBRARY
48 #include <VwMcdSPDiagRuntimeSystem.h>
49 typedef OpenTestSystem::Otx::DiagManager::DiagRuntimeSystem::VwMcdSPDiagRuntimeSystem VwMcdDiagRuntimeSystem;
51 #include <VwMcdDiagRuntimeSystem.h>
52 typedef OpenTestSystem::Otx::DiagManager::DiagRuntimeSystem::VwMcdDiagRuntimeSystem VwMcdDiagRuntimeSystem;
59 static std::string fileNameCurrent =
"";
60 static bool isDebug =
false;
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";
87 void SetDefaultArgumentsForRunner(std::map<std::string, std::string>& arguments);
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);
103 void Check32And64BitConflict(std::string kernelPath);
105 bool Is32BitRunner();
106 bool Is32BitKernelExist(std::string kernelPath);
107 bool Is64BitKernelExist(std::string kernelPath);
111 int main(
int argc,
char** argv)
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;
121 std::map<std::string, std::string> arguments;
122 SetDefaultArgumentsForRunner(arguments);
125 fileNameCurrent = std::string(argv[0]);
128 fileNameCurrent = fileNameCurrent.substr(fileNameCurrent.find_last_of(
'\\') + 1);
132 fileNameCurrent = fileNameCurrent.substr(fileNameCurrent.find_last_of(
'/') + 1);
135 if (argc == 1 || (argc == 2 && (argv[1] == HelpKey || argv[1] == QuestionMarkKey)))
141 PrintDebugTextToConsole(
"Initializing...");
142 if (argc == 2 && argv[1] == KillAllKey)
144 PrintDebugTextToConsole(
"Killing all proccesses...!");
146 PrintDebugTextToConsole(
"Killed all proccesses!");
151 PrintDebugTextToConsole(
"Updating arguments...!");
152 UpdateArgumentsByCommandLine(argc, argv, arguments);
154 logPath = arguments[LogPathKey];
155 logConfig = arguments[LogConfigKey];
156 logLevel = atoi(arguments[LogLevelKey].c_str());
158 PrintDebugTextToConsole(
"Setting up the logger...");
159 if (!SetupLogger(logPath, logLevel, logConfig, arguments[PortKey], arguments[PipeKey]))
161 PrintDebugTextToConsole(
"Setting up the logger failed!");
165 kernelPath = arguments[KernelPathKey];
166 configPath = arguments[ConfigPathKey];
167 javavmPath = arguments[JavaVmPathKey];
168 licenseKey = arguments[LicenseKey];
170 PrintDebugTextToConsole(
"Setting the environment variable path...");
171 if (!SetPathForVariableEnvironment(kernelPath, configPath, javavmPath))
173 log.Error(
"Setting the environment variable path failed!");
174 PrintDebugTextToConsole(
"Setting the environment variable path failed!");
178 PrintDebugTextToConsole(
"Setting up the command processor...");
179 if (!SetupCommandProcessor(&cmdProcessor, arguments))
181 log.Error(
"Setting up the command processor failed!");
182 PrintDebugTextToConsole(
"Setting up the command processor failed!");
186 kernelType = atoi(arguments[KernelTypeKey].c_str());
190 ServerFactory sFactory;
191 if (!arguments[PortKey].empty())
193 int port = atoi(arguments[PortKey].c_str());
197 log.Error(
"The port is wrong!!!");
198 PrintDebugTextToConsole(
"The port is wrong!!!");
203 if (OpenTestSystem::Otx::DiagManager::Server::SocketUtil::CheckPortInUse(port))
205 std::string message =
"The port " + std::to_string(port) +
" is in used.";
207 PrintDebugTextToConsole(message);
212 sFactory.SetSocketPort(port);
214 PrintDebugTextToConsole(
"Creating server with port " + std::to_string(port) +
"...");
215 sv = sFactory.Create(ServerType::Socket);
217 else if (!arguments[PipeKey].empty())
219 sFactory.SetPipeName(arguments[PipeKey]);
220 PrintDebugTextToConsole(
"Creating server with pipe " + arguments[PipeKey] +
"...");
221 sv = sFactory.Create(ServerType::Pipe);
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];
234 ::SwitchPduApi(diagRuntime, pduApi);
240 if (!licenseKey.empty())
242 sv->SetLicenseKey(licenseKey);
246 PrintDebugTextToConsole(
"A license key is required to activate DiagManager.");
249 sv->SetCommandProcessor(&cmdProcessor);
250 PrintDebugTextToConsole(
"The server is ready.");
252 PrintDebugTextToConsole(
"The server is stopped.");
263 catch (std::exception ex)
265 std::string message =
"Error: " + std::string(ex.what());
266 log.Error(ex.what());
267 PrintDebugTextToConsole(message);
276 IDiagRuntimeSystem* CreateDiagRuntimeSystemInstance(
const char * projectName,
const char * vehicleInfo,
const char* kernelPath, KernelTypes kernelType)
280 std::string DiagRuntimeSystem_17_50_FileName =
"OpenTestSystem.Otx.DiagManager.DiagRuntimeSystem.VwMcd_VC142.dll";
282 std::string DiagRuntimeSystemSP_17_50_FileName =
"OpenTestSystem.Otx.DiagManager.DiagRuntimeSystem.VwMcdSP_VC142.dll";
284 std::string DiagRuntimeSystem_09_00_FileName =
"OpenTestSystem.Otx.DiagManager.DiagRuntimeSystem.dll";
286 std::string DiagRuntimeSystemSP_09_00_FileName =
"OpenTestSystem.Otx.DiagManager.DiagRuntimeSystem.VwMcd90SP.dll";
288 std::string DiagRuntimeSystem_Prodis_FileName =
"OpenTestSystem.Otx.DiagManager.DiagRuntimeSystem.ProdisMcd.dll";
290 std::string DiagRuntimeSystem_Actia_FileName =
"OpenTestSystem.Otx.DiagManager.DiagRuntimeSystem.ActiaMcd.dll";
292 std::string DiagRuntimeSystem_Siemens_FileName =
"OpenTestSystem.Otx.DiagManager.DiagRuntimeSystem.SiemensMcd.dll";
295 std::string DiagRuntimeSystemFileName = DiagRuntimeSystem_17_50_FileName;
296 std::string kernelTypeStr =
"VwMcd1750";
297 if (kernelType == KernelTypes::VwMcdSP)
299 kernelTypeStr =
"VwMcd1750SP";
300 DiagRuntimeSystemFileName = DiagRuntimeSystemSP_17_50_FileName;
303 if (fs::exists(std::string(kernelPath) +
"/McdKernel_vc120.dll")
304 || fs::exists(std::string(kernelPath) +
"/McdKernel_vc120_64.dll"))
306 if (kernelType == KernelTypes::VwMcdSP)
308 kernelTypeStr =
"VwMcd90SP";
309 DiagRuntimeSystemFileName = DiagRuntimeSystemSP_09_00_FileName;
313 kernelTypeStr =
"VwMcd90";
314 DiagRuntimeSystemFileName = DiagRuntimeSystem_09_00_FileName;
317 else if (fs::exists(std::string(kernelPath) +
"/ProdisMcdKernel_vc142.dll")
318 || fs::exists(std::string(kernelPath) +
"/ProdisMcdKernel_vc142_64.dll"))
320 kernelTypeStr =
"ProdisMcd";
321 DiagRuntimeSystemFileName = DiagRuntimeSystem_Prodis_FileName;
323 else if (fs::exists(std::string(kernelPath) +
"/DiagServer.dll"))
325 kernelTypeStr =
"ActiaMcd";
326 DiagRuntimeSystemFileName = DiagRuntimeSystem_Actia_FileName;
328 else if (fs::exists(std::string(kernelPath) +
"/dkernel-core-vw.dll"))
330 kernelTypeStr =
"SiemensMcd";
331 DiagRuntimeSystemFileName = DiagRuntimeSystem_Siemens_FileName;
334 PrintDebugTextToConsole(
"The Kernel Type is " + kernelTypeStr +
".");
335 if (DiagRuntimeSystemDLL == NULL)
337 DiagRuntimeSystemDLL = ::LoadLibrary(DiagRuntimeSystemFileName.c_str());
340 if (DiagRuntimeSystemDLL == NULL)
342 std::string errorMessage = GetLastErrorAsString();
343 PrintDebugTextToConsole(errorMessage);
344 Check32And64BitConflict(std::string(kernelPath));
348 typedef IDiagRuntimeSystem* (__cdecl* typeCreateDiagRuntimeSystem)(
const char * projectName,
const char * vehicleInfo);
349 typeCreateDiagRuntimeSystem createFunction =
reinterpret_cast<typeCreateDiagRuntimeSystem
>(::GetProcAddress(DiagRuntimeSystemDLL,
"CreateDiagRuntimeSystem"));
351 if (createFunction ==
nullptr)
354 return createFunction(projectName, vehicleInfo);
356 #ifdef USE_VWMCD_LINK_LIBRARY
357 return new VwMcdDiagRuntimeSystem(projectName, vehicleInfo);
359 if (!handle && kernelType == KernelTypes::VwMcd)
361 PrintDebugTextToConsole(
"Kernel Type is VwMcd");
362 handle = dlopen(
"libOpenTestSystem.Otx.DiagManager.DiagRuntimeSystem.VwMcd.so", RTLD_NOW);
364 else if (!handle && kernelType == KernelTypes::VwMcdSP)
366 PrintDebugTextToConsole(
"Kernel Type is VwMcdSP");
367 handle = dlopen(
"libOpenTestSystem.Otx.DiagManager.DiagRuntimeSystem.VwMcdSP.so", RTLD_NOW);
372 std::cout << dlerror() << std::endl;
375 typedef IDiagRuntimeSystem* typeCreateDiagRuntimeSystem(
const char* projectName,
const char* vehicleInfo);
376 typeCreateDiagRuntimeSystem* createFunction =
reinterpret_cast<typeCreateDiagRuntimeSystem*
>(dlsym(handle,
"CreateDiagRuntimeSystem"));
383 IDiagRuntimeSystem* digRuntimeSystem = createFunction(projectName, vehicleInfo);
385 createFunction = NULL;
386 return digRuntimeSystem;
392 void Check32And64BitConflict(std::string kernelPath)
396 bool isRunner32 = Is32BitRunner();
397 bool isKernel32Exist = Is32BitKernelExist(kernelPath);
398 bool isKernel64Exist = Is64BitKernelExist(kernelPath);
400 if (isRunner32 != isKernel32Exist
401 && isRunner32 == isKernel64Exist)
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+
").";
407 PrintDebugTextToConsole(errorMessage);
415 BOOL bIsWow64 = FALSE;
417 typedef BOOL(WINAPI* LPFN_ISWOW64PROCESS) (HANDLE, PBOOL);
418 LPFN_ISWOW64PROCESS fnIsWow64Process;
419 fnIsWow64Process = (LPFN_ISWOW64PROCESS)GetProcAddress(GetModuleHandle(TEXT(
"kernel32")),
"IsWow64Process");
421 if (NULL != fnIsWow64Process)
423 if (!fnIsWow64Process(GetCurrentProcess(), &bIsWow64))
429 return bIsWow64 == TRUE ? true :
false;
434 SYSTEM_INFO systemInfo = { 0 };
435 GetNativeSystemInfo(&systemInfo);
438 if (systemInfo.wProcessorArchitecture == PROCESSOR_ARCHITECTURE_INTEL)
446 bool Is32BitKernelExist(std::string kernelPath)
448 return (fs::exists(std::string(kernelPath) +
"/McdKernel_vc120.dll")
449 || fs::exists(std::string(kernelPath) +
"/McdKernel_vc142.dll"));
452 bool Is64BitKernelExist(std::string kernelPath)
454 return (fs::exists(std::string(kernelPath) +
"/McdKernel_vc120_64.dll")
455 || fs::exists(std::string(kernelPath) +
"/McdKernel_vc142_64.dll"));
460 std::string GetAppDataPath()
462 char homedir[MAX_PATH];
465 snprintf(homedir, MAX_PATH,
"%s", getenv(
"APPDATA"));
468 snprintf(homedir, MAX_PATH,
"%s", getenv(
"TMPDIR"));
471 if (getenv(
"TEMP") != NULL)
473 snprintf(homedir, MAX_PATH,
"%s", getenv(
"TEMP"));
477 if (getenv(
"TMP") != NULL)
479 snprintf(homedir, MAX_PATH,
"%s", getenv(
"TMP"));
483 if (getenv(
"TMPDIR") != NULL)
485 snprintf(homedir, MAX_PATH,
"%s", getenv(
"TMPDIR"));
489 snprintf(homedir, MAX_PATH,
"%s",
"/tmp");
496 char* c = strdup(homedir);
506 void SetDefaultArgumentsForRunner(std::map<std::string, std::string>& arguments)
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] =
"";
525 bool UpdateArgumentsByCommandLine(
int argc,
char** argv, std::map<std::string, std::string>& arguments)
527 for (
int i = 1; i < argc; i++)
529 std::string argument = argv[i];
531 const size_t idx = argument.find(
'=');
533 if (std::string::npos != idx)
535 key = argument.substr(0, idx);
536 auto iter = arguments.find(key);
538 if (iter == arguments.end())
545 if (strcmp(key.c_str(), PortKey.c_str()) == 0)
547 arguments[PipeKey] =
"";
549 else if (strcmp(key.c_str(), PipeKey.c_str()) == 0)
551 arguments[PortKey] =
"";
554 std::string value = argument.substr(idx + 1, argument.length() - idx);
555 arguments[key] = value;
557 else if (strcmp(argument.c_str(), DebugKey.c_str()) == 0)
566 bool SetupLogger(std::string& logPath,
int logLevel, std::string& logConfig)
568 return SetupLogger(logPath, logLevel, logConfig,
"",
"");
571 bool SetupLogger(std::string &logPath,
int logLevel, std::string &logConfig, std::string portNumber, std::string pipeName)
582 if (!logPath.empty())
586 fs::create_directories(logPath);
588 if (logPath[logPath.length() - 1] != seperated)
590 logPath.push_back(seperated);
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);
602 std::cout << std::endl;
603 PrintDebugTextToConsole(
"Error: The path \"" + logPath +
"\" not found!");
608 if (logLevel > -1 && logLevel < 7 && logLevel != 3)
610 LogConfigBase * logConfig =
new LogConfigBase();
611 logConfig->SetDefaultLevel((ILog::Level)logLevel);
612 LogConfigSingleton::Set(std::shared_ptr<ILogConfig>(logConfig));
615 if (!logConfig.empty())
622 bool SetupCommandProcessor(CommandProcessor* commandProcessor, std::map<std::string, std::string>& arguments)
626 int MaxNumberOfConcurrentComChannels = atoi(arguments[MaxNumberOfConcurrentComChannelsKey].c_str());
627 int DiagServiceHandleMapping = atoi(arguments[DiagServiceHandleMappingKey].c_str());
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));
637 if (DiagServiceHandleMapping == 1)
639 commandProcessor->StartDiagServiceHandleMapping();
641 PrintDebugTextToConsole(
"DiagServiceHandleMapping: " + std::string(DiagServiceHandleMapping ?
"on" :
"off"));
643 catch (std::exception& e)
645 PrintDebugTextToConsole(e.what());
651 int SetVariableEnvironment(
const std::string& env)
653 char* envString =
new char[env.length() + 1];
654 strncpy(envString, env.c_str(), env.length());
655 envString[env.length()] =
'\0';
657 size_t pos = env.find(
'=');
658 std::string envName = env.substr(0, pos);
659 std::string envPath = env.substr(pos + 1, env.length());
661 std::string textConsole =
"Setting the environment variable \"" +
663 "\" with the path \"" +
666 PrintDebugTextToConsole(textConsole);
667 int ret = putenv(envString);
669 textConsole =
"The environment variable \"" +
671 "\" path is set to \"" +
673 PrintDebugTextToConsole(textConsole);
680 bool SetPathForVariableEnvironment(std::string kernelPath, std::string configPath, std::string javavmPath)
682 std::string seperated =
"";
691 if (!kernelPath.empty())
693 if (!fs::exists(kernelPath))
695 PrintDebugTextToConsole(
"Error: The path \"" + kernelPath +
"\" not found!");
700 PrintDebugTextToConsole(
"Find PATH environment");
701 std::string pathEnvs = getenv(
"PATH");
703 PrintDebugTextToConsole(
"Set kernelPath to environment system");
705 if (fs::exists(std::string(kernelPath) +
"/ProdisMcdKernel_vc142.dll")
706 || fs::exists(std::string(kernelPath) +
"/ProdisMcdKernel_vc142_64.dll"))
708 home =
"PRODIS_MCD_HOME=" + kernelPath;
710 else if (fs::exists(std::string(kernelPath) +
"/dkernel-core-vw.dll"))
712 home =
"SIEMENS_MCD_HOME=" + kernelPath;
715 home =
"VW_MCD_HOME=" + kernelPath;
717 SetVariableEnvironment(home);
719 std::string newPath(kernelPath);
720 newPath.append(seperated);
721 newPath.append(pathEnvs);
722 std::string path =
"PATH=" + newPath;
723 SetVariableEnvironment(path);
726 if (!configPath.empty())
728 if (!fs::exists(configPath))
730 PrintDebugTextToConsole(
"Error: The path \"" + configPath +
"\" not found!");
734 PrintDebugTextToConsole(
"Set configPath to environment system");
736 if (fs::exists(std::string(kernelPath) +
"/ProdisMcdKernel_vc142.dll")
737 || fs::exists(std::string(kernelPath) +
"/ProdisMcdKernel_vc142_64.dll"))
739 config =
"PRODIS_MCD_CONFIG=" + configPath;
741 else if (fs::exists(std::string(kernelPath) +
"/dkernel-core-vw.dll"))
743 config =
"SIEMENS_MCD_CONFIG=" + configPath;
746 config =
"VW_MCD_CONFIG=" + configPath;
748 SetVariableEnvironment(config);
751 if (!javavmPath.empty())
753 if (!fs::exists(javavmPath))
755 PrintDebugTextToConsole(
"Error: The path \"" + javavmPath +
"\" not found!");
760 std::string pathEnvs = getenv(
"PATH");
762 std::string newPath(javavmPath);
763 newPath.append(seperated);
764 newPath.append(pathEnvs);
765 std::string path =
"PATH=" + newPath;
766 SetVariableEnvironment(path.c_str());
773 std::string RemoveOldMcdHomeFromPathEnv()
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)
780 pathEnvs.erase(pos, oldMcdHomePath.length());
786 void PrintAvaiablePduApi(IDiagRuntimeSystem* drs)
788 if (!isDebug)
return;
790 std::cout <<
"Possible PDU-API name are: [" << std::endl;
792 cmd.SetCommandType(CommandTypesPb::GetPduApiNameList);
794 std::shared_ptr<Parameter> pHandle = std::make_shared<Parameter>();
795 cmd.AddParameter(1, pHandle);
797 Result* result = drs->Execute(cmd);
799 int resuldCode = result->GetResultCode();
800 if (resuldCode == ResultCodesPb::Success)
802 auto pduNameList =result->GetParameter(1)->GetValueAsList();
803 for (Parameter pduNameParam : pduNameList) {
804 std::cout <<
" " << pduNameParam.GetValueAsString() << std::endl;
807 std::cout <<
"]" << std::endl;
811 void SwitchPduApi(IDiagRuntimeSystem* drs,
const std::string& shortName)
813 PrintDebugTextToConsole(
"Switch to '" + shortName +
"' PDU-API");
814 std::shared_ptr<SwitchPduApiPb> pb = std::make_shared<SwitchPduApiPb>();
815 pb->set_pduapishortname(shortName);
818 cmd.SetCommandType(CommandTypesPb::SwitchPduApi);
821 pb->SerializeToString(&bytes);
823 std::shared_ptr<Parameter> pHandle = std::make_shared<Parameter>();
824 pHandle->SetBytesValue(bytes);
825 cmd.AddParameter(1, pHandle);
827 Result* result = drs->Execute(cmd);
829 int resuldCode = result->GetResultCode();
830 if (resuldCode == ResultCodesPb::Failed)
833 ExceptionTypesPb type;
835 result->GetExceptionData(errorcode, type, message);
838 PrintAvaiablePduApi(drs);
839 throw std::runtime_error(message.c_str());
845 std::vector<pid_t> getAllProcIdByName(std::string procName)
847 std::vector<pid_t> listProcesses;
849 DIR *dp = opendir(
"/proc");
856 while (dirp = readdir(dp))
859 int id = atoi(dirp->d_name);
864 std::string cmdPath = std::string(
"/proc/") + dirp->d_name +
"/cmdline";
865 std::ifstream cmdFile(cmdPath.c_str());
867 std::getline(cmdFile, cmdLine);
869 if (!cmdLine.empty())
872 size_t pos = cmdLine.find(
'\0');
874 if (pos != std::string::npos)
876 cmdLine = cmdLine.substr(0, pos);
880 pos = cmdLine.rfind(
'/');
882 if (pos != std::string::npos)
884 cmdLine = cmdLine.substr(pos + 1);
888 if (procName == cmdLine)
890 listProcesses.push_back(
id);
899 return listProcesses;
903 bool KillAllProccesses()
908 DWORD processCurrent = GetCurrentProcessId();
909 HANDLE snap = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
912 pe32.dwSize =
sizeof(PROCESSENTRY32);
914 if (!Process32First(snap, &pe32))
923 if (processCurrent != pe32.th32ProcessID && strcmp(pe32.szExeFile, fileNameCurrent.c_str()) == 0)
925 HANDLE hProcess = OpenProcess(PROCESS_TERMINATE, FALSE, pe32.th32ProcessID);
927 if (hProcess == NULL)
932 result = TerminateProcess(hProcess, 1);
934 CloseHandle(hProcess);
936 }
while (Process32Next(snap, &pe32));
941 pid_t processCurrent = ::getpid();
942 std::vector<pid_t> processesFound = getAllProcIdByName(fileNameCurrent);
944 if (processesFound.size() > 1)
946 for (
auto process = processesFound.begin(); process != processesFound.end(); ++process)
948 if (*process != processCurrent && *process)
950 kill(*process, SIGTERM);
962 std::string GetLastErrorAsString()
965 DWORD errorMessageID = ::GetLastError();
966 if (errorMessageID == 0) {
967 return std::string();
970 LPSTR messageBuffer =
nullptr;
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);
978 std::string message(messageBuffer, size);
981 LocalFree(messageBuffer);
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;
1108 void PrintDebugTextToConsole(std::string message)
1112 std::cout << message << std::endl;
Namespace containing all common methods for the DiagManage