diff --git a/2015-05-01-Note-16-47.xoj b/2015-05-01-Note-16-47.xoj
new file mode 100644
index 00000000..36b00336
Binary files /dev/null and b/2015-05-01-Note-16-47.xoj differ
diff --git a/src/hos_libvariant/src/.hg/store/phaseroots b/config.properties
similarity index 100%
rename from src/hos_libvariant/src/.hg/store/phaseroots
rename to config.properties
diff --git a/src/hos_core_types/launch/setup_core_types.launch b/src/hos_core_types/launch/setup_core_types.launch
index 9060b42f..2230092a 100644
--- a/src/hos_core_types/launch/setup_core_types.launch
+++ b/src/hos_core_types/launch/setup_core_types.launch
@@ -13,4 +13,8 @@
+
+
+
+
\ No newline at end of file
diff --git a/src/hos_core_types/schema/core/configs/rulepackage.json b/src/hos_core_types/schema/core/configs/rulepackage.json
new file mode 100644
index 00000000..3373fb3b
--- /dev/null
+++ b/src/hos_core_types/schema/core/configs/rulepackage.json
@@ -0,0 +1,152 @@
+{
+ "$schema": "http://json-schema.org/draft-04/schema#",
+ "title": "Rule Package",
+ "description": "",
+ "version": "1.0.0",
+ "type": "object",
+ "properties": {
+ "language": {
+ "description": "",
+ "type": "string"
+ },
+ "globalcontext": {
+ "description": "",
+ "type": "object"
+ },
+ "rules": {
+ "description": "",
+ "type": "object",
+ "minProperties": 1,
+ "patternProperties": {
+ ".*": {
+ "type": "object",
+ "properties": {
+ "body": {
+ "type": "string"
+ },
+ "conditions": {
+ "type": "array",
+ "minItems": 1,
+ "items": {
+ "type": "object",
+ "anyOf": [
+ { "$ref": "#/definitions/DeviceMsgCondition" },
+ { "$ref": "#/definitions/DeviceStatusCondition" },
+ { "$ref": "#/definitions/TimeCondition" },
+ { "$ref": "#/definitions/SystemCondition" }
+ ]
+ }
+ }
+ },
+ "additionalProperties": false,
+ "required": [ "name", "conditions", "body" ]
+ }
+ }
+ }
+ },
+ "definitions": {
+ "DeviceMsgCondition": {
+ "type": "object",
+ "properties": {
+ "type": {
+ "description": "",
+ "type": "string",
+ "pattern": "devicemsg"
+ },
+ "deviceid": {
+ "description": "",
+ "type": "string"
+ },
+ "msgtype": {
+ "description": "",
+ "type": "string",
+ "enum": ["status", "command"]
+ },
+ "msgpointer": {
+ "description": "",
+ "type": "string"
+ },
+ "msgvalue": {
+ "description": ""
+ }
+ },
+ "additionalProperties": false,
+ "anyOf": [
+ { "required": [ "type", "deviceid" ] },
+ { "required": [ "type", "deviceid", "msgtype", "msgvalue" ] },
+ { "required": [ "type", "deviceid", "msgtype", "msgpointer" ] }
+ ]
+ },
+ "DeviceStatusCondition": {
+ "type": "object",
+ "properties": {
+ "type": {
+ "description": "",
+ "type": "string",
+ "pattern": "devicestatus"
+ },
+ "deviceid": {
+ "description": "",
+ "type": "string"
+ },
+ "statuspointer": {
+ "description": "",
+ "type": "string"
+ },
+ "fromvalue": {
+ "description": ""
+ },
+ "tovalue": {
+ "description": ""
+ }
+ },
+ "additionalProperties": false,
+ "anyOf": [
+ {"required": [ "type", "deviceid" ] }
+ ]
+ },
+ "TimeCondition": {
+ "type": "object",
+ "properties": {
+ "type": {
+ "description": "",
+ "type": "string",
+ "pattern": "time"
+ },
+ "cron": {
+ "description": "",
+ "type": "string"
+ },
+ "time": {
+ "description": ""
+ }
+ },
+ "additionalProperties": false,
+ "anyOf": [
+ { "required": [ "type", "cron" ] },
+ { "required": [ "type", "time" ] }
+ ]
+ },
+ "SystemCondition": {
+ "type": "object",
+ "properties": {
+ "type": {
+ "description": "",
+ "type": "string",
+ "pattern": "systemevent"
+ },
+ "event": {
+ "description": "",
+ "type": "string",
+ "enum": [ "startup", "shutdown" ]
+ }
+ },
+ "additionalProperties": false,
+ "anyOf": [
+ { "required": [ "type", "event" ] }
+ ]
+ }
+ },
+ "additionalProperties": false,
+ "required": [ "language", "rules" ]
+}
\ No newline at end of file
diff --git a/src/hos_cosgi_core/CMakeLists.txt b/src/hos_cosgi_common/CMakeLists.txt
similarity index 91%
rename from src/hos_cosgi_core/CMakeLists.txt
rename to src/hos_cosgi_common/CMakeLists.txt
index cdb3bbf3..d8575a02 100644
--- a/src/hos_cosgi_core/CMakeLists.txt
+++ b/src/hos_cosgi_common/CMakeLists.txt
@@ -1,5 +1,5 @@
cmake_minimum_required(VERSION 2.8.3)
-project(hos_cosgi_core)
+project(hos_cosgi_common)
## Find catkin macros and libraries
## if COMPONENTS list like find_package(catkin REQUIRED COMPONENTS xyz)
@@ -79,7 +79,7 @@ find_package(catkin REQUIRED COMPONENTS
## DEPENDS: system dependencies of this project that dependent projects also need
catkin_package(
INCLUDE_DIRS include
-# LIBRARIES hos_cosgi_core
+# LIBRARIES hos_cosgi_common
CATKIN_DEPENDS hos_celix
# DEPENDS system_lib
)
@@ -96,19 +96,19 @@ include_directories(
)
## Declare a cpp library
-# add_library(hos_cosgi_core
-# src/${PROJECT_NAME}/hos_cosgi_core.cpp
+# add_library(hos_cosgi_common
+# src/${PROJECT_NAME}/hos_cosgi_common.cpp
# )
## Declare a cpp executable
-# add_executable(hos_cosgi_core_node src/hos_cosgi_core_node.cpp)
+# add_executable(hos_cosgi_common_node src/hos_cosgi_common_node.cpp)
## Add cmake target dependencies of the executable/library
## as an example, message headers may need to be generated before nodes
-# add_dependencies(hos_cosgi_core_node hos_cosgi_core_generate_messages_cpp)
+# add_dependencies(hos_cosgi_common_node hos_cosgi_common_generate_messages_cpp)
## Specify libraries to link a library or executable target against
-# target_link_libraries(hos_cosgi_core_node
+# target_link_libraries(hos_cosgi_common_node
# ${catkin_LIBRARIES}
# )
@@ -127,7 +127,7 @@ include_directories(
# )
## Mark executables and/or libraries for installation
-# install(TARGETS hos_cosgi_core hos_cosgi_core_node
+# install(TARGETS hos_cosgi_common hos_cosgi_common_node
# ARCHIVE DESTINATION ${CATKIN_PACKAGE_LIB_DESTINATION}
# LIBRARY DESTINATION ${CATKIN_PACKAGE_LIB_DESTINATION}
# RUNTIME DESTINATION ${CATKIN_PACKAGE_BIN_DESTINATION}
@@ -152,7 +152,7 @@ install(DIRECTORY include/${PROJECT_NAME}/
#############
## Add gtest based cpp test target and link libraries
-# catkin_add_gtest(${PROJECT_NAME}-test test/test_hos_cosgi_core.cpp)
+# catkin_add_gtest(${PROJECT_NAME}-test test/test_hos_cosgi_common.cpp)
# if(TARGET ${PROJECT_NAME}-test)
# target_link_libraries(${PROJECT_NAME}-test ${PROJECT_NAME})
# endif()
diff --git a/src/hos_cosgi_core/include/hos_cosgi_core/cosgi_core.h b/src/hos_cosgi_common/include/hos_cosgi_common/cosgi_common.h
similarity index 71%
rename from src/hos_cosgi_core/include/hos_cosgi_core/cosgi_core.h
rename to src/hos_cosgi_common/include/hos_cosgi_common/cosgi_common.h
index 5309e260..591bfb53 100644
--- a/src/hos_cosgi_core/include/hos_cosgi_core/cosgi_core.h
+++ b/src/hos_cosgi_common/include/hos_cosgi_common/cosgi_common.h
@@ -1,12 +1,12 @@
/*
- * cosgi_core.h
+ * cosgi_common.h
*
* Created on: 19.04.2015
* Author: matzman
*/
-#ifndef INCLUDE_HOS_COSGI_CORE_COSGI_CORE_H_
-#define INCLUDE_HOS_COSGI_CORE_COSGI_CORE_H_
+#ifndef INCLUDE_HOS_COSGI_COMMON_COSGI_CORE_H_
+#define INCLUDE_HOS_COSGI_COMMON_COSGI_CORE_H_
namespace hos {
@@ -29,4 +29,4 @@ public:
} // namespace cosgi
} // namespace hos
-#endif /* INCLUDE_HOS_COSGI_CORE_COSGI_CORE_H_ */
+#endif /* INCLUDE_HOS_COSGI_COMMON_COSGI_CORE_H_ */
diff --git a/src/hos_cosgi_core/package.xml b/src/hos_cosgi_common/package.xml
similarity index 91%
rename from src/hos_cosgi_core/package.xml
rename to src/hos_cosgi_common/package.xml
index 41f67a15..ff9931f9 100644
--- a/src/hos_cosgi_core/package.xml
+++ b/src/hos_cosgi_common/package.xml
@@ -1,8 +1,8 @@
- hos_cosgi_core
+ hos_cosgi_common
0.0.0
- The hos_cosgi_core package
+ The hos_cosgi_common package
@@ -19,7 +19,7 @@
-
+
diff --git a/src/hos_cosgi_devicerepository/CMakeLists.txt b/src/hos_cosgi_devicerepository/CMakeLists.txt
index 6192ad19..e82d5d3f 100644
--- a/src/hos_cosgi_devicerepository/CMakeLists.txt
+++ b/src/hos_cosgi_devicerepository/CMakeLists.txt
@@ -8,7 +8,7 @@ find_package(catkin REQUIRED COMPONENTS
hos_celix
hos_core_msgs
hos_cosgi_launcher
- hos_cosgi_core
+ hos_cosgi_common
hos_libvariant
hos_cpp_common
roscpp
@@ -91,7 +91,7 @@ find_package(Boost REQUIRED)
catkin_package(
INCLUDE_DIRS include
# LIBRARIES hos_cosgi_devicerepository
- CATKIN_DEPENDS hos_celix hos_core_msgs hos_cosgi_launcher roscpp hos_cosgi_core hos_libvariant hos_cpp_common
+ CATKIN_DEPENDS hos_celix hos_core_msgs hos_cosgi_launcher roscpp hos_cosgi_common hos_libvariant hos_cpp_common
# DEPENDS system_lib
)
@@ -122,7 +122,6 @@ bundle(hos_cosgi_devicerepository
SOURCES
${PROJECT_SOURCE_DIR}/src/bundle_activator
${PROJECT_SOURCE_DIR}/src/hos_devicerepository_service_impl
- ${PROJECT_SOURCE_DIR}/src/HosSchemaLoader
)
target_link_libraries(hos_cosgi_devicerepository
${catkin_LIBRARIES}
diff --git a/src/hos_cosgi_devicerepository/include/hos_cosgi_devicerepository/hos_devicerepository_service.h b/src/hos_cosgi_devicerepository/include/hos_cosgi_devicerepository/hos_devicerepository_service.h
index e64b7c77..de2606a7 100644
--- a/src/hos_cosgi_devicerepository/include/hos_cosgi_devicerepository/hos_devicerepository_service.h
+++ b/src/hos_cosgi_devicerepository/include/hos_cosgi_devicerepository/hos_devicerepository_service.h
@@ -2,64 +2,87 @@
#define _HOS_DEVICEREPOSITORY_SERVICE_H_
-#include
+#include
#include
#include
#include
+#include
+
+// Forward declarations
namespace libvariant {
-class Variant;
+ class Variant;
+}
+namespace hos {
+ namespace cosgi {
+ namespace devicerepository {
+ class Device;
+ }
+ }
}
+
+// Service Namespace
namespace hos {
namespace cosgi {
+namespace devicerepository {
-class DeviceEvent;
-class GenericDevice;
-
+/**
+ * Base class for device events
+ **/
class DeviceEvent {
public:
enum class EventType : int { DEVICE_ADDED = 1, DEVICE_REMOVED = 2, STATUS_UPDATED = 3, COMMAND_RECEIVED = 4 };
- DeviceEvent(GenericDevice* device, EventType type) : device(device), eventType(type) {}
- GenericDevice* device;
- EventType eventType;
- template T* as() { return (T*)this; }
- template const T* as() const { return (T*)this; }
+ const EventType eventType;
+ Device* const device;
+ DeviceEvent(Device* device, EventType type) : device(device), eventType(type) {}
};
-
+ /**
+ * Device added
+ **/
class DeviceAddedEvent : public DeviceEvent {
public:
- DeviceAddedEvent(GenericDevice* device)
- : DeviceEvent(device, DeviceEvent::EventType::DEVICE_ADDED) {}
+ DeviceAddedEvent(Device* device) : DeviceEvent(device, DeviceEvent::EventType::DEVICE_ADDED) {}
};
+/**
+ * Device removed
+ **/
class DeviceRemovedEvent : public DeviceEvent {
public:
- DeviceRemovedEvent(GenericDevice* device)
- : DeviceEvent(device, DeviceEvent::EventType::DEVICE_REMOVED) {}
+ DeviceRemovedEvent(Device* device) : DeviceEvent(device, DeviceEvent::EventType::DEVICE_REMOVED) {}
};
-class DeviceStatusEvent : public DeviceEvent {
+/**
+ * Device status message received
+ **/
+class DeviceStatusMsgEvent : public DeviceEvent {
public:
- DeviceStatusEvent(GenericDevice* device, const libvariant::Variant& statusMsg)
+ DeviceStatusMsgEvent(Device* device, const libvariant::Variant& statusMsg)
: DeviceEvent(device, DeviceEvent::EventType::STATUS_UPDATED), statusMsg(statusMsg) {}
const libvariant::Variant& statusMsg;
};
-class DeviceCmdEvent : public DeviceEvent {
+/**
+ * Device command message received
+ **/
+class DeviceCmdMsgEvent : public DeviceEvent {
public:
- DeviceCmdEvent(GenericDevice* device, const libvariant::Variant& cmdMsg)
+ DeviceCmdMsgEvent(Device* device, const libvariant::Variant& cmdMsg)
: DeviceEvent(device, DeviceEvent::EventType::COMMAND_RECEIVED), cmdMsg(cmdMsg) {}
const libvariant::Variant& cmdMsg;
};
-class GenericDevice : public COSGI_Object_Interface, public common::IObservable {
+/**
+ * Public interface of an device object
+ **/
+class Device : public COSGI_Object_Interface, public common::IObservable {
public:
virtual const std::string& getDeviceID() = 0;
virtual const std::string& getDeviceType() = 0;
@@ -71,18 +94,26 @@ public:
};
+
+/**
+ * Public Interface of the device repository service
+ **/
class HOSDeviceRepositoryService : public COSGI_Service_Interface, public common::IObservable {
public:
static constexpr const char* SERVICE_NAME = "hos_devicerepository_service";
static constexpr int SERVICE_VERSION_MAJOR = 1;
static constexpr int SERVICE_VERSION_MINOR = 0;
- virtual GenericDevice* getDevice(std::string device_id) = 0;
- virtual std::vector& getDevices(std::vector& devices) = 0;
+ virtual std::shared_ptr getDevice(std::string device_id) = 0;
+ virtual size_t getDevices(std::vector>& devices) = 0;
};
+
+} // namespace devicerepository
} // namespace cosgi
} // namespace hos
+
+
#endif /* _HOS_DEVICEREPOSITORY_SERVICE_H_ */
diff --git a/src/hos_cosgi_devicerepository/launch/cosgi_devicerepository.launch b/src/hos_cosgi_devicerepository/launch/cosgi_devicerepository.launch
index ec7ad252..65876dda 100644
--- a/src/hos_cosgi_devicerepository/launch/cosgi_devicerepository.launch
+++ b/src/hos_cosgi_devicerepository/launch/cosgi_devicerepository.launch
@@ -1,5 +1,5 @@
-
+
\ No newline at end of file
diff --git a/src/hos_cosgi_devicerepository/package.xml b/src/hos_cosgi_devicerepository/package.xml
index 89eb22e8..465d5939 100644
--- a/src/hos_cosgi_devicerepository/package.xml
+++ b/src/hos_cosgi_devicerepository/package.xml
@@ -44,14 +44,14 @@
hos_core_msgs
hos_cosgi_launcher
roscpp
- hos_cosgi_core
+ hos_cosgi_common
hos_libvariant
hos_cpp_common
hos_celix
hos_core_msgs
hos_cosgi_launcher
roscpp
- hos_cosgi_core
+ hos_cosgi_common
hos_libvariant
hos_cpp_common
diff --git a/src/hos_cosgi_devicerepository/src/bundle_activator.cpp b/src/hos_cosgi_devicerepository/src/bundle_activator.cpp
index a4f67a00..9812e3e3 100644
--- a/src/hos_cosgi_devicerepository/src/bundle_activator.cpp
+++ b/src/hos_cosgi_devicerepository/src/bundle_activator.cpp
@@ -14,65 +14,18 @@ extern "C" {
#include
#include "hos_devicerepository_service_impl.h"
-using namespace hos::cosgi;
-
-
#include
#include
+#include
-class Test01 : public hos::common::IObserver {
-public:
- void notificationReceived(hos::common::IObservable& o, const DeviceEvent* e) {
- switch (e->eventType) {
- case DeviceEvent::EventType::DEVICE_ADDED:
- {
- std::cout << "DeviceEvent: Device added: " << e->device->getDeviceID() << std::endl;
- }
- break;
- case DeviceEvent::EventType::DEVICE_REMOVED:
- {
- std::cout << "DeviceEvent: Device removed: " << e->device->getDeviceID() << std::endl;
- }
- break;
- case DeviceEvent::EventType::STATUS_UPDATED:
- {
- auto event = e->as();
- std::cout << "DeviceEvent: Device Updated: " << e->device->getDeviceID() << std::endl;
- std::cout << "message: ";
- libvariant::SerializeJSON(stdout, event->statusMsg, true);
- std::cout << std::endl;
- std::cout << "current: ";
- libvariant::SerializeJSON(stdout, event->device->getCurrentState(), true);
- std::cout << std::endl;
- std::cout << "last: ";
- libvariant::SerializeJSON(stdout, event->device->getLastState(), true);
- std::cout << std::endl;
- }
- break;
- case DeviceEvent::EventType::COMMAND_RECEIVED:
- {
- auto event = e->as();
- std::cout << "DeviceEvent: Device Command: " << e->device->getDeviceID() << std::endl;
- std::cout << "message: ";
- libvariant::SerializeJSON(stdout, event->statusMsg, true);
- std::cout << std::endl;
- }
- break;
- default:
- {
- std::cout << "DeviceEvent: Unknown event." << std::endl;
- }
- break;
- };
- }
-
-} test01;
+using namespace hos::cosgi;
+using namespace hos::cosgi::devicerepository;
struct UserData {
apr_pool_t* memoryPool = nullptr;
- hos::cosgi::HOSDeviceRepositoryServiceImpl* serviceImpl = nullptr;
+ std::unique_ptr serviceImpl;
service_registration_pt serviceReg = nullptr;
};
@@ -100,33 +53,29 @@ celix_status_t bundleActivator_create(bundle_context_pt context, void **userData
}
celix_status_t bundleActivator_start(void * userData, bundle_context_pt context) {
- celix_status_t status = CELIX_START_ERROR;
+ celix_status_t status = CELIX_SUCCESS;
if (userData != nullptr) {
UserData* myUserData = (UserData*)userData;
+ // Create hos-devicerepository-service
+ if (myUserData->serviceReg != nullptr) {
+ serviceRegistration_unregister(myUserData->serviceReg);
+ }
+ myUserData->serviceImpl.reset(new HOSDeviceRepositoryServiceImpl());
// Get HOS Core Service
service_reference_pt ref = nullptr;
- bundleContext_getServiceReference(context, (char*)HOSCoreService::SERVICE_NAME, &ref);
- hos::cosgi::HOSCoreService* coreService = nullptr;
+ bundleContext_getServiceReference(context, (char*)core::HOSCoreService::SERVICE_NAME, &ref);
+ core::HOSCoreService* coreService = nullptr;
bundleContext_getService(context, ref, (void**)&coreService);
if (coreService == nullptr) {
- ROS_ERROR("DeviceRepositoryService: Could not retrieve HOSCoreService.");
+ ROS_ERROR("DeviceRepositoryService: Could not retrieve HOSCoreService. Are you using hos_cosgi_launcher?");
} else {
- int major = 0, minor = 0;
- coreService->getServiceVersion(major, minor);
- ROS_INFO_STREAM("DeviceRepositoryService: Found HOSCoreService Version " << major << "." << minor);
- // Create and register hos-devicerepository-service
- if (myUserData->serviceReg != nullptr) {
- serviceRegistration_unregister(myUserData->serviceReg);
- }
- if (myUserData->serviceImpl != nullptr) {
- delete myUserData->serviceImpl;
- }
- myUserData->serviceImpl = new hos::cosgi::HOSDeviceRepositoryServiceImpl(*coreService);
- myUserData->serviceImpl->addObserver(test01);
- bundleContext_registerService(context, (char*)hos::cosgi::HOSDeviceRepositoryService::SERVICE_NAME, myUserData->serviceImpl, nullptr, &myUserData->serviceReg);
- status = CELIX_SUCCESS;
- ROS_INFO("DeviceRepositoryService: Bundle successfully started");
+ myUserData->serviceImpl->setCoreService(coreService);
}
+ // Register hos-devicerepository-service
+ if (myUserData->serviceImpl->isInitialized()) {
+ bundleContext_registerService(context, (char*)HOSDeviceRepositoryService::SERVICE_NAME, myUserData->serviceImpl.get(), nullptr, &myUserData->serviceReg);
+ }
+ ROS_INFO("DeviceRepositoryService: Bundle successfully started");
} else {
ROS_ERROR("DeviceRepositoryService: Could not start bundle, user data struct is null");
}
@@ -138,16 +87,11 @@ celix_status_t bundleActivator_stop(void * userData, bundle_context_pt context)
if (userData != nullptr) {
UserData* myUserData = (UserData*)userData;
if (myUserData->serviceReg != nullptr) {
- if (myUserData->serviceImpl->getRefCount() > 0) {
- frameworkLogger_log(OSGI_FRAMEWORK_LOG_ERROR, 0, 0, 0, (char*)"RefCount > 0");
- return status;
- }
serviceRegistration_unregister(myUserData->serviceReg);
myUserData->serviceReg = nullptr;
}
- if (myUserData->serviceImpl != nullptr) {
- delete myUserData->serviceImpl;
- myUserData->serviceImpl = nullptr;
+ if (myUserData->serviceImpl) {
+ myUserData->serviceImpl.reset();
}
ROS_INFO("DeviceRepositoryService: Bundle successfully stopped");
status = CELIX_SUCCESS;
diff --git a/src/hos_cosgi_devicerepository/src/hos_devicerepository_service_impl.cpp b/src/hos_cosgi_devicerepository/src/hos_devicerepository_service_impl.cpp
index 8a3efc2d..77fd2c48 100644
--- a/src/hos_cosgi_devicerepository/src/hos_devicerepository_service_impl.cpp
+++ b/src/hos_cosgi_devicerepository/src/hos_devicerepository_service_impl.cpp
@@ -7,44 +7,57 @@
#include "hos_devicerepository_service_impl.h"
#include
-#include "HosSchemaLoader.h"
#include
#include
#include
#include
+
+
namespace hos {
namespace cosgi {
+namespace devicerepository {
-GenericDeviceImpl::GenericDeviceImpl(std::string deviceID, std::string type, std::string statusTopic, std::string cmdTopic)
+DeviceImpl::DeviceImpl(std::string deviceID, std::string type, std::string statusTopic, std::string cmdTopic)
: deviceID(deviceID), deviceType(type), statusTopic(statusTopic), cmdTopic(cmdTopic) {
std::cout << "GenericDeviceImpl(" << deviceID << ", " << type << ", " << statusTopic << ", " << cmdTopic << ")" << std::endl;
}
-void GenericDeviceImpl::handleStatusMsg(libvariant::Variant& msg) {
+void DeviceImpl::handleStatusMsg(Variant& msg) {
+ std::lock_guard lock(objMutex);
lastState = currentState.Copy();
currentState.Merge(msg);
- DeviceStatusEvent event(this, msg);
+ DeviceStatusMsgEvent event(this, msg);
notifyObservers(&event);
}
-void GenericDeviceImpl::handleCommandMsg(libvariant::Variant& msg) {
- DeviceCmdEvent event(this, msg);
+void DeviceImpl::handleCommandMsg(Variant& msg) {
+ std::lock_guard lock(objMutex);
+ DeviceCmdMsgEvent event(this, msg);
notifyObservers(&event);
}
+void HOSDeviceRepositoryServiceImpl::setCoreService(core::HOSCoreService* coreService) {
+ if (coreService && !this->coreService) {
+ this->coreService = coreService;
+ this->nodehandle = coreService->getPrivateNodeHandle();
+ int major = 0, minor = 0;
+ coreService->getServiceVersion(major, minor);
+ ROS_INFO_STREAM("DeviceRepositoryService: Found HOSCoreService Version " << major << "." << minor);
+ init();
+ }
+}
-HOSDeviceRepositoryServiceImpl::HOSDeviceRepositoryServiceImpl(HOSCoreService& coreService)
- : coreService(coreService), nodehandle(coreService.getPrivateNodeHandle()) {
- nodehandle.getParam("device_repository_prefix", deviceRepositoryPrefix);
- nodehandle.getParam("hos_status_topic", hosStatusTopic);
+void HOSDeviceRepositoryServiceImpl::init() {
+ nodehandle->getParam("device_repository_prefix", deviceRepositoryPrefix);
+ nodehandle->getParam("hos_status_topic", hosStatusTopic);
XmlRpc::XmlRpcValue rawValue;
- nodehandle.getParam(deviceRepositoryPrefix, rawValue);
+ nodehandle->getParam(deviceRepositoryPrefix, rawValue);
if (rawValue.getType() == XmlRpc::XmlRpcValue::TypeStruct) {
- for (auto iter = rawValue.begin(); iter != rawValue.end(); iter++) {
- std::string devname = (*iter).first;
- XmlRpc::XmlRpcValue devRaw = (*iter).second;
+ for (auto dev : rawValue) {
+ std::string devname = dev.first;
+ XmlRpc::XmlRpcValue devRaw = dev.second;
try {
addDevice(devname, devRaw);
ROS_INFO_STREAM("Created device " << devname << ".");
@@ -53,47 +66,22 @@ HOSDeviceRepositoryServiceImpl::HOSDeviceRepositoryServiceImpl(HOSCoreService& c
}
}
}
- hosStatusSub = nodehandle.subscribe(hosStatusTopic, 1000, &HOSDeviceRepositoryServiceImpl::hosStatusMsgCallback, this);
- schemaLoader = new HosSchemaLoader();
+ hosStatusSub = nodehandle->subscribe(hosStatusTopic, 1000, &HOSDeviceRepositoryServiceImpl::hosStatusMsgCallback, this);
+ schemaLoader.reset(new libvariant::HosSchemaLoader());
+ initialized = true;
+ ROS_INFO_STREAM("DeviceRepositoryService: Initialized and Ready.");
}
void HOSDeviceRepositoryServiceImpl::addDevice(std::string name) {
std::stringstream ss;
ss << deviceRepositoryPrefix << "/" << name;
XmlRpc::XmlRpcValue rawValue;
- nodehandle.getParam(ss.str(), rawValue);
+ nodehandle->getParam(ss.str(), rawValue);
addDevice(name, rawValue);
}
void HOSDeviceRepositoryServiceImpl::addDevice(std::string name, XmlRpc::XmlRpcValue& rawValue) {
- GenericDevice* dev = _createDevice(name, rawValue);
- if (dev != nullptr) {
- devices.insert({name, dev});
- // cmd topic
- auto& entry = subscripedTopics[dev->getCmdTopic()];
- std::cout << "subCount1: " << entry.first << "." << std::endl;
- if (entry.first <= 0) {
- entry.second = nodehandle.subscribe(dev->getCmdTopic(), 1000, &HOSDeviceRepositoryServiceImpl::cmdMsgCallback, this);
- std::cout << "subscriped to " << dev->getCmdTopic() << "." << std::endl;
- }
- entry.first= entry.first + 1;
- subscripedTopics[dev->getCmdTopic()] = entry;
- // status topic
- entry = subscripedTopics[dev->getStatusTopic()];
- std::cout << "subCount2: " << entry.first << "." << std::endl;
- if (entry.first <= 0) {
- entry.second = nodehandle.subscribe(dev->getStatusTopic(), 1000, &HOSDeviceRepositoryServiceImpl::statusMsgCallback, this);
- std::cout << "subscriped to " << dev->getStatusTopic() << "." << std::endl;
- }
- entry.first= entry.first + 1;
- subscripedTopics[dev->getStatusTopic()] = entry;
- DeviceAddedEvent event(dev);
- notifyObservers(&event);
- }
-}
-
-
-GenericDevice* HOSDeviceRepositoryServiceImpl::_createDevice(std::string name, XmlRpc::XmlRpcValue& rawValue) {
+ std::lock_guard lock(serviceMutex);
std::string type, statusTopic, cmdTopic;
XmlRpc::XmlRpcValue& typeRaw = rawValue["type"];
if (typeRaw.getType() != XmlRpc::XmlRpcValue::TypeString) {
@@ -110,31 +98,56 @@ GenericDevice* HOSDeviceRepositoryServiceImpl::_createDevice(std::string name, X
throw std::runtime_error("cmdTopic is not a string.");
}
cmdTopic = static_cast(cmdTopicRaw);
- return new GenericDeviceImpl(name, type, statusTopic, cmdTopic);
+ std::shared_ptr dev = std::make_shared(name, type, statusTopic, cmdTopic);
+ devices.insert({name, dev});
+ // cmd topic
+ auto& entry = subscripedTopics[dev->getCmdTopic()];
+ std::cout << "subCount1: " << entry.first << "." << std::endl;
+ if (entry.first <= 0) {
+ entry.second = nodehandle->subscribe(dev->getCmdTopic(), 1000, &HOSDeviceRepositoryServiceImpl::cmdMsgCallback, this);
+ std::cout << "subscriped to " << dev->getCmdTopic() << "." << std::endl;
+ }
+ entry.first= entry.first + 1;
+ subscripedTopics[dev->getCmdTopic()] = entry;
+ // status topic
+ entry = subscripedTopics[dev->getStatusTopic()];
+ std::cout << "subCount2: " << entry.first << "." << std::endl;
+ if (entry.first <= 0) {
+ entry.second = nodehandle->subscribe(dev->getStatusTopic(), 1000, &HOSDeviceRepositoryServiceImpl::statusMsgCallback, this);
+ std::cout << "subscriped to " << dev->getStatusTopic() << "." << std::endl;
+ }
+ entry.first= entry.first + 1;
+ subscripedTopics[dev->getStatusTopic()] = entry;
+ // send device added event
+ DeviceAddedEvent event(dev.get());
+ notifyObservers(&event);
}
void HOSDeviceRepositoryServiceImpl::removeDevice(std::string name) {
- GenericDevice* dev = devices[name];
- if (dev != nullptr) {
- DeviceRemovedEvent event(dev);
+ std::lock_guard lock(serviceMutex);
+ auto& dev = devices[name];
+ if (dev) {
+ DeviceRemovedEvent event(dev.get());
notifyObservers(&event);
dev->notifyObservers(&event);
devices.erase(name);
- delete dev;
}
}
-GenericDevice* HOSDeviceRepositoryServiceImpl::getDevice(std::string device_id) {
- return this->devices[device_id];
+std::shared_ptr HOSDeviceRepositoryServiceImpl::getDevice(std::string device_id) {
+ return std::static_pointer_cast(this->devices[device_id]);
}
-std::vector& HOSDeviceRepositoryServiceImpl::getDevices(std::vector& devices) {
+size_t HOSDeviceRepositoryServiceImpl::getDevices(std::vector>& devices) {
+ std::lock_guard lock(serviceMutex);
+ size_t retval = 0;
for (auto item : this->devices) {
- devices.push_back(item.second);
+ devices.push_back(std::static_pointer_cast(item.second));
+ retval++;
}
- return devices;
+ return retval;
}
@@ -143,21 +156,18 @@ void HOSDeviceRepositoryServiceImpl::getServiceVersion(int& major, int& minor) {
minor = SERVICE_VERSION_MINOR;
}
-int HOSDeviceRepositoryServiceImpl::getRefCount() {
- return 0;
-}
-
void HOSDeviceRepositoryServiceImpl::statusMsgCallback(const hos_core_msgs::DeviceStatusUpdate::ConstPtr& msg) {
+ std::lock_guard lock(serviceMutex);
std::cout << "HOSDeviceRepositoryServiceImpl::statusMsgCallback" << std::endl;
- libvariant::Variant s = schemaLoader->GetSchema(std::string("hos:schema://").append(msg->device_type).append("/status"));
- libvariant::Variant m = libvariant::Deserialize(msg->msg_body, libvariant::SERIALIZE_JSON);
- libvariant::SchemaResult sr = libvariant::SchemaValidate(s, m, schemaLoader);
+ Variant s = schemaLoader->GetSchema(std::string("hos:schema://").append(msg->device_type).append("/status"));
+ Variant m = Deserialize(msg->msg_body, SERIALIZE_JSON);
+ SchemaResult sr = SchemaValidate(s, m, schemaLoader.get());
if (!sr.Error()) {
- GenericDevice* dev = devices[msg->device_id];
- if (dev != nullptr) {
- ((GenericDeviceImpl*)dev)->handleStatusMsg(m);
- DeviceStatusEvent event(dev, m);
+ std::shared_ptr dev = std::static_pointer_cast(devices[msg->device_id]);
+ if (dev) {
+ dev->handleStatusMsg(m);
+ DeviceStatusMsgEvent event(dev.get(), m);
notifyObservers(&event);
}
} else {
@@ -166,15 +176,16 @@ void HOSDeviceRepositoryServiceImpl::statusMsgCallback(const hos_core_msgs::Devi
}
void HOSDeviceRepositoryServiceImpl::cmdMsgCallback(const hos_core_msgs::DeviceCommand::ConstPtr& msg) {
+ std::lock_guard lock(serviceMutex);
std::cout << "HOSDeviceRepositoryServiceImpl::cmdMsgCallback" << std::endl;
- libvariant::Variant s = schemaLoader->GetSchema(std::string("hos:schema://").append(msg->device_type).append("/command"));
- libvariant::Variant m = libvariant::Deserialize(msg->msg_body, libvariant::SERIALIZE_JSON);
- libvariant::SchemaResult sr = libvariant::SchemaValidate(s, m, schemaLoader);
+ Variant s = schemaLoader->GetSchema(std::string("hos:schema://").append(msg->device_type).append("/command"));
+ Variant m = Deserialize(msg->msg_body, SERIALIZE_JSON);
+ SchemaResult sr = SchemaValidate(s, m, schemaLoader.get());
if (!sr.Error()) {
- GenericDevice* dev = devices[msg->device_id];
+ std::shared_ptr dev = std::static_pointer_cast(devices[msg->device_id]);
if (dev != nullptr) {
- ((GenericDeviceImpl*)dev)->handleCommandMsg(m);
- DeviceCmdEvent event(dev, m);
+ dev->handleCommandMsg(m);
+ DeviceCmdMsgEvent event(dev.get(), m);
notifyObservers(&event);
}
} else {
@@ -183,10 +194,11 @@ void HOSDeviceRepositoryServiceImpl::cmdMsgCallback(const hos_core_msgs::DeviceC
}
void HOSDeviceRepositoryServiceImpl::hosStatusMsgCallback(const hos_core_msgs::HosStatusUpdate::ConstPtr& msg) {
+ std::lock_guard lock(serviceMutex);
std::cout << "HOSDeviceRepositoryServiceImpl::hosStatusMsgCallback" << std::endl;
- libvariant::Variant s = schemaLoader->GetSchema(std::string("hos:schema://core/msgs/hosstatusupdate"));
- libvariant::Variant m = libvariant::Deserialize(msg->msg_body, libvariant::SERIALIZE_JSON);
- libvariant::SchemaResult sr = libvariant::SchemaValidate(s, m, schemaLoader);
+ Variant s = schemaLoader->GetSchema(std::string("hos:schema://core/msgs/hosstatusupdate"));
+ Variant m = Deserialize(msg->msg_body, SERIALIZE_JSON);
+ SchemaResult sr = SchemaValidate(s, m, schemaLoader.get());
if (!sr.Error()) {
if (m.Contains("devices")) {
auto d = m["devices"];
@@ -217,6 +229,7 @@ void HOSDeviceRepositoryServiceImpl::hosStatusMsgCallback(const hos_core_msgs::H
}
+} // namespace devicerepository
} // namespace cosgi
} // namespace hos
diff --git a/src/hos_cosgi_devicerepository/src/hos_devicerepository_service_impl.h b/src/hos_cosgi_devicerepository/src/hos_devicerepository_service_impl.h
index c69940ce..10c59325 100644
--- a/src/hos_cosgi_devicerepository/src/hos_devicerepository_service_impl.h
+++ b/src/hos_cosgi_devicerepository/src/hos_devicerepository_service_impl.h
@@ -10,94 +10,136 @@
#include
#include
+#include
#include
#include