diff --git a/CMakeLists.txt b/CMakeLists.txt
new file mode 100644
index 0000000..a3f9f81
--- /dev/null
+++ b/CMakeLists.txt
@@ -0,0 +1,60 @@
+# Copyright 2018 Proyectos y Sistemas de Mantenimiento SL (eProsima).
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+
+# Set CMake version
+cmake_minimum_required(VERSION 3.5)
+
+
+# Set proyect name
+project(micro_ros_agent)
+
+
+# Find packages depencences
+find_package(ament_cmake REQUIRED)
+find_package(fastcdr REQUIRED CONFIG)
+find_package(fastrtps REQUIRED CONFIG)
+find_package(micrortps_agent REQUIRED CONFIG)
+find_package(ament_cmake_python REQUIRED)
+
+
+# Export dependencies to downstream packages
+ament_export_dependencies(fastcdr)
+ament_export_dependencies(fastrtps)
+ament_export_dependencies(micrortps_agent)
+
+
+# Install python files
+ament_python_install_package(${PROJECT_NAME})
+
+
+# Register package resource in order to be called when a new msg package is generated
+ament_index_register_resource("rosidl_typesupport_c")
+
+
+# Install the package.xml file, and generate code for ``find_package`` so that other packages can get information about this package.
+ament_package(
+ CONFIG_EXTRAS "micro_ros_agent-extras.cmake.in"
+)
+
+
+install(
+ PROGRAMS bin/micro_ros_agent
+ DESTINATION lib/micro_ros_agent
+)
+
+install(
+ DIRECTORY cmake resource
+ DESTINATION share/${PROJECT_NAME}
+)
\ No newline at end of file
diff --git a/bin/micro_ros_agent b/bin/micro_ros_agent
new file mode 100644
index 0000000..a717221
--- /dev/null
+++ b/bin/micro_ros_agent
@@ -0,0 +1,45 @@
+#!/usr/bin/env python3
+
+import argparse
+import os
+import sys
+
+from rosidl_cmake import read_generator_arguments
+from rosidl_parser import UnknownMessageType
+from micro_ros_agent import generate_micro_ros_agent_xml_support
+
+def is_valid_file(parser, file_name):
+ if not os.path.exists(file_name):
+ parser.error("File does not exist: '{0}'".format(file_name))
+ file_name_abs = os.path.abspath(file_name)
+ if not os.path.isfile(file_name_abs):
+ parser.error("Path exists but is not a file: '{0}'".format(file_name_abs))
+ return file_name
+
+
+def main(argv=sys.argv[1:]):
+ parser = argparse.ArgumentParser(
+ description='Generate xml files for micrortps agent.',
+ formatter_class=argparse.ArgumentDefaultsHelpFormatter)
+ parser.add_argument(
+ '--generator-arguments-file',
+ required=True,
+ help='The location of the file containing the generator arguments')
+ args = parser.parse_args(argv)
+
+ generator_args = read_generator_arguments(args.generator_arguments_file)
+
+ try:
+ rc = generate_micro_ros_agent_xml_support(generator_args)
+
+ return 0
+ except UnknownMessageType as e:
+ print(str(e), file=sys.stderr)
+ return 1
+ if rc:
+ return rc
+ return 0
+
+
+if __name__ == '__main__':
+ sys.exit(main())
diff --git a/cmake/micrortps_agent_xml_generator.cmake b/cmake/micrortps_agent_xml_generator.cmake
new file mode 100644
index 0000000..6f269f0
--- /dev/null
+++ b/cmake/micrortps_agent_xml_generator.cmake
@@ -0,0 +1,69 @@
+# Copyright 2016-2018 Proyectos y Sistemas de Mantenimiento SL (eProsima).
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+
+# list msg files
+set(_ros_idl_files "")
+foreach(_idl_file ${rosidl_generate_interfaces_IDL_FILES})
+ get_filename_component(_extension "${_idl_file}" EXT)
+ # Skip .srv files
+ if(_extension STREQUAL ".msg")
+ list(APPEND _ros_idl_files "${_idl_file}")
+ endif()
+endforeach()
+
+
+# Set output dir
+set(_output_path "${CMAKE_CURRENT_BINARY_DIR}/../micro_ros_agent/xml_gen")
+
+
+# check if all templates exits
+set(target_dependencies
+ "${micro_ros_agent_BIN}"
+ "${micro_ros_agent_GENERATOR_FILES}"
+ ${rosidl_generate_interfaces_IDL_FILES}
+ ${_dependency_files})
+foreach(dep ${target_dependencies})
+ if(NOT EXISTS "${dep}")
+ message(FATAL_ERROR "Target dependency '${dep}' does not exist")
+ endif()
+endforeach()
+
+
+# generate script argument file
+set(generator_arguments_file "${CMAKE_CURRENT_BINARY_DIR}/micro_ros_agent__arguments.json")
+rosidl_write_generator_arguments(
+ "${generator_arguments_file}"
+ PACKAGE_NAME "${PROJECT_NAME}"
+ ROS_INTERFACE_FILES "${rosidl_generate_interfaces_IDL_FILES}"
+ ROS_INTERFACE_DEPENDENCIES "${_dependencies}"
+ OUTPUT_DIR "${_output_path}"
+ TEMPLATE_DIR "${micro_ros_agent_DEFAULT_PROFILES_DIR}"
+ TARGET_DEPENDENCIES ${target_dependencies}
+ ADDITIONAL_FILES ${_dds_idl_files}
+)
+
+
+# Execute python script
+execute_process(
+ COMMAND ${PYTHON_EXECUTABLE} ${micro_ros_agent_BIN}
+ --generator-arguments-file "${generator_arguments_file}"
+ )
+
+
+#Install
+install(
+ DIRECTORY "${_output_path}/"
+ DESTINATION "../micrortps_agent/bin"
+)
\ No newline at end of file
diff --git a/micro_ros_agent-extras.cmake.in b/micro_ros_agent-extras.cmake.in
new file mode 100644
index 0000000..aa4e047
--- /dev/null
+++ b/micro_ros_agent-extras.cmake.in
@@ -0,0 +1,14 @@
+find_package(ament_cmake_core QUIET REQUIRED)
+ament_register_extension(
+ "rosidl_generate_interfaces"
+ "micro_ros_agent"
+ "micrortps_agent_xml_generator.cmake")
+
+set(micro_ros_agent_BIN "${micro_ros_agent_DIR}/../../../lib/micro_ros_agent/micro_ros_agent")
+normalize_path(micro_ros_agent_BIN "${micro_ros_agent_BIN}")
+
+set(micro_ros_agent_GENERATOR_FILES "${micro_ros_agent_DIR}/../../../@PYTHON_INSTALL_DIR@/micro_ros_agent/__init__.py")
+normalize_path(micro_ros_agent_GENERATOR_FILES "${micro_ros_agent_GENERATOR_FILES}")
+
+set(micro_ros_agent_DEFAULT_PROFILES_DIR "${micro_ros_agent_DIR}/../resource")
+normalize_path(micro_ros_agent_DEFAULT_PROFILES_DIR "${micro_ros_agent_DEFAULT_PROFILES_DIR}")
\ No newline at end of file
diff --git a/micro_ros_agent/__init__.py b/micro_ros_agent/__init__.py
new file mode 100644
index 0000000..34ad0b0
--- /dev/null
+++ b/micro_ros_agent/__init__.py
@@ -0,0 +1,241 @@
+# Copyright 2016-2018 Proyectos y Sistemas de Mantenimiento SL (eProsima).
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+import struct
+import os
+import sys
+
+if os.name == 'nt':
+ import win32con
+ import win32file
+ import pywintypes
+ __overlapped = pywintypes.OVERLAPPED()
+elif os.name == 'posix':
+ import fcntl
+else:
+ raise RuntimeError('PortaLocker only defined for nt and posix platforms')
+
+from rosidl_cmake import convert_camel_case_to_lower_case_underscore
+from rosidl_cmake import expand_template
+from rosidl_cmake import extract_message_types
+from rosidl_cmake import get_newest_modification_time
+from rosidl_parser import parse_message_file
+from rosidl_parser import parse_service_file
+from rosidl_parser import validate_field_types
+from shutil import copyfile
+from pathlib import Path
+
+
+def generate_micro_ros_agent_xml_support(args):
+ pkg_name = args['package_name']
+ known_msg_types = extract_message_types(
+ pkg_name, args['ros_interface_files'], args.get('ros_interface_dependencies', []))
+
+ functions = {
+ 'get_header_filename_from_msg_name': convert_camel_case_to_lower_case_underscore,
+ }
+
+
+ # Set file format
+ file_format = ".xml"
+ ros2_prefix = "rt/"
+
+
+ # Check destination dir
+ dest_dir = args['output_dir']
+ if not os.path.exists(dest_dir):
+ os.makedirs(dest_dir)
+
+
+ # Check source dir
+ srcs_dir = os.path.join(dest_dir, "srcs")
+ if not os.path.exists(srcs_dir):
+ os.makedirs(srcs_dir)
+
+
+ # Copy all included xml files
+ for filename in os.listdir(args['template_dir']):
+ if filename.endswith(file_format):
+ template_src_path = os.path.join(args['template_dir'], filename)
+ template_dest_path = os.path.join(srcs_dir, filename)
+ if not os.path.isfile(template_dest_path):
+ copyfile(template_src_path, template_dest_path)
+
+
+ # Iterate throw all msgs/srvs
+ for idl_file in args['ros_interface_files']:
+ extension = os.path.splitext(idl_file)[1]
+ if extension == '.msg':
+ spec = parse_message_file(pkg_name, idl_file)
+ validate_field_types(spec, known_msg_types)
+ subfolder = os.path.basename(os.path.dirname(idl_file))
+
+ data = {
+ 'spec': spec,
+ 'pkg': spec.base_type.pkg_name,
+ 'msg': spec.msg_name,
+ 'type': spec.base_type.type,
+ 'subfolder': subfolder,
+ }
+ data.update(functions)
+
+
+ # Generate source file path
+ src_file = os.path.join(srcs_dir, "%s_%s_%s.xml" % (spec.base_type.pkg_name, subfolder, spec.msg_name))
+
+
+ # Publisher
+ file_content = " \n" % (spec.base_type.pkg_name, subfolder, spec.msg_name)
+ file_content += " \n" % (spec.base_type.pkg_name, subfolder, spec.msg_name)
+ file_content += " NO_KEY\n"
+ file_content += " %s%s_%s_%s\n" % (ros2_prefix, spec.base_type.pkg_name, subfolder, spec.msg_name)
+ file_content += " %s::%s::dds_::%s_\n" % (spec.base_type.pkg_name, subfolder, spec.msg_name)
+ file_content += " \n"
+ file_content += " KEEP_LAST\n"
+ file_content += " 5\n"
+ file_content += " \n"
+ file_content += " \n"
+ file_content += " TRANSIENT_LOCAL\n"
+ file_content += " \n"
+ file_content += " \n"
+ file_content += " \n"
+
+
+ # Subscriber
+ file_content += " \n" % (spec.base_type.pkg_name, subfolder, spec.msg_name)
+ file_content += " \n" % (spec.base_type.pkg_name, subfolder, spec.msg_name)
+ file_content += " NO_KEY\n"
+ file_content += " %s%s_%s_%s\n" % (ros2_prefix, spec.base_type.pkg_name, subfolder, spec.msg_name)
+ file_content += " %s::%s::dds_::%s_\n" % (spec.base_type.pkg_name, subfolder, spec.msg_name)
+ file_content += " \n"
+ file_content += " KEEP_LAST\n"
+ file_content += " 5\n"
+ file_content += " \n"
+ file_content += " \n"
+ file_content += " TRANSIENT_LOCAL\n"
+ file_content += " \n"
+ file_content += " \n"
+ file_content += " \n"
+
+
+ # Topic
+ file_content += " \n" % (spec.base_type.pkg_name, subfolder, spec.msg_name)
+ file_content += " %s%s_%s_%s\n" % (ros2_prefix, spec.base_type.pkg_name, subfolder, spec.msg_name)
+ file_content += " %s::%s::dds_::%s_\n" % (spec.base_type.pkg_name, subfolder, spec.msg_name)
+ file_content += " \n"
+
+
+ # Write file content
+ fd1 = open(src_file, "w")
+ if os.name == 'nt':
+ # Lock
+ hfile1 = win32file._get_osfhandle(fd1.fileno())
+ win32file.LockFileEx(hfile1, win32con.LOCKFILE_EXCLUSIVE_LOCK, 0, -0x10000, __overlapped)
+
+ # Write
+ fd1.write(file_content)
+
+ # Unlock
+ win32file.UnlockFileEx(hfile1, 0, -0x10000, __overlapped)
+ elif os.name == 'posix':
+ # Lock
+ fcntl.flock(fd1.fileno(), fcntl.LOCK_EX)
+
+ # Write
+ fd1.write(file_content)
+
+ # Unlock
+ fcntl.flock(fd1.fileno(), fcntl.LOCK_UN)
+ fd1.close()
+
+
+ # Open collect file
+ collec_file = os.path.join(args['output_dir'], "DEFAULT_FASTRTPS_PROFILES.xml")
+ fd2 = open(collec_file, "w")
+ if os.name == 'nt':
+ # Lock
+ hfile2 = win32file._get_osfhandle(fd2.fileno())
+ win32file.LockFileEx(hfile2, win32con.LOCKFILE_EXCLUSIVE_LOCK, 0, -0x10000, __overlapped)
+
+ # Generate head
+ fd2.write("\n")
+
+ # Append all files contents
+ for filename in os.listdir(srcs_dir):
+ if filename.endswith(".xml"):
+ # Open
+ fd3 = open(os.path.join(srcs_dir, filename), "r+")
+
+ # Lock
+ hfile3 = win32file._get_osfhandle(fd3.fileno())
+ win32file.LockFileEx(hfile3, win32con.LOCKFILE_EXCLUSIVE_LOCK, 0, -0x10000, __overlapped)
+
+ # Write
+ fd2.write(fd3.read())
+
+ # Unlock
+ win32file.UnlockFileEx(hfile3, 0, -0x10000, __overlapped)
+ fd3.close()
+
+ # Generate tail
+ fd2.write("\n")
+
+ # UnLock
+ win32file.UnlockFileEx(hfile2, 0, -0x10000, __overlapped)
+ elif os.name == 'posix':
+ # Lock
+ fcntl.flock(fd2.fileno(), fcntl.LOCK_EX)
+
+ # Generate head
+ fd2.write("\n")
+
+ # Append all files contents
+ for filename in os.listdir(srcs_dir):
+ if filename.endswith(".xml"):
+ # Open
+ fd3 = open(os.path.join(srcs_dir, filename), "r+")
+
+ # Lock
+ fcntl.flock(fd3, fcntl.LOCK_EX)
+
+ # Write
+ fd2.write(fd3.read())
+
+ # Unlock
+ fcntl.flock(fd3.fileno(), fcntl.LOCK_UN)
+
+ # Close
+ fd3.close()
+
+ # Generate tail
+ fd2.write("\n")
+
+ # UnLock
+ fcntl.flock(fd2.fileno(), fcntl.LOCK_UN)
+ # Close file
+ fd2.close()
+
+
+ #elif extension == '.srv':
+
+ #data = {'spec': spec}
+ #data.update(functions)
+
+ #if not os.path.exists(args['output_dir']):
+ # os.makedirs(args['output_dir'])
+
+ #f = open(os.path.join(args['output_dir'], 'demofile.txt'), 'w+')
+ #f.write("%s\n" % spec)
+ #f.close()
+ return 0
\ No newline at end of file
diff --git a/package.xml b/package.xml
new file mode 100644
index 0000000..461ed8a
--- /dev/null
+++ b/package.xml
@@ -0,0 +1,31 @@
+
+
+
+ micro_ros_agent
+ 0.0.1
+ DDS-XCRE agent implementation
+ Javier Moreno
+ Apache License 2.0
+
+ ament_cmake
+ ament_cmake
+
+ rosidl_parser
+
+ fastcdr
+ fastrtps
+ micrortps_agent
+
+ ament_lint_auto
+ ament_lint_common
+
+ rosidl_typesupport_c_packages
+
+
+ ament_cmake
+
+
+
+
+
+
diff --git a/resource/StaticValues.xml b/resource/StaticValues.xml
new file mode 100644
index 0000000..7444a10
--- /dev/null
+++ b/resource/StaticValues.xml
@@ -0,0 +1,39 @@
+
+
+
+
+ INFINITE
+
+ 0
+
+ DataReader_participant_subscriber
+
+
+
+
+ WITH_KEY
+ Square
+ ShapeType
+
+ KEEP_LAST
+ 5
+
+
+ TRANSIENT_LOCAL
+
+
+
+
+
+ WITH_KEY
+ Square
+ ShapeType
+
+ KEEP_LAST
+ 5
+
+
+ TRANSIENT_LOCAL
+
+
+