Example Basic Service#
Note
The code in the following example is different from typical Basic Service s in the way that the service in the example reads from and writes to the Vehicle Device. In real life an vehicle device will either write or read from Vehicle Device, not both together. The Vehicle Device itself offers only one functionality, not both.
To create a Basic Service one just starts with a general Component, sets the object type to BasicService
from the EObjectType enum and adds functionality through implementing the inherited interfaces, using Vehicle Device s, see How to access other components.
#include "example_interfaces.h"
#include "example_reception_interfaces.h"
#include "example_transfer_interfaces.h"
#include <support/signal_support.h>
#include <support/component_impl.h>
#include <interfaces/dispatch.h>
#include <iostream>
#include <set>
class CBasicService
: public sdv::CSdvObject
, public vss::Device::IReceptionSignalSpeed_Event
, public vss::Service::IReceptionSignalSpeed
, public vss::Service::ITransferSignalBrakeForce
{
public:
CBasicService()
{
auto device = sdv::core::GetObject("VehicleDevice_Component").GetInterface<vss::Device::IReceptionSignalSpeed>();
if (!device)
{
SDV_LOG_ERROR("Could not get abstract device: [CBasicService]");
throw std::runtime_error("VehicleDevice_Component device not found");
}
device->RegisterSpeedEvent(static_cast<vss::Device::IReceptionSignalSpeed_Event*> (this));
m_BrakeForce = sdv::core::GetObject("VehicleDevice_Component").GetInterface<vss::Device::ITransferSignalBrakeForce>();
if (!m_BrakeForce)
{
SDV_LOG_ERROR("Could not get abstract device: [CBasicService]");
throw std::runtime_error("VehicleDevice_Component device not found");
}
SDV_LOG_TRACE("CBasicService created: [BasicService_Component]");
}
~CBasicService()
{
auto device = sdv::core::GetObject("VehicleDevice_Component").GetInterface<vss::Device::IReceptionSignalSpeed>();
if (device)
{
device->UnRegisterSpeedEvent(static_cast<vss::Device::IReceptionSignalSpeed_Event*> (this));
}
}
BEGIN_SDV_INTERFACE_MAP()
SDV_INTERFACE_ENTRY(vss::Service::IReceptionSignalSpeed)
SDV_INTERFACE_ENTRY(vss::Device::IReceptionSignalSpeed_Event)
SDV_INTERFACE_ENTRY(vss::Service::ITransferSignalBrakeForce)
END_SDV_INTERFACE_MAP()
DECLARE_OBJECT_CLASS_NAME("BasicService_Component")
DECLARE_OBJECT_CLASS_TYPE(sdv::EObjectType::BasicService);
/**
* @brief Set brake force
* @param[in] value of the brake force
* @return true on success otherwise false
*/
bool SetBrakeForce(uint32_t value) override
{
return m_BrakeForce->SetBrakeForce(value);
}
/**
* @brief Set speed
* @param[in] value speed
*/
void SetSpeedValue(int32_t value) override
{
m_Speed = value;
std::lock_guard<std::mutex> lock(m_mutexCallbacks);
for (auto callback : m_Callbacks)
{
callback->SetSpeedValue(value);
}
}
/**
* @brief Get Speedspeed
*/
int32_t GetSpeedValue() override
{
return m_Speed;
}
/**
* @brief Register Callback on signal change
* @param[in] callback function
*/
void RegisterCallBack(/*in*/ vss::Device::IReceptionSignalSpeed_Event* callback) override
{
if (callback)
{
std::lock_guard<std::mutex> lock(m_mutexCallbacks);
m_Callbacks.insert(callback);
}
}
/**
* @brief Unregister Callback
* @param[in] callback function
*/
void UnregisterCallBack(vss::Device::IReceptionSignalSpeed_Event* callback) override
{
if (callback)
{
std::lock_guard<std::mutex> lock(m_mutexCallbacks);
m_Callbacks.erase(callback);
}
}
private:
uint32_t m_Speed = { 0 }; ///< speed value which will be received
mutable std::mutex m_mutexCallbacks; ///< Mutex protecting m_Callbacks
std::set<vss::Device::IReceptionSignalSpeed_Event*> m_Callbacks; ///< collection of events to be called (received value)
vss::Device::ITransferSignalBrakeForce* m_BrakeForce = nullptr; ///< To write the brake force to the abstract device
};
DEFINE_SDV_OBJECT(CBasicService)
#include "example_interfaces.h"
#include "example_reception_interfaces.h"
#include "example_transfer_interfaces.h"
#include <support/signal_support.h>
#include <support/component_impl.h>
#include <interfaces/dispatch.h>
#include <iostream>
#include <set>
class CBasicService
: public sdv::CSdvObject
, public vss::Device::IReceptionSignalSpeed_Event
, public vss::Service::IReceptionSignalSpeed
, public vss::Service::ITransferSignalBrakeForce
{
public:
CBasicService()
{
auto device = sdv::core::GetObject("VehicleDevice_Component").GetInterface<vss::Device::IReceptionSignalSpeed>();
if (!device)
{
SDV_LOG_ERROR("Could not get abstract device: [CBasicService]");
throw std::runtime_error("VehicleDevice_Component device not found");
}
device->RegisterSpeedEvent(static_cast<vss::Device::IReceptionSignalSpeed_Event*> (this));
m_BrakeForce = sdv::core::GetObject("VehicleDevice_Component").GetInterface<vss::Device::ITransferSignalBrakeForce>();
if (!m_BrakeForce)
{
SDV_LOG_ERROR("Could not get abstract device: [CBasicService]");
throw std::runtime_error("VehicleDevice_Component device not found");
}
SDV_LOG_TRACE("CBasicService created: [BasicService_Component]");
}
~CBasicService()
{
auto device = sdv::core::GetObject("VehicleDevice_Component").GetInterface<vss::Device::IReceptionSignalSpeed>();
if (device)
{
device->UnRegisterSpeedEvent(static_cast<vss::Device::IReceptionSignalSpeed_Event*> (this));
}
}
BEGIN_SDV_INTERFACE_MAP()
SDV_INTERFACE_ENTRY(vss::Service::IReceptionSignalSpeed)
SDV_INTERFACE_ENTRY(vss::Device::IReceptionSignalSpeed_Event)
SDV_INTERFACE_ENTRY(vss::Service::ITransferSignalBrakeForce)
END_SDV_INTERFACE_MAP()
DECLARE_OBJECT_CLASS_NAME("BasicService_Component")
DECLARE_OBJECT_CLASS_TYPE(sdv::EObjectType::BasicService);
/**
* @brief Set brake force
* @param[in] value of the brake force
* @return true on success otherwise false
*/
bool SetBrakeForce(uint32_t value) override
{
return m_BrakeForce->SetBrakeForce(value);
}
/**
* @brief Set speed
* @param[in] value speed
*/
void SetSpeedValue(int32_t value) override
{
m_Speed = value;
std::lock_guard<std::mutex> lock(m_mutexCallbacks);
for (auto callback : m_Callbacks)
{
callback->SetSpeedValue(value);
}
}
/**
* @brief Get Speedspeed
*/
int32_t GetSpeedValue() override
{
return m_Speed;
}
/**
* @brief Register Callback on signal change
* @param[in] callback function
*/
void RegisterCallBack(/*in*/ vss::Device::IReceptionSignalSpeed_Event* callback) override
{
if (callback)
{
std::lock_guard<std::mutex> lock(m_mutexCallbacks);
m_Callbacks.insert(callback);
}
}
/**
* @brief Unregister Callback
* @param[in] callback function
*/
void UnregisterCallBack(vss::Device::IReceptionSignalSpeed_Event* callback) override
{
if (callback)
{
std::lock_guard<std::mutex> lock(m_mutexCallbacks);
m_Callbacks.erase(callback);
}
}
private:
uint32_t m_Speed = { 0 }; ///< speed value which will be received
mutable std::mutex m_mutexCallbacks; ///< Mutex protecting m_Callbacks
std::set<vss::Device::IReceptionSignalSpeed_Event*> m_Callbacks; ///< collection of events to be called (received value)
vss::Device::ITransferSignalBrakeForce* m_BrakeForce = nullptr; ///< To write the brake force to the abstract device
};
DEFINE_SDV_OBJECT(CBasicService)
Set object type and name.
#include "example_interfaces.h"
#include "example_reception_interfaces.h"
#include "example_transfer_interfaces.h"
#include <support/signal_support.h>
#include <support/component_impl.h>
#include <interfaces/dispatch.h>
#include <iostream>
#include <set>
class CBasicService
: public sdv::CSdvObject
, public vss::Device::IReceptionSignalSpeed_Event
, public vss::Service::IReceptionSignalSpeed
, public vss::Service::ITransferSignalBrakeForce
{
public:
CBasicService()
{
auto device = sdv::core::GetObject("VehicleDevice_Component").GetInterface<vss::Device::IReceptionSignalSpeed>();
if (!device)
{
SDV_LOG_ERROR("Could not get abstract device: [CBasicService]");
throw std::runtime_error("VehicleDevice_Component device not found");
}
device->RegisterSpeedEvent(static_cast<vss::Device::IReceptionSignalSpeed_Event*> (this));
m_BrakeForce = sdv::core::GetObject("VehicleDevice_Component").GetInterface<vss::Device::ITransferSignalBrakeForce>();
if (!m_BrakeForce)
{
SDV_LOG_ERROR("Could not get abstract device: [CBasicService]");
throw std::runtime_error("VehicleDevice_Component device not found");
}
SDV_LOG_TRACE("CBasicService created: [BasicService_Component]");
}
~CBasicService()
{
auto device = sdv::core::GetObject("VehicleDevice_Component").GetInterface<vss::Device::IReceptionSignalSpeed>();
if (device)
{
device->UnRegisterSpeedEvent(static_cast<vss::Device::IReceptionSignalSpeed_Event*> (this));
}
}
BEGIN_SDV_INTERFACE_MAP()
SDV_INTERFACE_ENTRY(vss::Service::IReceptionSignalSpeed)
SDV_INTERFACE_ENTRY(vss::Device::IReceptionSignalSpeed_Event)
SDV_INTERFACE_ENTRY(vss::Service::ITransferSignalBrakeForce)
END_SDV_INTERFACE_MAP()
DECLARE_OBJECT_CLASS_NAME("BasicService_Component")
DECLARE_OBJECT_CLASS_TYPE(sdv::EObjectType::BasicService);
/**
* @brief Set brake force
* @param[in] value of the brake force
* @return true on success otherwise false
*/
bool SetBrakeForce(uint32_t value) override
{
return m_BrakeForce->SetBrakeForce(value);
}
/**
* @brief Set speed
* @param[in] value speed
*/
void SetSpeedValue(int32_t value) override
{
m_Speed = value;
std::lock_guard<std::mutex> lock(m_mutexCallbacks);
for (auto callback : m_Callbacks)
{
callback->SetSpeedValue(value);
}
}
/**
* @brief Get Speedspeed
*/
int32_t GetSpeedValue() override
{
return m_Speed;
}
/**
* @brief Register Callback on signal change
* @param[in] callback function
*/
void RegisterCallBack(/*in*/ vss::Device::IReceptionSignalSpeed_Event* callback) override
{
if (callback)
{
std::lock_guard<std::mutex> lock(m_mutexCallbacks);
m_Callbacks.insert(callback);
}
}
/**
* @brief Unregister Callback
* @param[in] callback function
*/
void UnregisterCallBack(vss::Device::IReceptionSignalSpeed_Event* callback) override
{
if (callback)
{
std::lock_guard<std::mutex> lock(m_mutexCallbacks);
m_Callbacks.erase(callback);
}
}
private:
uint32_t m_Speed = { 0 }; ///< speed value which will be received
mutable std::mutex m_mutexCallbacks; ///< Mutex protecting m_Callbacks
std::set<vss::Device::IReceptionSignalSpeed_Event*> m_Callbacks; ///< collection of events to be called (received value)
vss::Device::ITransferSignalBrakeForce* m_BrakeForce = nullptr; ///< To write the brake force to the abstract device
};
DEFINE_SDV_OBJECT(CBasicService)
To write/send any data to the network the corresponding VAPI Interface of the Vehicle Device has to be used.
#include "example_interfaces.h"
#include "example_reception_interfaces.h"
#include "example_transfer_interfaces.h"
#include <support/signal_support.h>
#include <support/component_impl.h>
#include <interfaces/dispatch.h>
#include <iostream>
#include <set>
class CBasicService
: public sdv::CSdvObject
, public vss::Device::IReceptionSignalSpeed_Event
, public vss::Service::IReceptionSignalSpeed
, public vss::Service::ITransferSignalBrakeForce
{
public:
CBasicService()
{
auto device = sdv::core::GetObject("VehicleDevice_Component").GetInterface<vss::Device::IReceptionSignalSpeed>();
if (!device)
{
SDV_LOG_ERROR("Could not get abstract device: [CBasicService]");
throw std::runtime_error("VehicleDevice_Component device not found");
}
device->RegisterSpeedEvent(static_cast<vss::Device::IReceptionSignalSpeed_Event*> (this));
m_BrakeForce = sdv::core::GetObject("VehicleDevice_Component").GetInterface<vss::Device::ITransferSignalBrakeForce>();
if (!m_BrakeForce)
{
SDV_LOG_ERROR("Could not get abstract device: [CBasicService]");
throw std::runtime_error("VehicleDevice_Component device not found");
}
SDV_LOG_TRACE("CBasicService created: [BasicService_Component]");
}
~CBasicService()
{
auto device = sdv::core::GetObject("VehicleDevice_Component").GetInterface<vss::Device::IReceptionSignalSpeed>();
if (device)
{
device->UnRegisterSpeedEvent(static_cast<vss::Device::IReceptionSignalSpeed_Event*> (this));
}
}
BEGIN_SDV_INTERFACE_MAP()
SDV_INTERFACE_ENTRY(vss::Service::IReceptionSignalSpeed)
SDV_INTERFACE_ENTRY(vss::Device::IReceptionSignalSpeed_Event)
SDV_INTERFACE_ENTRY(vss::Service::ITransferSignalBrakeForce)
END_SDV_INTERFACE_MAP()
DECLARE_OBJECT_CLASS_NAME("BasicService_Component")
DECLARE_OBJECT_CLASS_TYPE(sdv::EObjectType::BasicService);
/**
* @brief Set brake force
* @param[in] value of the brake force
* @return true on success otherwise false
*/
bool SetBrakeForce(uint32_t value) override
{
return m_BrakeForce->SetBrakeForce(value);
}
/**
* @brief Set speed
* @param[in] value speed
*/
void SetSpeedValue(int32_t value) override
{
m_Speed = value;
std::lock_guard<std::mutex> lock(m_mutexCallbacks);
for (auto callback : m_Callbacks)
{
callback->SetSpeedValue(value);
}
}
/**
* @brief Get Speedspeed
*/
int32_t GetSpeedValue() override
{
return m_Speed;
}
/**
* @brief Register Callback on signal change
* @param[in] callback function
*/
void RegisterCallBack(/*in*/ vss::Device::IReceptionSignalSpeed_Event* callback) override
{
if (callback)
{
std::lock_guard<std::mutex> lock(m_mutexCallbacks);
m_Callbacks.insert(callback);
}
}
/**
* @brief Unregister Callback
* @param[in] callback function
*/
void UnregisterCallBack(vss::Device::IReceptionSignalSpeed_Event* callback) override
{
if (callback)
{
std::lock_guard<std::mutex> lock(m_mutexCallbacks);
m_Callbacks.erase(callback);
}
}
private:
uint32_t m_Speed = { 0 }; ///< speed value which will be received
mutable std::mutex m_mutexCallbacks; ///< Mutex protecting m_Callbacks
std::set<vss::Device::IReceptionSignalSpeed_Event*> m_Callbacks; ///< collection of events to be called (received value)
vss::Device::ITransferSignalBrakeForce* m_BrakeForce = nullptr; ///< To write the brake force to the abstract device
};
DEFINE_SDV_OBJECT(CBasicService)
First of all, the Basic Service must register itself by calling the register method of the Vehicle Device. This is done in the constructor of the class. Event driven approach: now on any signal change the ‘SetSpeedValue’ method is called and the value is updated automatically. Any Complex Service or Extern Application can get this value by polling ‘GetSpeed()’ or automatically if the Complex Service or Extern Application has registered a callback function. In this case the callback function of all registered methods will be called.
#include "example_interfaces.h"
#include "example_reception_interfaces.h"
#include "example_transfer_interfaces.h"
#include <support/signal_support.h>
#include <support/component_impl.h>
#include <interfaces/dispatch.h>
#include <iostream>
#include <set>
class CBasicService
: public sdv::CSdvObject
, public vss::Device::IReceptionSignalSpeed_Event
, public vss::Service::IReceptionSignalSpeed
, public vss::Service::ITransferSignalBrakeForce
{
public:
CBasicService()
{
auto device = sdv::core::GetObject("VehicleDevice_Component").GetInterface<vss::Device::IReceptionSignalSpeed>();
if (!device)
{
SDV_LOG_ERROR("Could not get abstract device: [CBasicService]");
throw std::runtime_error("VehicleDevice_Component device not found");
}
device->RegisterSpeedEvent(static_cast<vss::Device::IReceptionSignalSpeed_Event*> (this));
m_BrakeForce = sdv::core::GetObject("VehicleDevice_Component").GetInterface<vss::Device::ITransferSignalBrakeForce>();
if (!m_BrakeForce)
{
SDV_LOG_ERROR("Could not get abstract device: [CBasicService]");
throw std::runtime_error("VehicleDevice_Component device not found");
}
SDV_LOG_TRACE("CBasicService created: [BasicService_Component]");
}
~CBasicService()
{
auto device = sdv::core::GetObject("VehicleDevice_Component").GetInterface<vss::Device::IReceptionSignalSpeed>();
if (device)
{
device->UnRegisterSpeedEvent(static_cast<vss::Device::IReceptionSignalSpeed_Event*> (this));
}
}
BEGIN_SDV_INTERFACE_MAP()
SDV_INTERFACE_ENTRY(vss::Service::IReceptionSignalSpeed)
SDV_INTERFACE_ENTRY(vss::Device::IReceptionSignalSpeed_Event)
SDV_INTERFACE_ENTRY(vss::Service::ITransferSignalBrakeForce)
END_SDV_INTERFACE_MAP()
DECLARE_OBJECT_CLASS_NAME("BasicService_Component")
DECLARE_OBJECT_CLASS_TYPE(sdv::EObjectType::BasicService);
/**
* @brief Set brake force
* @param[in] value of the brake force
* @return true on success otherwise false
*/
bool SetBrakeForce(uint32_t value) override
{
return m_BrakeForce->SetBrakeForce(value);
}
/**
* @brief Set speed
* @param[in] value speed
*/
void SetSpeedValue(int32_t value) override
{
m_Speed = value;
std::lock_guard<std::mutex> lock(m_mutexCallbacks);
for (auto callback : m_Callbacks)
{
callback->SetSpeedValue(value);
}
}
/**
* @brief Get Speedspeed
*/
int32_t GetSpeedValue() override
{
return m_Speed;
}
/**
* @brief Register Callback on signal change
* @param[in] callback function
*/
void RegisterCallBack(/*in*/ vss::Device::IReceptionSignalSpeed_Event* callback) override
{
if (callback)
{
std::lock_guard<std::mutex> lock(m_mutexCallbacks);
m_Callbacks.insert(callback);
}
}
/**
* @brief Unregister Callback
* @param[in] callback function
*/
void UnregisterCallBack(vss::Device::IReceptionSignalSpeed_Event* callback) override
{
if (callback)
{
std::lock_guard<std::mutex> lock(m_mutexCallbacks);
m_Callbacks.erase(callback);
}
}
private:
uint32_t m_Speed = { 0 }; ///< speed value which will be received
mutable std::mutex m_mutexCallbacks; ///< Mutex protecting m_Callbacks
std::set<vss::Device::IReceptionSignalSpeed_Event*> m_Callbacks; ///< collection of events to be called (received value)
vss::Device::ITransferSignalBrakeForce* m_BrakeForce = nullptr; ///< To write the brake force to the abstract device
};
DEFINE_SDV_OBJECT(CBasicService)
If the Basic Service has registered itself in the Vehicle Device it has to unregister itself on shutdown.
#include "example_interfaces.h"
#include "example_reception_interfaces.h"
#include "example_transfer_interfaces.h"
#include <support/signal_support.h>
#include <support/component_impl.h>
#include <interfaces/dispatch.h>
#include <iostream>
#include <set>
class CBasicService
: public sdv::CSdvObject
, public vss::Device::IReceptionSignalSpeed_Event
, public vss::Service::IReceptionSignalSpeed
, public vss::Service::ITransferSignalBrakeForce
{
public:
CBasicService()
{
auto device = sdv::core::GetObject("VehicleDevice_Component").GetInterface<vss::Device::IReceptionSignalSpeed>();
if (!device)
{
SDV_LOG_ERROR("Could not get abstract device: [CBasicService]");
throw std::runtime_error("VehicleDevice_Component device not found");
}
device->RegisterSpeedEvent(static_cast<vss::Device::IReceptionSignalSpeed_Event*> (this));
m_BrakeForce = sdv::core::GetObject("VehicleDevice_Component").GetInterface<vss::Device::ITransferSignalBrakeForce>();
if (!m_BrakeForce)
{
SDV_LOG_ERROR("Could not get abstract device: [CBasicService]");
throw std::runtime_error("VehicleDevice_Component device not found");
}
SDV_LOG_TRACE("CBasicService created: [BasicService_Component]");
}
~CBasicService()
{
auto device = sdv::core::GetObject("VehicleDevice_Component").GetInterface<vss::Device::IReceptionSignalSpeed>();
if (device)
{
device->UnRegisterSpeedEvent(static_cast<vss::Device::IReceptionSignalSpeed_Event*> (this));
}
}
BEGIN_SDV_INTERFACE_MAP()
SDV_INTERFACE_ENTRY(vss::Service::IReceptionSignalSpeed)
SDV_INTERFACE_ENTRY(vss::Device::IReceptionSignalSpeed_Event)
SDV_INTERFACE_ENTRY(vss::Service::ITransferSignalBrakeForce)
END_SDV_INTERFACE_MAP()
DECLARE_OBJECT_CLASS_NAME("BasicService_Component")
DECLARE_OBJECT_CLASS_TYPE(sdv::EObjectType::BasicService);
/**
* @brief Set brake force
* @param[in] value of the brake force
* @return true on success otherwise false
*/
bool SetBrakeForce(uint32_t value) override
{
return m_BrakeForce->SetBrakeForce(value);
}
/**
* @brief Set speed
* @param[in] value speed
*/
void SetSpeedValue(int32_t value) override
{
m_Speed = value;
std::lock_guard<std::mutex> lock(m_mutexCallbacks);
for (auto callback : m_Callbacks)
{
callback->SetSpeedValue(value);
}
}
/**
* @brief Get Speedspeed
*/
int32_t GetSpeedValue() override
{
return m_Speed;
}
/**
* @brief Register Callback on signal change
* @param[in] callback function
*/
void RegisterCallBack(/*in*/ vss::Device::IReceptionSignalSpeed_Event* callback) override
{
if (callback)
{
std::lock_guard<std::mutex> lock(m_mutexCallbacks);
m_Callbacks.insert(callback);
}
}
/**
* @brief Unregister Callback
* @param[in] callback function
*/
void UnregisterCallBack(vss::Device::IReceptionSignalSpeed_Event* callback) override
{
if (callback)
{
std::lock_guard<std::mutex> lock(m_mutexCallbacks);
m_Callbacks.erase(callback);
}
}
private:
uint32_t m_Speed = { 0 }; ///< speed value which will be received
mutable std::mutex m_mutexCallbacks; ///< Mutex protecting m_Callbacks
std::set<vss::Device::IReceptionSignalSpeed_Event*> m_Callbacks; ///< collection of events to be called (received value)
vss::Device::ITransferSignalBrakeForce* m_BrakeForce = nullptr; ///< To write the brake force to the abstract device
};
DEFINE_SDV_OBJECT(CBasicService)
Event driven approach: Implement the VAPI Interface which allows any Complex Service or Extern Application to register a callback (the Vehicle Device event), which is called on any signal change so that a Complex Service or Extern Application is automatically updated.