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;
32 #define LINUX_PIPE_PREFIX "/tmp/OpenTestSystem/pipe/"
39 std::string GetLastErrorAsString();
40 HMODULE DiagRuntimeSystemDLL = NULL;
44 #include <sys/types.h>
47 #ifdef USE_VWMCD_LINK_LIBRARY
49 #include <VwMcdSPDiagRuntimeSystem.h>
50 typedef OpenTestSystem::Otx::DiagManager::DiagRuntimeSystem::VwMcdSPDiagRuntimeSystem VwMcdDiagRuntimeSystem;
52 #include <VwMcdDiagRuntimeSystem.h>
53 typedef OpenTestSystem::Otx::DiagManager::DiagRuntimeSystem::VwMcdDiagRuntimeSystem VwMcdDiagRuntimeSystem;
60 static std::string fileNameCurrent =
"";
61 static bool isDebug =
false;
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";
88 void SetDefaultArgumentsForRunner(std::map<std::string, std::string>& arguments);
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);
104 void Check32And64BitConflict(std::string kernelPath);
106 bool Is32BitRunner();
107 bool Is32BitKernelExist(std::string kernelPath);
108 bool Is64BitKernelExist(std::string kernelPath);
112 int main(
int argc,
char** argv)
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;
122 std::map<std::string, std::string> arguments;
123 SetDefaultArgumentsForRunner(arguments);
126 fileNameCurrent = std::string(argv[0]);
129 fileNameCurrent = fileNameCurrent.substr(fileNameCurrent.find_last_of(
'\\') + 1);
133 fileNameCurrent = fileNameCurrent.substr(fileNameCurrent.find_last_of(
'/') + 1);
136 if (argc == 1 || (argc == 2 && (argv[1] == HelpKey || argv[1] == QuestionMarkKey)))
142 PrintDebugTextToConsole(
"Initializing...");
143 if (argc == 2 && argv[1] == KillAllKey)
145 PrintDebugTextToConsole(
"Killing all proccesses...!");
147 PrintDebugTextToConsole(
"Killed all proccesses!");
152 PrintDebugTextToConsole(
"Updating arguments...!");
153 UpdateArgumentsByCommandLine(argc, argv, arguments);
155 logPath = arguments[LogPathKey];
156 logConfig = arguments[LogConfigKey];
157 logLevel = atoi(arguments[LogLevelKey].c_str());
159 PrintDebugTextToConsole(
"Setting up the logger...");
160 if (!SetupLogger(logPath, logLevel, logConfig, arguments[PortKey], arguments[PipeKey]))
162 PrintDebugTextToConsole(
"Setting up the logger failed!");
166 kernelPath = arguments[KernelPathKey];
167 configPath = arguments[ConfigPathKey];
168 javavmPath = arguments[JavaVmPathKey];
169 licenseKey = arguments[LicenseKey];
171 PrintDebugTextToConsole(
"Setting the environment variable path...");
172 if (!SetPathForVariableEnvironment(kernelPath, configPath, javavmPath))
174 log.Error(
"Setting the environment variable path failed!");
175 PrintDebugTextToConsole(
"Setting the environment variable path failed!");
179 PrintDebugTextToConsole(
"Setting up the command processor...");
180 if (!SetupCommandProcessor(&cmdProcessor, arguments))
182 log.Error(
"Setting up the command processor failed!");
183 PrintDebugTextToConsole(
"Setting up the command processor failed!");
187 kernelType = atoi(arguments[KernelTypeKey].c_str());
191 ServerFactory sFactory;
192 if (!arguments[PortKey].empty())
194 int port = atoi(arguments[PortKey].c_str());
198 log.Error(
"The port is wrong!!!");
199 PrintDebugTextToConsole(
"The port is wrong!!!");
204 if (OpenTestSystem::Otx::DiagManager::Server::SocketUtil::CheckPortInUse(port))
206 std::string message =
"The port " + std::to_string(port) +
" is in used.";
208 PrintDebugTextToConsole(message);
213 sFactory.SetSocketPort(port);
215 PrintDebugTextToConsole(
"Creating server with port " + std::to_string(port) +
"...");
216 sv = sFactory.Create(ServerType::Socket);
218 else if (!arguments[PipeKey].empty())
220 sFactory.SetPipeName(arguments[PipeKey]);
221 PrintDebugTextToConsole(
"Creating server with pipe " + arguments[PipeKey] +
"...");
222 sv = sFactory.Create(ServerType::Pipe);
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];
235 ::SwitchPduApi(diagRuntime, pduApi);
241 if (!licenseKey.empty())
243 sv->SetLicenseKey(licenseKey);
247 PrintDebugTextToConsole(
"A license key is required to activate DiagManager.");
250 sv->SetCommandProcessor(&cmdProcessor);
251 PrintDebugTextToConsole(
"The server is ready.");
253 PrintDebugTextToConsole(
"The server is stopped.");
264 catch (std::exception& ex)
266 std::string message =
"Error: " + std::string(ex.what());
267 log.Error(ex.what());
268 PrintDebugTextToConsole(message);
277 IDiagRuntimeSystem* CreateDiagRuntimeSystemInstance(
const char * projectName,
const char * vehicleInfo,
const char* kernelPath, KernelTypes kernelType)
281 std::string DiagRuntimeSystem_17_50_FileName =
"OpenTestSystem.Otx.DiagManager.DiagRuntimeSystem.VwMcd_VC142.dll";
283 std::string DiagRuntimeSystemSP_17_50_FileName =
"OpenTestSystem.Otx.DiagManager.DiagRuntimeSystem.VwMcdSP_VC142.dll";
285 std::string DiagRuntimeSystem_09_00_FileName =
"OpenTestSystem.Otx.DiagManager.DiagRuntimeSystem.dll";
287 std::string DiagRuntimeSystemSP_09_00_FileName =
"OpenTestSystem.Otx.DiagManager.DiagRuntimeSystem.VwMcd90SP.dll";
289 std::string DiagRuntimeSystem_Prodis_FileName =
"OpenTestSystem.Otx.DiagManager.DiagRuntimeSystem.ProdisMcd.dll";
291 std::string DiagRuntimeSystem_Actia_FileName =
"OpenTestSystem.Otx.DiagManager.DiagRuntimeSystem.ActiaMcd.dll";
293 std::string DiagRuntimeSystem_Siemens_FileName =
"OpenTestSystem.Otx.DiagManager.DiagRuntimeSystem.SiemensMcd.dll";
296 std::string DiagRuntimeSystemFileName = DiagRuntimeSystem_17_50_FileName;
297 std::string kernelTypeStr =
"VwMcd1750";
298 if (kernelType == KernelTypes::VwMcdSP)
300 kernelTypeStr =
"VwMcd1750SP";
301 DiagRuntimeSystemFileName = DiagRuntimeSystemSP_17_50_FileName;
304 if (fs::exists(std::string(kernelPath) +
"/McdKernel_vc120.dll")
305 || fs::exists(std::string(kernelPath) +
"/McdKernel_vc120_64.dll"))
307 if (kernelType == KernelTypes::VwMcdSP)
309 kernelTypeStr =
"VwMcd90SP";
310 DiagRuntimeSystemFileName = DiagRuntimeSystemSP_09_00_FileName;
314 kernelTypeStr =
"VwMcd90";
315 DiagRuntimeSystemFileName = DiagRuntimeSystem_09_00_FileName;
318 else if (fs::exists(std::string(kernelPath) +
"/ProdisMcdKernel_vc142.dll")
319 || fs::exists(std::string(kernelPath) +
"/ProdisMcdKernel_vc142_64.dll"))
321 kernelTypeStr =
"ProdisMcd";
322 DiagRuntimeSystemFileName = DiagRuntimeSystem_Prodis_FileName;
324 else if (fs::exists(std::string(kernelPath) +
"/DiagServer.dll"))
326 kernelTypeStr =
"ActiaMcd";
327 DiagRuntimeSystemFileName = DiagRuntimeSystem_Actia_FileName;
329 else if (fs::exists(std::string(kernelPath) +
"/dkernel-core-vw.dll"))
331 kernelTypeStr =
"SiemensMcd";
332 DiagRuntimeSystemFileName = DiagRuntimeSystem_Siemens_FileName;
335 PrintDebugTextToConsole(
"The Kernel Type is " + kernelTypeStr +
".");
336 if (DiagRuntimeSystemDLL == NULL)
338 DiagRuntimeSystemDLL = ::LoadLibrary(DiagRuntimeSystemFileName.c_str());
341 if (DiagRuntimeSystemDLL == NULL)
343 std::string errorMessage = GetLastErrorAsString();
344 PrintDebugTextToConsole(errorMessage);
345 Check32And64BitConflict(std::string(kernelPath));
349 typedef IDiagRuntimeSystem* (__cdecl* typeCreateDiagRuntimeSystem)(
const char * projectName,
const char * vehicleInfo);
350 typeCreateDiagRuntimeSystem createFunction =
reinterpret_cast<typeCreateDiagRuntimeSystem
>(::GetProcAddress(DiagRuntimeSystemDLL,
"CreateDiagRuntimeSystem"));
352 if (createFunction ==
nullptr)
355 return createFunction(projectName, vehicleInfo);
357 #ifdef USE_VWMCD_LINK_LIBRARY
358 return new VwMcdDiagRuntimeSystem(projectName, vehicleInfo);
360 if (!handle && kernelType == KernelTypes::VwMcd)
362 PrintDebugTextToConsole(
"Kernel Type is VwMcd");
363 handle = dlopen(
"libOpenTestSystem.Otx.DiagManager.DiagRuntimeSystem.VwMcd.so", RTLD_NOW);
365 else if (!handle && kernelType == KernelTypes::VwMcdSP)
367 PrintDebugTextToConsole(
"Kernel Type is VwMcdSP");
368 handle = dlopen(
"libOpenTestSystem.Otx.DiagManager.DiagRuntimeSystem.VwMcdSP.so", RTLD_NOW);
373 std::cout << dlerror() << std::endl;
376 typedef IDiagRuntimeSystem* typeCreateDiagRuntimeSystem(
const char* projectName,
const char* vehicleInfo);
377 typeCreateDiagRuntimeSystem* createFunction =
reinterpret_cast<typeCreateDiagRuntimeSystem*
>(dlsym(handle,
"CreateDiagRuntimeSystem"));
384 IDiagRuntimeSystem* digRuntimeSystem = createFunction(projectName, vehicleInfo);
386 createFunction = NULL;
387 return digRuntimeSystem;
393 void Check32And64BitConflict(std::string kernelPath)
397 bool isRunner32 = Is32BitRunner();
398 bool isKernel32Exist = Is32BitKernelExist(kernelPath);
399 bool isKernel64Exist = Is64BitKernelExist(kernelPath);
401 if (isRunner32 != isKernel32Exist
402 && isRunner32 == isKernel64Exist)
404 std::string runnerBit = isRunner32 ?
"32" :
"64";
405 std::string kernelBit = isKernel32Exist ?
"32" :
"64";
406 std::string errorMessage =
"Conflict between DiagManager Runner ("+runnerBit+
") and MCD-Kernel ("+kernelBit+
").";
408 PrintDebugTextToConsole(errorMessage);
416 BOOL bIsWow64 = FALSE;
418 typedef BOOL(WINAPI* LPFN_ISWOW64PROCESS) (HANDLE, PBOOL);
419 LPFN_ISWOW64PROCESS fnIsWow64Process;
420 fnIsWow64Process = (LPFN_ISWOW64PROCESS)GetProcAddress(GetModuleHandle(TEXT(
"kernel32")),
"IsWow64Process");
422 if (NULL != fnIsWow64Process)
424 if (!fnIsWow64Process(GetCurrentProcess(), &bIsWow64))
430 return bIsWow64 == TRUE ? true :
false;
435 SYSTEM_INFO systemInfo = { 0 };
436 GetNativeSystemInfo(&systemInfo);
439 if (systemInfo.wProcessorArchitecture == PROCESSOR_ARCHITECTURE_INTEL)
447 bool Is32BitKernelExist(std::string kernelPath)
449 return (fs::exists(std::string(kernelPath) +
"/McdKernel_vc120.dll")
450 || fs::exists(std::string(kernelPath) +
"/McdKernel_vc142.dll"));
453 bool Is64BitKernelExist(std::string kernelPath)
455 return (fs::exists(std::string(kernelPath) +
"/McdKernel_vc120_64.dll")
456 || fs::exists(std::string(kernelPath) +
"/McdKernel_vc142_64.dll"));
461 std::string GetAppDataPath()
463 char homedir[MAX_PATH];
466 snprintf(homedir, MAX_PATH,
"%s", getenv(
"APPDATA"));
469 snprintf(homedir, MAX_PATH,
"%s", getenv(
"TMPDIR"));
472 if (getenv(
"TEMP") != NULL)
474 snprintf(homedir, MAX_PATH,
"%s", getenv(
"TEMP"));
478 if (getenv(
"TMP") != NULL)
480 snprintf(homedir, MAX_PATH,
"%s", getenv(
"TMP"));
484 if (getenv(
"TMPDIR") != NULL)
486 snprintf(homedir, MAX_PATH,
"%s", getenv(
"TMPDIR"));
490 snprintf(homedir, MAX_PATH,
"%s",
"/tmp");
497 char* c = strdup(homedir);
507 void SetDefaultArgumentsForRunner(std::map<std::string, std::string>& arguments)
509 std::string defaultLogPath = fs::path(GetAppDataPath()).append(
"OpenTestSystem").append(CommonHelper::Get().GetSortVersion()).append(
"DiagManager").append(
"Logging").string();
510 arguments[PortKey] =
"8888";
511 arguments[PipeKey] =
"???";
512 arguments[KernelPathKey] =
"";
513 arguments[ConfigPathKey] =
"";
514 arguments[JavaVmPathKey] =
"";
515 arguments[LogPathKey] = defaultLogPath;
516 arguments[LogLevelKey] =
"3";
517 arguments[LogConfigKey] =
"";
518 arguments[KernelTypeKey] = KernelTypes::VwMcd;
519 arguments[MaxNumberOfConcurrentComChannelsKey] =
"28";
520 arguments[DiagServiceHandleMappingKey] =
"1";
521 arguments[PduApiKey] =
"";
522 arguments[LicenseKey] =
"";
526 bool UpdateArgumentsByCommandLine(
int argc,
char** argv, std::map<std::string, std::string>& arguments)
528 for (
int i = 1; i < argc; i++)
530 std::string argument = argv[i];
532 const size_t idx = argument.find(
'=');
534 if (std::string::npos != idx)
536 key = argument.substr(0, idx);
537 auto iter = arguments.find(key);
539 if (iter == arguments.end())
546 if (strcmp(key.c_str(), PortKey.c_str()) == 0)
548 arguments[PipeKey] =
"";
550 else if (strcmp(key.c_str(), PipeKey.c_str()) == 0)
552 arguments[PortKey] =
"";
555 std::string value = argument.substr(idx + 1, argument.length() - idx);
556 arguments[key] = value;
558 else if (strcmp(argument.c_str(), DebugKey.c_str()) == 0)
567 bool SetupLogger(std::string& logPath,
int logLevel, std::string& logConfig)
569 return SetupLogger(logPath, logLevel, logConfig,
"",
"");
572 bool SetupLogger(std::string &logPath,
int logLevel, std::string &logConfig, std::string portNumber, std::string pipeName)
583 if (!logPath.empty())
587 fs::create_directories(logPath);
589 if (logPath[logPath.length() - 1] != seperated)
591 logPath.push_back(seperated);
594 const std::string fileName =
"DiagManagerRunner.log";
595 DefaultLogger * log =
new DefaultLogger(logPath, fileName);
596 log->SetDiagManagerInfo(portNumber, pipeName);
597 DefaultLogger::Set(log);
598 CrashHandler::InstallCrashHandler(logPath, fileName);
603 std::cout << std::endl;
604 PrintDebugTextToConsole(
"Error: The path \"" + logPath +
"\" not found!");
609 if (logLevel > -1 && logLevel < 7 && logLevel != 3)
611 LogConfigBase * logConfig =
new LogConfigBase();
612 logConfig->SetDefaultLevel((ILog::Level)logLevel);
613 LogConfigSingleton::Set(std::shared_ptr<ILogConfig>(logConfig));
616 if (!logConfig.empty())
623 bool SetupCommandProcessor(CommandProcessor* commandProcessor, std::map<std::string, std::string>& arguments)
627 int MaxNumberOfConcurrentComChannels = atoi(arguments[MaxNumberOfConcurrentComChannelsKey].c_str());
628 int DiagServiceHandleMapping = atoi(arguments[DiagServiceHandleMappingKey].c_str());
631 auto commandDispatcher = std::make_unique<CommandDispatcher>();
632 auto* comChannelManager = commandDispatcher->GetComChannelManager();
633 comChannelManager->SetMaxChannels(MaxNumberOfConcurrentComChannels);
634 commandProcessor->SetCommandDispatcher(std::move(commandDispatcher));
635 PrintDebugTextToConsole(
"MaxNumberOfConcurrentComChannels: " + std::to_string(MaxNumberOfConcurrentComChannels));
638 if (DiagServiceHandleMapping == 1)
640 commandProcessor->StartDiagServiceHandleMapping();
642 PrintDebugTextToConsole(
"DiagServiceHandleMapping: " + std::string(DiagServiceHandleMapping ?
"on" :
"off"));
644 catch (std::exception& e)
646 PrintDebugTextToConsole(e.what());
652 int SetVariableEnvironment(
const std::string& env)
654 char* envString =
new char[env.length() + 1];
655 strncpy(envString, env.c_str(), env.length());
656 envString[env.length()] =
'\0';
658 size_t pos = env.find(
'=');
659 std::string envName = env.substr(0, pos);
660 std::string envPath = env.substr(pos + 1, env.length());
662 std::string textConsole =
"Setting the environment variable \"" +
664 "\" with the path \"" +
667 PrintDebugTextToConsole(textConsole);
668 int ret = putenv(envString);
670 textConsole =
"The environment variable \"" +
672 "\" path is set to \"" +
674 PrintDebugTextToConsole(textConsole);
681 bool SetPathForVariableEnvironment(std::string kernelPath, std::string configPath, std::string javavmPath)
683 std::string seperated =
"";
692 if (!kernelPath.empty())
694 if (!fs::exists(kernelPath))
696 PrintDebugTextToConsole(
"Error: The path \"" + kernelPath +
"\" not found!");
701 PrintDebugTextToConsole(
"Find PATH environment");
702 std::string pathEnvs = getenv(
"PATH");
704 PrintDebugTextToConsole(
"Set kernelPath to environment system");
706 if (fs::exists(std::string(kernelPath) +
"/ProdisMcdKernel_vc142.dll")
707 || fs::exists(std::string(kernelPath) +
"/ProdisMcdKernel_vc142_64.dll"))
709 home =
"PRODIS_MCD_HOME=" + kernelPath;
711 else if (fs::exists(std::string(kernelPath) +
"/dkernel-core-vw.dll"))
713 home =
"SIEMENS_MCD_HOME=" + kernelPath;
716 home =
"VW_MCD_HOME=" + kernelPath;
718 SetVariableEnvironment(home);
720 std::string newPath(kernelPath);
721 newPath.append(seperated);
722 newPath.append(pathEnvs);
723 std::string path =
"PATH=" + newPath;
724 SetVariableEnvironment(path);
727 if (!configPath.empty())
729 if (!fs::exists(configPath))
731 PrintDebugTextToConsole(
"Error: The path \"" + configPath +
"\" not found!");
735 PrintDebugTextToConsole(
"Set configPath to environment system");
737 if (fs::exists(std::string(kernelPath) +
"/ProdisMcdKernel_vc142.dll")
738 || fs::exists(std::string(kernelPath) +
"/ProdisMcdKernel_vc142_64.dll"))
740 config =
"PRODIS_MCD_CONFIG=" + configPath;
742 else if (fs::exists(std::string(kernelPath) +
"/dkernel-core-vw.dll"))
744 config =
"SIEMENS_MCD_CONFIG=" + configPath;
747 config =
"VW_MCD_CONFIG=" + configPath;
749 SetVariableEnvironment(config);
752 if (!javavmPath.empty())
754 if (!fs::exists(javavmPath))
756 PrintDebugTextToConsole(
"Error: The path \"" + javavmPath +
"\" not found!");
761 std::string pathEnvs = getenv(
"PATH");
763 std::string newPath(javavmPath);
764 newPath.append(seperated);
765 newPath.append(pathEnvs);
766 std::string path =
"PATH=" + newPath;
767 SetVariableEnvironment(path.c_str());
774 std::string RemoveOldMcdHomeFromPathEnv()
776 std::string oldMcdHomePath = getenv(
"VW_MCD_HOME");
777 std::string pathEnvs = getenv(
"PATH");
778 std::size_t pos = pathEnvs.find(oldMcdHomePath);
779 if (pos != std::string::npos)
781 pathEnvs.erase(pos, oldMcdHomePath.length());
787 void PrintAvaiablePduApi(IDiagRuntimeSystem* drs)
789 if (!isDebug)
return;
791 std::cout <<
"Possible PDU-API name are: [" << std::endl;
793 cmd.SetCommandType(CommandTypesPb::GetPduApiNameList);
795 std::shared_ptr<Parameter> pHandle = std::make_shared<Parameter>();
796 cmd.AddParameter(1, pHandle);
798 Result* result = drs->Execute(cmd);
800 int resuldCode = result->GetResultCode();
801 if (resuldCode == ResultCodesPb::Success)
803 auto pduNameList =result->GetParameter(1)->GetValueAsList();
804 for (Parameter pduNameParam : pduNameList) {
805 std::cout <<
" " << pduNameParam.GetValueAsString() << std::endl;
808 std::cout <<
"]" << std::endl;
812 void SwitchPduApi(IDiagRuntimeSystem* drs,
const std::string& shortName)
814 PrintDebugTextToConsole(
"Switch to '" + shortName +
"' PDU-API");
815 std::shared_ptr<SwitchPduApiPb> pb = std::make_shared<SwitchPduApiPb>();
816 pb->set_pduapishortname(shortName);
819 cmd.SetCommandType(CommandTypesPb::SwitchPduApi);
822 pb->SerializeToString(&bytes);
824 std::shared_ptr<Parameter> pHandle = std::make_shared<Parameter>();
825 pHandle->SetBytesValue(bytes);
826 cmd.AddParameter(1, pHandle);
828 Result* result = drs->Execute(cmd);
830 int resuldCode = result->GetResultCode();
831 if (resuldCode == ResultCodesPb::Failed)
834 ExceptionTypesPb type;
836 result->GetExceptionData(errorcode, type, message);
839 PrintAvaiablePduApi(drs);
840 throw std::runtime_error(message.c_str());
846 std::vector<pid_t> getAllProcIdByName(std::string procName)
848 std::vector<pid_t> listProcesses;
850 DIR *dp = opendir(
"/proc");
857 while (
struct dirent* dirp = readdir(dp))
860 int id = atoi(dirp->d_name);
865 std::string cmdPath = std::string(
"/proc/") + dirp->d_name +
"/cmdline";
866 std::ifstream cmdFile(cmdPath.c_str());
868 std::getline(cmdFile, cmdLine);
870 if (!cmdLine.empty())
873 size_t pos = cmdLine.find(
'\0');
875 if (pos != std::string::npos)
877 cmdLine = cmdLine.substr(0, pos);
881 pos = cmdLine.rfind(
'/');
883 if (pos != std::string::npos)
885 cmdLine = cmdLine.substr(pos + 1);
889 if (procName == cmdLine)
891 listProcesses.push_back(
id);
900 return listProcesses;
904 bool KillAllProccesses()
909 DWORD processCurrent = GetCurrentProcessId();
910 HANDLE snap = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
913 pe32.dwSize =
sizeof(PROCESSENTRY32);
915 if (!Process32First(snap, &pe32))
924 if (processCurrent != pe32.th32ProcessID && strcmp(pe32.szExeFile, fileNameCurrent.c_str()) == 0)
926 HANDLE hProcess = OpenProcess(PROCESS_TERMINATE, FALSE, pe32.th32ProcessID);
928 if (hProcess == NULL)
933 result = TerminateProcess(hProcess, 1);
935 CloseHandle(hProcess);
937 }
while (Process32Next(snap, &pe32));
942 pid_t processCurrent = ::getpid();
943 std::vector<pid_t> processesFound = getAllProcIdByName(fileNameCurrent);
945 if (processesFound.size() > 1)
947 for (
auto process = processesFound.begin(); process != processesFound.end(); ++process)
949 if (*process != processCurrent && *process)
951 kill(*process, SIGTERM);
958 std::string directory = std::string(LINUX_PIPE_PREFIX);
959 if (fs::exists(directory))
961 fs::remove_all(directory);
964 catch (std::exception& e)
974 std::string GetLastErrorAsString()
977 DWORD errorMessageID = ::GetLastError();
978 if (errorMessageID == 0) {
979 return std::string();
982 LPSTR messageBuffer =
nullptr;
986 size_t size = FormatMessageA(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS,
987 NULL, errorMessageID, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), (LPSTR)&messageBuffer, 0, NULL);
990 std::string message(messageBuffer, size);
993 LocalFree(messageBuffer);
1000 std::cout <<
"" << std::endl;
1001 std::cout <<
"Creates and starts a new process with the OTX DiagManager server." << std::endl;
1002 std::cout <<
"" << std::endl;
1003 std::cout <<
"The OTX DiagManager (short DiagManager) is a software component between" << std::endl;
1004 std::cout <<
"diagnostic applications and various, interchangeable diagnostic runtime" << std::endl;
1005 std::cout <<
"systems. The DiagManager is part of the OTX-Runtime API, but it can also" << std::endl;
1006 std::cout <<
"be used stand-alone." << std::endl;
1007 std::cout <<
"" << std::endl;
1008 std::cout <<
"OpenTestSystem.Otx.DiagManager.Runner [-options]" << std::endl;
1009 std::cout <<
"" << std::endl;
1010 std::cout <<
" -help" << std::endl;
1011 std::cout <<
" -?" << std::endl;
1012 std::cout <<
" Print this help message. This option must be used" << std::endl;
1013 std::cout <<
" exclusive without any other option, otherwise it will" << std::endl;
1014 std::cout <<
" be ignored." << std::endl;
1015 std::cout <<
"" << std::endl;
1016 std::cout <<
" -debug" << std::endl;
1017 std::cout <<
" If set, debug messages will be written into the" << std::endl;
1018 std::cout <<
" standard i/o." << std::endl;
1019 std::cout <<
"" << std::endl;
1020 std::cout <<
" -port=<PortNumber> [0..1]" << std::endl;
1021 std::cout <<
" Sets the port number for interprocess communication" << std::endl;
1022 std::cout <<
" via sockets. The default value is 8888. If the port" << std::endl;
1023 std::cout <<
" is set explicit, the pipe will be ignored." << std::endl;
1024 std::cout <<
"" << std::endl;
1025 std::cout <<
" -pipe=<PipeName> [0..1]" << std::endl;
1026 std::cout <<
" Sets the pipe name for interprocess communication via" << std::endl;
1027 std::cout <<
" pipes. The default value is \"???\"." << std::endl;
1028 std::cout <<
"" << std::endl;
1029 std::cout <<
" -MaxNumberOfConcurrentComChannels=<MaxNumberOfConcurrentComChannels> [0..1]" << std::endl;
1030 std::cout <<
" Sets max number of concurrent ComChannels for the CommandProcessor." << std::endl;
1031 std::cout <<
" Sets maximum number of concurrent ComChannels for the CommandProcessor," << std::endl;
1032 std::cout <<
" which can be open at the same time. If the number is exceeded," << std::endl;
1033 std::cout <<
" ComChannels that are no longer used are automatically closed. The" << std::endl;
1034 std::cout <<
" default value is \"28\"." << std::endl;
1035 std::cout <<
"" << std::endl;
1036 std::cout <<
" -DiagServiceHandleMapping=<DiagServiceHandleMapping> [0..1]" << std::endl;
1037 std::cout <<
" Switches the DiagService handle translation of the CommandProcessor" << std::endl;
1038 std::cout <<
" ON or OFF. Possible value are:" << std::endl;
1039 std::cout <<
" [" << std::endl;
1040 std::cout <<
" OFF = 0," << std::endl;
1041 std::cout <<
" ON = 1" << std::endl;
1042 std::cout <<
" ]" << std::endl;
1043 std::cout <<
" The default value is ON. DiagService handle mapping is needed" << std::endl;
1044 std::cout <<
" to restore DiagService objects of closed and re-opend ComChannels" << std::endl;
1045 std::cout <<
" when the ComChannels limit is exceeded. The mapping takes time and" << std::endl;
1046 std::cout <<
" can be switched off, if it is not needed." << std::endl;
1047 std::cout <<
"" << std::endl;
1048 std::cout <<
" -kernelType=<KernelTypeEnum> [0..1]" << std::endl;
1049 std::cout <<
" Sets the type of the diagnostic runtime system. Possible" << std::endl;
1050 std::cout <<
" types are:" << std::endl;
1051 std::cout <<
" [" << std::endl;
1052 std::cout <<
" VwMcd = 0," << std::endl;
1053 std::cout <<
" VwMcdSP = 1," << std::endl;
1054 std::cout <<
" ProdisMCD = 2" << std::endl;
1055 std::cout <<
" ]" << std::endl;
1056 std::cout <<
" The default value is 0 (VwMcd). If the option is not set" << std::endl;
1057 std::cout <<
" to a valid value, the default value will be used." << std::endl;
1058 std::cout <<
"" << std::endl;
1059 std::cout <<
" -kernelPath=<KernelPath> [1]" << std::endl;
1060 std::cout <<
" Sets the path to the binary of the diagnostic runtime" << std::endl;
1061 std::cout <<
" system. If the option is not set to a valid value, the" << std::endl;
1062 std::cout <<
" DiagManager returns an error." << std::endl;
1063 std::cout <<
"" << std::endl;
1064 std::cout <<
" -configPath=<ConfigPath> [1]" << std::endl;
1065 std::cout <<
" Sets the path to the configuration folder of the" << std::endl;
1066 std::cout <<
" diagnostic runtime system. If the option is not set to" << std::endl;
1067 std::cout <<
" a valid value, the DiagManager returns an error." << std::endl;
1068 std::cout <<
"" << std::endl;
1069 std::cout <<
" -pduApi=<D_PDU_VCI_NAME> [0..1]" << std::endl;
1070 std::cout <<
" Sets the PDU-API of the diagnostic runtime system." << std::endl;
1071 std::cout <<
"" << std::endl;
1072 std::cout <<
" -javaVmPath=<JavaVmPath> [0..1]" << std::endl;
1073 std::cout <<
" Sets the path to the Java VM which should be used for" << std::endl;
1074 std::cout <<
" Java Jobs by the diagnostic runtime system. If the" << std::endl;
1075 std::cout <<
" value is not set, the Java VM will be searched inside" << std::endl;
1076 std::cout <<
" the system PATH." << std::endl;
1077 std::cout <<
"" << std::endl;
1078 std::cout <<
" -logPath=<LogPath> [0..1]" << std::endl;
1079 std::cout <<
" Sets the log path. The default log path is \"[User]/" << std::endl;
1080 std::cout <<
" AppData/Roaming/OpenTestSystem/[Version]/DiagManager/Logging/\"." << std::endl;
1081 std::cout <<
"" << std::endl;
1082 std::cout <<
" -logLevel=<LogLevel> [0..1]" << std::endl;
1083 std::cout <<
" Sets the log level (Off = 0, Error = 1, Critical = 2," << std::endl;
1084 std::cout <<
" Warning = 3, Info = 4, Debug = 5, Trace = 6). The" << std::endl;
1085 std::cout <<
" default log level is 3." << std::endl;
1086 std::cout <<
"" << std::endl;
1087 std::cout <<
" -licenseKey=<LicenseKey> [1]" << std::endl;
1088 std::cout <<
" Sets the license key to activate DiagManager" << std::endl;
1089 std::cout <<
" If the option is not set to a valid value, the" << std::endl;
1090 std::cout <<
" DiagManager cannot be activated." << std::endl;
1091 std::cout <<
"" << std::endl;
1092 std::cout <<
" -killAll [0..1]" << std::endl;
1093 std::cout <<
" All started processes at any port or pipe name will" << std::endl;
1094 std::cout <<
" be killed. This option must be used exclusively without" << std::endl;
1095 std::cout <<
" any other option, otherwise it will be ignored. This" << std::endl;
1096 std::cout <<
" option should only be used to get a clean environment." << std::endl;
1097 std::cout <<
" Please note, that this is not a regular exit!" << std::endl;
1098 std::cout <<
"" << std::endl;
1099 std::cout <<
"Return values:" << std::endl;
1100 std::cout <<
"" << std::endl;
1101 std::cout <<
" 0 If the server was started successfully or all started" << std::endl;
1102 std::cout <<
" processes was killed or the help was displayed." << std::endl;
1103 std::cout <<
" 1 An error occurred. The error message is written into" << std::endl;
1104 std::cout <<
" the output. Possible errors:" << std::endl;
1105 std::cout <<
" - The given port number or the pipe name is wrong or already" << std::endl;
1106 std::cout <<
" in use." << std::endl;
1107 std::cout <<
" - The Kernel path is wrong, does not exist or does not contain" << std::endl;
1108 std::cout <<
" a valid diagnostic runtime system." << std::endl;
1109 std::cout <<
" - The Configuration path is wrong, does not exist or does not" << std::endl;
1110 std::cout <<
" contain a valid configuration file. The configuration" << std::endl;
1111 std::cout <<
" file format depends on the selected diagnostic runtime" << std::endl;
1112 std::cout <<
" system." << std::endl;
1113 std::cout <<
" - The Log path is wrong or cannot be accessed." << std::endl;
1114 std::cout <<
" - The Log level is wrong." << std::endl;
1115 std::cout <<
" - No process to kill exists, see -stopAll option." << std::endl;
1116 std::cout <<
" - The server cannot be started because of any other reason." << std::endl;
1117 std::cout <<
"" << std::endl;
1120 void PrintDebugTextToConsole(std::string message)
1124 std::cout << message << std::endl;
Namespace containing all common methods for the DiagManage