Commit 0e0f2d02 authored by Markus Georg Bendel's avatar Markus Georg Bendel

Add basic adapter generation

parent cf1e61d0
Pipeline #159190 passed with stages
in 2 minutes and 10 seconds
......@@ -6,50 +6,39 @@
#define SAMPLE_EVENT_ID 0x2345
#define SAMPLE_EVENTGROUP_ID 0x1456
tests_a_compA* component;
std::shared_ptr<vsomeip::application> _clockSubscriber;
std::shared_ptr<vsomeip::application> _echoPublisher;
SomeIPAdapter_tests_a_compA::SomeIPAdapter_tests_a_compA() {}
void SomeIPAdapter_tests_a_compA::init(tests_a_compA *comp)
{
void SomeIPAdapter_tests_a_compA::init(tests_a_compA *comp) {
// Initialize component
this->component = comp;
// Intitialize subscriber
_clockSubscriber = vsomeip::runtime::get()->create_application("Subscriber");
_clockSubscriber->init();
//_clockSubscriber->register_availability_handler(SAMPLE_SERVICE_ID, SAMPLE_INSTANCE_ID, on_availability);
_clockSubscriber->request_service(SAMPLE_SERVICE_ID, SAMPLE_INSTANCE_ID);
_clockSubscriber->register_message_handler(SAMPLE_SERVICE_ID, SAMPLE_INSTANCE_ID, SAMPLE_METHOD_ID, std::bind(&SomeIPAdapter_tests_a_compA::on_message, this, std::placeholders::_1));
//_clockSubscriber->register_message_handler(vsomeip::ANY_SERVICE, vsomeip::ANY_INSTANCE, vsomeip::ANY_METHOD, std::bind(&SomeipAdapter_tests_a_compA::on_message, this, std::placeholders::_1));
std::set<vsomeip::eventgroup_t> its_groups;
its_groups.insert(SAMPLE_EVENTGROUP_ID);
_clockSubscriber->request_event(SAMPLE_SERVICE_ID, SAMPLE_INSTANCE_ID, SAMPLE_EVENT_ID, its_groups, true);
// Subscribe
std::set<vsomeip::eventgroup_t> event_group;
event_group.insert(SAMPLE_EVENTGROUP_ID);
_clockSubscriber->request_event(SAMPLE_SERVICE_ID, SAMPLE_INSTANCE_ID, SAMPLE_EVENT_ID, event_group, true);
_clockSubscriber->subscribe(SAMPLE_SERVICE_ID, SAMPLE_INSTANCE_ID, SAMPLE_EVENTGROUP_ID);
_clockSubscriber->start();
// Intitialize Publisher
_echoPublisher = vsomeip::runtime::get()->create_application("Publisher");
_echoPublisher->init();
//_echoPublisher->register_message_handler(SAMPLE_SERVICE_ID, SAMPLE_INSTANCE_ID, SAMPLE_METHOD_ID, on_message);
_echoPublisher->offer_service(SAMPLE_SERVICE_ID, SAMPLE_INSTANCE_ID);
_echoPublisher->start();
}
void SomeIPAdapter_tests_a_compA::on_message(const std::shared_ptr<vsomeip::message> &_request) {
//read received message
std::shared_ptr<vsomeip::payload> its_payload = _request->get_payload();
vsomeip::length_t l = its_payload->get_length();
double dataFromMessage = *((double*)its_payload->get_data());
component->rosIn = dataFromMessage;
component->someIPIn = dataFromMessage;
//print data to std out
std::cout << "SERVICE: Received message from ["
<< std::setw(4) << std::setfill('0') << std::hex << _request->get_client() << "/"
<< std::setw(4) << std::setfill('0') << std::hex << _request->get_session() << "]: "
......@@ -58,22 +47,19 @@ void SomeIPAdapter_tests_a_compA::on_message(const std::shared_ptr<vsomeip::mess
void SomeIPAdapter_tests_a_compA::publish_echoPublisher()
{
double d = component->rosOut;
uint8_t *byteArray = (uint8_t*)&d;
//Read data from component
double d = component->someIPOut;
//Create message
uint8_t *byteArray = (uint8_t*)&d;
vsomeip::byte_t *p;
p = byteArray;
std::shared_ptr< vsomeip::payload > payload = vsomeip::runtime::get()->create_payload(p,8);
//const vsomeip::byte_t its_data[] = component->rosOut; //component->rosOut
//std::shared_ptr< vsomeip::payload > payload = vsomeip::runtime::get()->create_payload();
//payload->set_data(its_data, sizeof(its_data));
std::set<vsomeip::eventgroup_t> its_groups;
its_groups.insert(SAMPLE_EVENTGROUP_ID);
_echoPublisher->offer_event(SAMPLE_SERVICE_ID, SAMPLE_INSTANCE_ID, SAMPLE_EVENT_ID, its_groups, true);
//Publish
std::set<vsomeip::eventgroup_t> event_group;
event_group.insert(SAMPLE_EVENTGROUP_ID);
_echoPublisher->offer_event(SAMPLE_SERVICE_ID, SAMPLE_INSTANCE_ID, SAMPLE_EVENT_ID, event_group, true);
_echoPublisher->notify(SAMPLE_SERVICE_ID, SAMPLE_INSTANCE_ID, SAMPLE_EVENT_ID, payload);
}
......
......@@ -28,5 +28,8 @@ public:
private:
tests_a_compA* component = nullptr;
};
std::shared_ptr<vsomeip::application> _clockSubscriber;
std::shared_ptr<vsomeip::application> _echoPublisher;
};
#include <stdio.h>
#include "tests_a_compA.h"
tests_a_compA::tests_a_compA(double value)
{
someIPOut = value;
}
......@@ -6,10 +6,11 @@
using namespace std;
class tests_a_compA {
public:
double rosIn = 2.5;
double rosOut = 3.14;
tests_a_compA(double value);
double someIPIn = 2.5;
double someIPOut = 3.14;
};
#endif /* tests_a_compA_h */
......@@ -17,20 +17,53 @@ public class GeneratorSomeIP {
List<File> generateSomeIPAdapter(EMAComponentInstanceSymbol component) {
List<File> files = new ArrayList<>();
// Get info about the ports from the component
Collection<EMAPortInstanceSymbol> ports = component.getPortInstanceList();
List<String> contents = new ArrayList<String>();
List<FileWriter> frs = new ArrayList<FileWriter>();
// Create and fill model
SomeIPAdapterModel model = new SomeIPAdapterModel(component.getFullName());
model.addPorts(ports);
//Generate files and write to project
contents.add(SomeIPTemplates.generateSomeIPAdapterH(model));
files.add(new File("./target/generated-sources/SomeIPAdapter_"+model.getEscapedCompName()+".h"));
contents.add(SomeIPTemplates.generateSomeIPAdapterCPP(model));
files.add(new File("./target/generated-sources/SomeIPAdapter_"+model.getEscapedCompName()+".cpp"));
try {
int counter = 0;
for (File file : files)
{
frs.add(new FileWriter(file));
frs.get(counter).write(contents.get(counter));
counter++;
}
} catch (IOException e) {
e.printStackTrace();
}finally{
//Close resources
try {
for (FileWriter fr : frs)
fr.close();
} catch (IOException e) {
e.printStackTrace();
}
}
files.add(generateCMake(component));
return files;
}
File generateCMake(EMAComponentInstanceSymbol component) {
// Create and fill model
SomeIPAdapterModel model = new SomeIPAdapterModel(component.getFullName());
//Generate files and write to project
String content = SomeIPTemplates.generateSomeIPAdapter(model);
String content = SomeIPTemplates.generateSomeIPCMakeLists(model);
File file = new File("./target/generated-sources/ports.txt");
files.add(file);
File file = new File("./target/generated-sources/CMakeLists.txt");
FileWriter fr = null;
try {
......@@ -46,18 +79,27 @@ public class GeneratorSomeIP {
e.printStackTrace();
}
}
return files;
return file;
}
File generateCMake(EMAComponentInstanceSymbol component) {
List<File> generatePrettyPrint(EMAComponentInstanceSymbol component)
{
List<File> files = new ArrayList<>();
// Get info about the ports from the component
Collection<EMAPortInstanceSymbol> ports = component.getPortInstanceList();
// Create and fill model
SomeIPAdapterModel model = new SomeIPAdapterModel(component.getFullName());
model.addPortsDesc(ports);
//Generate files and write to project
String content = SomeIPTemplates.generateSomeIPCMakeLists(model);
String content = SomeIPTemplates.generatePrettyPrint(model);
File file = new File("./target/generated-sources/CMakeLists.txt");
File file = new File("./target/generated-sources/ports.txt");
files.add(file);
FileWriter fr = null;
try {
......@@ -65,7 +107,7 @@ public class GeneratorSomeIP {
fr.write(content);
} catch (IOException e) {
e.printStackTrace();
} finally {
}finally{
//Close resources
try {
fr.close();
......@@ -74,8 +116,10 @@ public class GeneratorSomeIP {
}
}
return file;
}
return files;
}
}
......@@ -31,7 +31,7 @@ public class SomeIPAdapterModel {
// Parse through component to find information about its ports
public void addPorts(Collection<EMAPortInstanceSymbol> ports)
public void addPortsDesc(Collection<EMAPortInstanceSymbol> ports)
{
for (EMAPortInstanceSymbol port : ports)
{
......@@ -42,14 +42,16 @@ public class SomeIPAdapterModel {
{
SomeIPConnectionSymbol sym = (SomeIPConnectionSymbol) symbol.get();
int serviceID = sym.getserviceID().isPresent()?sym.getserviceID().get():-1;
symbolKind = "someip, serviceID: " + serviceID;
int instanceID = sym.getinstanceID().isPresent()?sym.getinstanceID().get():-1;
int eventgroupID = sym.geteventgroupID().isPresent()?sym.geteventgroupID().get():-1;
symbolKind = "someip, serviceID: " + serviceID + " instanceID: " + instanceID + " eventgroupID: " + eventgroupID;
}
this.ports.add(port.getName() + " : " + kind + " (" + symbolKind + ")");
}
}
public List<String> getPorts()
public List<String> getPortsDesc()
{
return this.ports;
}
......
......@@ -16,6 +16,8 @@ public class SomeIPTemplates {
private static final Template SOMEIP_PRETTYPRINT;
private static final Template SOMEIP_CMAKELISTS;
private static final Template SOMEIP_ADAPTER_H;
private static final Template SOMEIP_ADAPTER_CPP;
// Loading .ftl files
static {
......@@ -27,6 +29,8 @@ public class SomeIPTemplates {
try {
SOMEIP_PRETTYPRINT = conf.getTemplate("PrettyPrint.ftl");
SOMEIP_CMAKELISTS = conf.getTemplate("CMakeLists.ftl");
SOMEIP_ADAPTER_H = conf.getTemplate("Adapter.h.ftl");
SOMEIP_ADAPTER_CPP = conf.getTemplate("Adapter.cpp.ftl");
} catch (IOException e) {
String msg = "could not load template";
Log.error(msg, e);
......@@ -34,12 +38,23 @@ public class SomeIPTemplates {
}
}
public static String generateSomeIPAdapter(SomeIPAdapterModel model) {
public static String generateSomeIPAdapterH(SomeIPAdapterModel model) {
HashMap<String, Object> data = new HashMap<>();
data.put("model", model);
return generate(SOMEIP_PRETTYPRINT, data);
return generate(SOMEIP_ADAPTER_H, data);
}
public static String generateSomeIPAdapterCPP(SomeIPAdapterModel model) {
HashMap<String, Object> data = new HashMap<>();
data.put("model", model);
return generate(SOMEIP_ADAPTER_CPP, data);
}
public static String generatePrettyPrint(SomeIPAdapterModel model) {
HashMap<String, Object> data = new HashMap<>();
data.put("model", model);
return generate(SOMEIP_PRETTYPRINT, data);
}
public static String generateSomeIPCMakeLists(SomeIPAdapterModel model) {
HashMap<String, Object> data = new HashMap<>();
......
<#import "SomeIPMacros.ftl" as m>
#include "<@m.mwIdent/>Adapter_${model.getEscapedCompName()}.h"
#define SAMPLE_SERVICE_ID 0x1234
#define SAMPLE_INSTANCE_ID 0x5678
#define SAMPLE_METHOD_ID 0x0421
#define SAMPLE_EVENT_ID 0x2345
#define SAMPLE_EVENTGROUP_ID 0x1456
<@m.mwIdent/>Adapter_${model.getEscapedCompName()}::<@m.mwIdent/>Adapter_${model.getEscapedCompName()}() {}
void <@m.mwIdent/>Adapter_${model.getEscapedCompName()}::init(${model.getEscapedCompName()} *comp) {
// Initialize component
this->component = comp;
// Intitialize subscriber
_clockSubscriber = vsomeip::runtime::get()->create_application("Subscriber");
_clockSubscriber->init();
_clockSubscriber->request_service(SAMPLE_SERVICE_ID, SAMPLE_INSTANCE_ID);
_clockSubscriber->register_message_handler(SAMPLE_SERVICE_ID, SAMPLE_INSTANCE_ID, SAMPLE_METHOD_ID, std::bind(&SomeIPAdapter_tests_a_compA::on_message, this, std::placeholders::_1));
// Subscribe
std::set<vsomeip::eventgroup_t> event_group;
event_group.insert(SAMPLE_EVENTGROUP_ID);
_clockSubscriber->request_event(SAMPLE_SERVICE_ID, SAMPLE_INSTANCE_ID, SAMPLE_EVENT_ID, event_group, true);
_clockSubscriber->subscribe(SAMPLE_SERVICE_ID, SAMPLE_INSTANCE_ID, SAMPLE_EVENTGROUP_ID);
_clockSubscriber->start();
// Intitialize Publisher
_echoPublisher = vsomeip::runtime::get()->create_application("Publisher");
_echoPublisher->init();
_echoPublisher->offer_service(SAMPLE_SERVICE_ID, SAMPLE_INSTANCE_ID);
_echoPublisher->start();
}
void <@m.mwIdent/>Adapter_${model.getEscapedCompName()}::on_message(const std::shared_ptr<vsomeip::message> &_request) {
//read received message
std::shared_ptr<vsomeip::payload> its_payload = _request->get_payload();
vsomeip::length_t l = its_payload->get_length();
double dataFromMessage = *((double*)its_payload->get_data());
component->someIPIn = dataFromMessage;
//print data to std out
std::cout << "SERVICE: Received message from ["
<< std::setw(4) << std::setfill('0') << std::hex << _request->get_client() << "/"
<< std::setw(4) << std::setfill('0') << std::hex << _request->get_session() << "]: "
<< dataFromMessage << std::endl;
}
void <@m.mwIdent/>Adapter_${model.getEscapedCompName()}::publish_echoPublisher()
{
//Read data from component
double d = component->someIPOut;
//Create message
uint8_t *byteArray = (uint8_t*)&d;
vsomeip::byte_t *p;
p = byteArray;
std::shared_ptr< vsomeip::payload > payload = vsomeip::runtime::get()->create_payload(p,8);
//Publish
std::set<vsomeip::eventgroup_t> event_group;
event_group.insert(SAMPLE_EVENTGROUP_ID);
_echoPublisher->offer_event(SAMPLE_SERVICE_ID, SAMPLE_INSTANCE_ID, SAMPLE_EVENT_ID, event_group, true);
_echoPublisher->notify(SAMPLE_SERVICE_ID, SAMPLE_INSTANCE_ID, SAMPLE_EVENT_ID, payload);
}
void <@m.mwIdent/>Adapter_${model.getEscapedCompName()}::tick()
{
publish_echoPublisher();
}
<#import "SomeIPMacros.ftl" as m>
#pragma once
#include "${model.getEscapedCompName()}.h"
#include <iomanip>
#include <iostream>
#include <sstream>
#include <condition_variable>
#include <thread>
#include <vsomeip/vsomeip.hpp>
using namespace std;
class <@m.mwIdent/>Adapter_${model.getEscapedCompName()} {
public:
<@m.mwIdent/>Adapter_${model.getEscapedCompName()}();
void init(${model.getEscapedCompName()}* comp);
void publish_echoPublisher();
void tick();
void on_message(const std::shared_ptr<vsomeip::message> &_response);
private:
${model.getEscapedCompName()}* component = nullptr;
std::shared_ptr<vsomeip::application> _clockSubscriber;
std::shared_ptr<vsomeip::application> _echoPublisher;
};
......@@ -4,6 +4,6 @@ Component name: ${model.getCompName()}
Ports:
<#list model.getPorts() as gen>
<#list model.getPortsDesc() as gen>
${gen}
</#list>
<#macro mwIdent>SomeIP</#macro>
<#macro smallIdent>someip</#macro>
package de.monticore.lang.monticar.generator.someip;
import static org.junit.Assert.assertNotNull;
import java.io.File;
import java.io.IOException;
import java.util.List;
import org.junit.Test;
import de.monticore.lang.embeddedmontiarc.embeddedmontiarc._symboltable.instanceStructure.EMAComponentInstanceSymbol;
import de.monticore.lang.embeddedmontiarc.tagging.middleware.someip.SomeIPConnectionSymbol;
import de.monticore.lang.embeddedmontiarc.tagging.middleware.ros.RosToEmamTagSchema;
import de.monticore.lang.tagging._symboltable.TaggingResolver;
public class AdapterGenerationTest extends AbstractSymtabTest {
@Test
public void testAdapter() throws IOException {
TaggingResolver taggingResolver = createSymTabAndTaggingResolver("src/test/resources/");
// Ros schema is used for now
RosToEmamTagSchema.registerTagTypes(taggingResolver);
// Create component instance and run the generator
EMAComponentInstanceSymbol componentInstanceSymbol = taggingResolver.<EMAComponentInstanceSymbol>resolve("tests.a.compA", EMAComponentInstanceSymbol.KIND).orElse(null);
assertNotNull(componentInstanceSymbol);
GeneratorSomeIP generatorSomeIP = new GeneratorSomeIP();
// Connect component's ports to topics
componentInstanceSymbol.getPortInstance("portA").orElse(null).setMiddlewareSymbol(new SomeIPConnectionSymbol(1,2,3));
List<File> files = generatorSomeIP.generateSomeIPAdapter(componentInstanceSymbol);
testFilesAreEqual(files, "echoAdapter/");
}
}
......@@ -33,7 +33,7 @@ public class PrettyPrintGenerationTest extends AbstractSymtabTest {
// Connect component's ports to topics
componentInstanceSymbol.getPortInstance("portA").orElse(null).setMiddlewareSymbol(new SomeIPConnectionSymbol(1,2,3));
List<File> files = generatorSomeIP.generateSomeIPAdapter(componentInstanceSymbol);
List<File> files = generatorSomeIP.generatePrettyPrint(componentInstanceSymbol);
testFilesAreEqual(files, "echo/");
}
......
......@@ -3,7 +3,7 @@ Component name: tests.a.compA
Ports:
portA : incoming (someip, serviceID: 1)
portA : incoming (someip, serviceID: 1 instanceID: 2 eventgroupID: 3)
portB : incoming (unknown symbol)
portC : outgoing (unknown symbol)
portD : outgoing (unknown symbol)
# Setting cmake version
cmake_minimum_required (VERSION 2.8)
# Using C++ with flags
set (CMAKE_CXX_FLAGS "-g -std=c++0x")
# Find vsomeip and boost packages
find_package (vsomeip 2.10.0 REQUIRED)
find_package( Boost 1.55 COMPONENTS system thread log REQUIRED )
#include vsomeip and boost directories
include_directories (
${Boost_INCLUDE_DIR}
${VSOMEIP_INCLUDE_DIRS}
)
# Linking libraries to target
add_library(SomeIPAdapter_tests_a_compA SomeIPAdapter_tests_a_compA.cpp)
target_link_libraries(SomeIPAdapter_tests_a_compA vsomeip ${Boost_LIBRARIES})
# Export target to a cmake module file for outside usage
export(TARGETS SomeIPAdapter_tests_a_compA FILE SomeIPAdapter_tests_a_compA.cmake)
#include "SomeIPAdapter_tests_a_compA.h"
#define SAMPLE_SERVICE_ID 0x1234
#define SAMPLE_INSTANCE_ID 0x5678
#define SAMPLE_METHOD_ID 0x0421
#define SAMPLE_EVENT_ID 0x2345
#define SAMPLE_EVENTGROUP_ID 0x1456
SomeIPAdapter_tests_a_compA::SomeIPAdapter_tests_a_compA() {}
void SomeIPAdapter_tests_a_compA::init(tests_a_compA *comp) {
// Initialize component
this->component = comp;
// Intitialize subscriber
_clockSubscriber = vsomeip::runtime::get()->create_application("Subscriber");
_clockSubscriber->init();
_clockSubscriber->request_service(SAMPLE_SERVICE_ID, SAMPLE_INSTANCE_ID);
_clockSubscriber->register_message_handler(SAMPLE_SERVICE_ID, SAMPLE_INSTANCE_ID, SAMPLE_METHOD_ID, std::bind(&SomeIPAdapter_tests_a_compA::on_message, this, std::placeholders::_1));
// Subscribe
std::set<vsomeip::eventgroup_t> event_group;
event_group.insert(SAMPLE_EVENTGROUP_ID);
_clockSubscriber->request_event(SAMPLE_SERVICE_ID, SAMPLE_INSTANCE_ID, SAMPLE_EVENT_ID, event_group, true);
_clockSubscriber->subscribe(SAMPLE_SERVICE_ID, SAMPLE_INSTANCE_ID, SAMPLE_EVENTGROUP_ID);
_clockSubscriber->start();
// Intitialize Publisher
_echoPublisher = vsomeip::runtime::get()->create_application("Publisher");
_echoPublisher->init();
_echoPublisher->offer_service(SAMPLE_SERVICE_ID, SAMPLE_INSTANCE_ID);
_echoPublisher->start();
}
void SomeIPAdapter_tests_a_compA::on_message(const std::shared_ptr<vsomeip::message> &_request) {
//read received message
std::shared_ptr<vsomeip::payload> its_payload = _request->get_payload();
vsomeip::length_t l = its_payload->get_length();
double dataFromMessage = *((double*)its_payload->get_data());
component->someIPIn = dataFromMessage;
//print data to std out
std::cout << "SERVICE: Received message from ["
<< std::setw(4) << std::setfill('0') << std::hex << _request->get_client() << "/"
<< std::setw(4) << std::setfill('0') << std::hex << _request->get_session() << "]: "
<< dataFromMessage << std::endl;
}
void SomeIPAdapter_tests_a_compA::publish_echoPublisher()
{
//Read data from component
double d = component->someIPOut;
//Create message
uint8_t *byteArray = (uint8_t*)&d;
vsomeip::byte_t *p;
p = byteArray;
std::shared_ptr< vsomeip::payload > payload = vsomeip::runtime::get()->create_payload(p,8);
//Publish
std::set<vsomeip::eventgroup_t> event_group;
event_group.insert(SAMPLE_EVENTGROUP_ID);
_echoPublisher->offer_event(SAMPLE_SERVICE_ID, SAMPLE_INSTANCE_ID, SAMPLE_EVENT_ID, event_group, true);
_echoPublisher->notify(SAMPLE_SERVICE_ID, SAMPLE_INSTANCE_ID, SAMPLE_EVENT_ID, payload);
}
void SomeIPAdapter_tests_a_compA::tick()
{
publish_echoPublisher();
}
#pragma once
#include "tests_a_compA.h"
#include <iomanip>
#include <iostream>
#include <sstream>
#include <condition_variable>
#include <thread>
#include <vsomeip/vsomeip.hpp>