The following section describes how a user can implement its own DiagRuntimeSystem. The interface of the DiagRuntimeSystem is generic. It only executes a Command and gets a result. Except some special commands, see NoneOtxDiagApi, the structure of the commands and the result is equal to the structure of the related OTX extensions, see OtxDiagApi.
Note: The DiagRuntimeSystem must be implemented in C++.
Requirements
- The own diagnostic runtime system must support the functionality of at least the following actions and terms of the DiagCom OTX extension.
- GetComChannel
- CreateDiagServiceByName
- ExecuteDiagService
- The own diagnostic runtime system can support the functionality of all other diagnostic relevant OTX extensions:
- BusMonitoring
- ComInterface
- DiagComPlus
- DiagConfiguration
- DiagDataBrowsing
- DiagDataBrowsingPlus
- EcuConfiguration
- Flash
- FlashPlus
- Job
- VehicleInfo
Note: It is recommended, if an extension is supported, then all commands of that extension should be supported.
Note: If an OTX extension is not supported by the own implementation and inside an OTX procedure a related command will be executed, an Exception will be thrown inside the OTX runtime.
Note: Inside the OTX Development Environment the usage of extensions can be prevent inside the Extension-Manager.
Integration
- The own implementation must implement the interface IDiagRuntimeSystem
- Implement all relevant OTX and none OTX Commands for vehicle diagnostics, see methods of related OTX extensions in IOtxDiag and INoneOtxDiag
- Build the binary of the own implementation
- Set the own implementation as the diagnostic runtime system of the CommandProcessor, see SetRuntimeSystem
Sample Implementation
The sections shows a sample implementation of the main Commands:
- SelectProject
- SelectVehicleInformation
- GetComChannel
- CreateDiagServiceByName
- ExecuteDiagService
Note: A complete example in C++ can be found inside the archive file below.
DiagRuntimeSystemOwnImplementationSample.rar.
Sample Command SelectProject
if (command.GetCommandType() == CommandTypesPb::SelectProject)
{
TMessage *_data = command.GetParameter(1)->GetValueAsBytes();
std::string projectName = this->_data->projectname();
DSystemState systemState = this->_vwDiagSystem->GetState();
if (systemState == DSystemState::eINITIALIZED)
{
dproject = this->_vwDiagSystem->SelectProjectByName(projectName);
}
else if (systemState == DSystemState::ePROJECT_SELECTED || systemState == DSystemState::eLOGICALLY_CONNECTED)
{
dproject->DeselectVehicleInformation();
this->_vwDiagSystem->DeselectProject();
this->_vwDiagSystem->SelectProjectByName(projectName);
}
Result *result = new Result(command, 0);
}
Sample Command SelectVehicleInformation
if (command.GetCommandType() == CommandTypesPb::SelectVehicleInformation)
{
TMessage *_data = command.GetParameter(1)->GetValueAsBytes();
std::string vehicleInfo= this->_data->vehicleinformation();
DSystemState systemState = this->_vwDiagSystem->GetState();
if (systemState == DSystemState::ePROJECT_SELECTED || systemState == DSystemState::eLOGICALLY_CONNECTED)
{
if (this->_vwDiagSystem->GetActiveProject()->GetActiveDbVehicleInformation() != nullptr)
{
this->_vwDiagSystem->GetActiveProject()->DeselectVehicleInformation();
}
this->_vwDiagSystem->LoadDbVehicleInformation(vehicleInfo);
}
Result *result = new Result(command, 0);
}
Sample Command GetComChannel
if (command.GetCommandType() == CommandTypesPb::GetComChannel)
{
TMessage *_data = command.GetParameter(1)->GetValueAsBytes();
string identifier = this->_data->identifier();
string ecuvariantname = this->_data->ecuvariantname();
bool performvariantselection = this->_data->performvariantselection();
shared_ptr<DLogicalLinkEx> logicalLink = this->_vwDiagSystem->CreateLogicalLink(identifier, ecuvariantname, performvariantselection);
DComChannelPb comChannelPb;
comChannelPb.set_identifier(identifier);
comChannelPb.set_ecuvariantname(ecuvariantname);
Util::ConvertMcd2Pb(logicalLink, &comChannelPb);
string data;
comChannelPb.SerializeToString(&data);
shared_ptr<Common::Parameter> pHandle = make_shared<Common::Parameter>();
pHandle->SetBytesValue(data);
result.AddParameter(1, pHandle);
return result;
}
Sample Command CreateDiagServiceByName
if (command.GetCommandType() == CommandTypesPb::CreateDiagServiceByName)
{
TMessage *_data = command.GetParameter(1)->GetValueAsBytes();
std::string name = _data->name();
shared_ptr<DDataPrimitiveEx> diagComPrimitive = logicalLink->CreateDiagServiceByName(name);
DDiagServicePb diagServicePb;
diagServicePb.mutable_comchannel()->CopyFrom(this->_data->comchannel());
Util::ConvertMcd2Pb(diagComPrimitive, &diagServicePb);
string data;
diagServicePb.SerializeToString(&data);
shared_ptr<Common::Parameter> pHandle = make_shared<Common::Parameter>();
pHandle->SetBytesValue(data);
result.AddParameter(1, pHandle);
return result;
}
Sample Command ExecuteDiagService
Synchronous execution with OTX Inline-Mapping and processing of the request and response parameters.
if (command.GetCommandType() == CommandTypesPb::ExecuteDiagService)
{
TMessage *_data = command.GetParameter(1)->GetValueAsBytes();
bool async = command.GetParameter(2)->GetValueAsBool();
if (!this->_data->has_requestparamters())
{
this->_data->set_allocated_requestparamters(new DParameterCollectionPb());
}
DDiagServicePb *diagService = this->_data->mutable_diagservice();
RepeatedPtrField<DParameterPb> *requestparameters = this->_data->mutable_requestparamters()->mutable_items();
RepeatedPtrField<DParameterPb> *responseparameters = responseparameters = this->_data->mutable_responseparamters()->mutable_items();
if (this->async)
{
dataPrimitive->ExecuteAsync(requestparameters, this->_data->suppresspositiveresponse());
result.SetResultCode(ResultCodesPb::Pending);
}
else
{
shared_ptr<DResultEx> dResult = dataPrimitive->DDiagComPrimitiveEx::ExecuteSync(requestparameters, responseparameters, this->_data->suppresspositiveresponse());
DiagLoggingUtil::WriteResponses(this->_clientId, this->_clientName, *dataPrimitive, *dResult);
DResultPb resultPb;
resultPb.mutable_diagservice()->mutable_comchannel()->set_handle(diagService->mutable_comchannel()->handle());
resultPb.mutable_diagservice()->set_handle(diagService->handle());
std::shared_ptr<DDbDiagComPrimitive> dbObject = dataPrimitive->DDiagComPrimitiveEx::GetDbObject();
resultPb.mutable_diagservice()->set_shortname(dbObject->GetShortName());
resultPb.mutable_diagservice()->set_longname(Util::UnicodeToString(dbObject->GetLongName()));
Util::ConvertMcd2Pb(dResult, &resultPb);
string data;
resultPb.SerializeToString(&data);
shared_ptr<Parameter> parameter1 = make_shared<Parameter>();
parameter1->SetBytesValue(data);
result.AddParameter(1, parameter1);
this->_data->mutable_responseparamters()->SerializeToString(&data);
shared_ptr<Parameter> parameter2 = make_shared<Parameter>();
parameter2->SetBytesValue(data);
result.AddParameter(2, parameter2);
}
return result;
}