Skip to content
Snippets Groups Projects
Commit 95b1c117 authored by Carsten Patzke's avatar Carsten Patzke
Browse files

*

parent fed4baac
No related branches found
No related tags found
No related merge requests found
Showing
with 299 additions and 273 deletions
......@@ -8,7 +8,7 @@
- /producer/producer-api
**Library:** Producer library which can send data to the receiver
**Library:** ProducerImpl library which can send data to the receiver
- /receiver
......
......@@ -6,102 +6,99 @@
namespace HIDRA2
{
namespace Networking
{
enum OP_CODE : uint8_t {
OP_CODE__HELLO,
OP_CODE__PREPARE_SEND_DATA,
OP_CODE__SEND_DATA_CHUNK,
};
enum OpCode : uint8_t {
OP_CODE__HELLO,
OP_CODE__PREPARE_SEND_DATA,
OP_CODE__SEND_DATA_CHUNK,
};
enum ERROR_CODE : uint16_t {
ERR__NO_ERROR,
ERR__UNSUPPORTED_VERSION,
ERR__FILENAME_ALREADY_IN_USE,
ERR__UNKNOWN_REFERENCE_ID,
ERR__INTERNAL_SERVER_ERROR = 65535,
};
enum NetworkErrorCode : uint16_t {
NET_ERR__NO_ERROR,
NET_ERR__UNSUPPORTED_VERSION,
NET_ERR__FILENAME_ALREADY_IN_USE,
NET_ERR__UNKNOWN_REFERENCE_ID,
NET_ERR__INTERNAL_SERVER_ERROR = 65535,
};
/**
* @defgroup RPC
* RPC always return a response to a corresponding request
* @{
*/
struct GenericNetworkRequest {
OP_CODE op_code;
uint64_t request_id;
char data[];
};
/**
* @defgroup RPC
* RPC always return a response to a corresponding request
* @{
*/
struct GenericNetworkRequest {
OpCode op_code;
uint64_t request_id;
char data[];
};
struct GenericNetworkResponse {
OP_CODE op_code;
uint64_t request_id;
ERROR_CODE error_code;
char data[];
};
struct GenericNetworkResponse {
OpCode op_code;
uint64_t request_id;
NetworkErrorCode error_code;
char data[];
};
struct HelloRequest {
uint32_t client_version;
struct HelloRequest {
uint32_t client_version;
OS_TYPE os : 4;
bool is_x64 : 1;
};
OS_TYPE os : 4;
bool is_x64 : 1;
};
/**
* Possible error codes:
* - ::ERR__UNSUPPORTED_VERSION
*/
struct HelloResponse {
uint32_t server_version;
};
/**
* Possible error codes:
* - ::NET_ERR__UNSUPPORTED_VERSION
*/
struct HelloResponse {
uint32_t server_version;
};
struct PrepareSendDataRequest {
char filename[255];
uint64_t file_size;
};
struct PrepareSendDataRequest {
char filename[255];
uint64_t file_size;
};
/**
* Possible error codes:
* - ::ERR__FILENAME_ALREADY_IN_USE
*/
struct PrepareSendDataResponse {
uint64_t file_reference_id;
};
/**
* Possible error codes:
* - ::NET_ERR__FILENAME_ALREADY_IN_USE
*/
struct PrepareSendDataResponse {
uint64_t file_reference_id;
};
struct SendDataChunkRequest {
uint64_t file_reference_id;
uint64_t start_byte;
uint64_t chunk_size;
};
struct SendDataChunkRequest {
uint64_t file_reference_id;
uint64_t start_byte;
uint64_t chunk_size;
};
/**
* Possible error codes:
* - ::ERR__UNKNOWN_REFERENCE_ID
*/
struct SendDataChunkResponse {
};
/** @} */
/**
* Possible error codes:
* - ::NET_ERR__UNKNOWN_REFERENCE_ID
*/
struct SendDataChunkResponse {
};
/** @} */
/**
* @defgroup EVENT
* Events cannot be requests, they will be send by the server spontaneously
* @{
*/
struct GenericNetworkEvent {
OP_CODE op_code;
ERROR_CODE error_code;
char data[];
};
/**
* @defgroup EVENT
* Events cannot be requests, they will be send by the server spontaneously
* @{
*/
struct GenericNetworkEvent {
OpCode op_code;
NetworkErrorCode error_code;
char data[];
};
/**
* Possible error codes:
* - TODO
*/
struct FileStatusEvent {
uint64_t file_reference_id;
};
/** @} */
}
/**
* Possible error codes:
* - TODO
*/
struct FileStatusEvent {
uint64_t file_reference_id;
};
/** @} */
}
#endif //HIDRA2__COMMON_NETWORKING_H
......@@ -7,5 +7,5 @@ TEST(Networking, CheckIfNoErrorIsNull)
* To ensure that developers can use
* if(!response->error_code)
*/
EXPECT_EQ((uint16_t)HIDRA2::Networking::ERR__NO_ERROR, 0);
EXPECT_EQ((uint16_t)HIDRA2::NET_ERR__NO_ERROR, 0);
}
set(TARGET_NAME producer-api)
set(SOURCE_FILES src/producer/producer.cpp include/producer/producer.h)
set(SOURCE_FILES src/producer_impl.cpp src/producer_impl.h include/producer/producer.h src/producer.cpp)
################################
......
......@@ -5,18 +5,18 @@
namespace HIDRA2
{
enum ProducerError {
PRODUCER_ERROR__OK,
};
class Producer
{
private:
static uint64_t kInitCount;
Producer();
public:
static const uint32_t kVersion;
Producer(const Producer&) = delete;
Producer& operator=(const Producer&) = delete;
static Producer* create();
static Producer* CreateProducer(std::string receiver_address);
virtual uint64_t get_version() = 0;
//virtual ProducerError connect(std::string receiver_address) = 0;
//virtual ProducerError sendfile(std::string receiver_address) = 0;
};
}
......
#include "producer/producer.h"
#include "producer_impl.h"
HIDRA2::Producer* HIDRA2::Producer::create()
{
return new ProducerImpl();
}
#include <producer/producer.h>
unsigned long HIDRA2::Producer::kInitCount = 0;
const uint32_t HIDRA2::Producer::kVersion = 1;
HIDRA2::Producer::Producer()
{
kInitCount++;
}
HIDRA2::Producer *HIDRA2::Producer::CreateProducer(std::string receiver_address)
{
return new Producer();
}
#include "producer_impl.h"
const uint32_t HIDRA2::ProducerImpl::kVersion = 1;
uint64_t HIDRA2::ProducerImpl::get_version()
{
return 1;
}
#ifndef HIDRA2__PRODUCER_PRODUCERIMPL_H
#define HIDRA2__PRODUCER_PRODUCERIMPL_H
#include <string>
#include "producer/producer.h"
namespace HIDRA2
{
class ProducerImpl : public Producer
{
private:
static const uint32_t kVersion;
public:
ProducerImpl(const ProducerImpl&) = delete;
ProducerImpl& operator=(const ProducerImpl&) = delete;
ProducerImpl() = default;
~ProducerImpl() = default;
uint64_t get_version() override;
//ProducerError connect(std::string receiver_address) override;
};
}
#endif //HIDRA2__PRODUCER_PRODUCERIMPL_H
#include <gtest/gtest.h>
#include <producer/producer.h>
#include "producer/producer.h"
namespace
{
TEST(VERSION, VersionAboveZero)
{
EXPECT_GE(HIDRA2::Producer::kVersion, 0);
HIDRA2::Producer* p = HIDRA2::Producer::create();
EXPECT_GE(p->get_version(), 0);
}
TEST(CreateProducer, PointerIsNotNullptr)
{
HIDRA2::Producer* prod = HIDRA2::Producer::CreateProducer("127.0.0.1");
EXPECT_NE(prod, nullptr);
//HIDRA2::ProducerImpl* prod = HIDRA2::ProducerImpl::CreateProducer("127.0.0.1");
//EXPECT_NE(1, nullptr);
}
}
set(TARGET_NAME inotify-event-detector-cpp)
set(SOURCE_FILES
src/main.cpp
src/inotify_helper.cpp include/inotify-event-detector-cpp/inotify_helper.h
src/Inotify_event_detector.cpp include/inotify-event-detector-cpp/Inotify_event_detector.h
src/inotify_helper.cpp src/inotify_helper.h
src/Inotify_event_detector.cpp src/Inotify_event_detector.h
)
......
#ifndef HIDRA2__INOTIFYEVENTDETECTOR_INOTIFYHELPER_H
#define HIDRA2__INOTIFYEVENTDETECTOR_INOTIFYHELPER_H
#include <string>
#include <cstdint>
#include <unistd.h>
#include <sys/inotify.h>
#include <thread>
#define EVENT_SIZE ( sizeof (struct inotify_event) )
#define EVENT_BUF_LEN ( 1024 * ( EVENT_SIZE + 16 ) )
namespace HIDRA2
{
namespace inotifyeventdetector
{
enum INOTIFY_ERR {
INOTIFY_ERR__OK,
INOTIFY_ERR__FAIL_TO_CREATE_WATCH_DESCRIPTOR,
INOTIFY_ERR__FAIL_TO_CREATE_INOTIFY_FILE_DESCRITPTOR,
};
enum INOTIFY_WATCH_MASK : uint32_t {
INOTIFY_WATCH_MASK__IN_CLOSE_WRITE = IN_CLOSE_WRITE,
INOTIFY_WATCH_MASK__IN_CLOSE_NOWRITE = IN_CLOSE_NOWRITE,
INOTIFY_WATCH_MASK__IN_CLOSE = IN_CLOSE,
};
class InotifyHelper
{
public:
typedef void on_event_function_t (void* arg1, inotify_event*);
InotifyHelper(const InotifyHelper&) = delete;
InotifyHelper& operator=(const InotifyHelper&) = delete;
~InotifyHelper();
static INOTIFY_ERR create(InotifyHelper*& ref, std::string watch_folder_path, INOTIFY_WATCH_MASK watch_mask, on_event_function_t on_event, void* on_event_arg1);
void start();
void stop();
void free_event(inotify_event* event);
private:
InotifyHelper() = default;
bool running_;
on_event_function_t* on_event_;
void* on_event_arg1_;
int file_descriptor_;
int watch_descriptor_;
std::thread* internal_thread_handle_;
void internal_thread_();
};
}
}
#endif //HIDRA2__INOTIFYEVENTDETECTOR_INOTIFYHELPER_H
#include <inotify-event-detector-cpp/Inotify_event_detector.h>
#include <producer/producer.h>
#include "Inotify_event_detector.h"
#include <iostream>
#include <inotify-event-detector-cpp/inotify_helper.h>
#include <producer/producer.h>
namespace HIDRA2
{
int inotifyeventdetector::InotifyEventDetector::main(int argc, char** argv)
{
std::cout << "Running producer version: " << Producer::kVersion << std::endl;
Producer* producer = HIDRA2::Producer::create();
Producer* producer = HIDRA2::Producer::CreateProducer("127.0.0.1");
if (!producer) {
std::cerr << "Fail to create producer" << std::endl;
return 1;
}
inotifyeventdetector::InotifyHelper* inotify_helper;
//inotifyeventdetector::InotifyHelper::on_event_function_t a = std::bind(inotifyeventdetector::InotifyEventDetector::event_handler_, this);
typedef void (*FPtr)(void);
FPtr p = inotifyeventdetector::InotifyEventDetector::event_handler_;
std::cout << "Running producer version: " << producer->get_version() << std::endl;
if (!inotify_helper->create(inotify_helper, "/tmp/data", inotifyeventdetector::INOTIFY_WATCH_MASK__IN_CLOSE_WRITE,
(InotifyHelper::on_event_function_t) p, this));
InotifyError error;
InotifyHelper* inotify_helper = inotify_helper->create("/tmp/data", INOTIFY_WATCH_MASK__IN_CLOSE_WRITE,
[this](InotifyEvent* event) {
event_handler_(event);
}, error);
inotify_helper->start();
......@@ -36,8 +33,8 @@ namespace HIDRA2
return 0;
}
void inotifyeventdetector::InotifyEventDetector::event_handler_(inotify_event* event)
void inotifyeventdetector::InotifyEventDetector::event_handler_(InotifyEvent* event)
{
std::cout << "File was edited: '" << event->name << "'" << std::endl;
std::cout << "File was edited: '" << event->filename << "'" << std::endl;
}
}
......@@ -2,6 +2,7 @@
#define HIDRA2__INOTIFYEVENTDETECTOR_INOTIFYEVENTDETECTOR_H
#include <sys/inotify.h>
#include "inotify_helper.h"
namespace HIDRA2
{
......@@ -16,7 +17,7 @@ namespace HIDRA2
int main(int argc, char* argv[]);
private:
void event_handler_(inotify_event* event);
void event_handler_(InotifyEvent* event);
};
}
}
......
#include <inotify-event-detector-cpp/inotify_helper.h>
#include "inotify_helper.h"
#include <iostream>
#include <cstring>
const size_t EVENT_SIZE = sizeof (struct inotify_event);
const size_t EVENT_BUF_LEN = 1024 * ( EVENT_SIZE + 16 );
namespace HIDRA2
{
namespace inotifyeventdetector
InotifyHelper::~InotifyHelper()
{
inotify_rm_watch(file_descriptor_, watch_descriptor_);
close(file_descriptor_);
stop();
}
InotifyHelper* InotifyHelper::create(std::string watch_folder_path, InotifyWatchMask watch_mask,
InotifyEventFunction on_event, InotifyError& error)
{
InotifyHelper::~InotifyHelper()
{
inotify_rm_watch(file_descriptor_, watch_descriptor_);
close(file_descriptor_);
stop();
auto* self = new InotifyHelper();
self->file_descriptor_ = inotify_init();
if (self->file_descriptor_ < 0) {
error = INOTIFY_ERR__FAIL_TO_CREATE_INOTIFY_FILE_DESCRITPTOR;
return nullptr;
}
INOTIFY_ERR
InotifyHelper::create(InotifyHelper*& ref,
std::string watch_folder_path, INOTIFY_WATCH_MASK watch_mask,
InotifyHelper::on_event_function_t on_event, void* on_event_arg1)
{
auto* self = new InotifyHelper();
self->file_descriptor_ = inotify_init();
if (self->file_descriptor_ < 0) {
return INOTIFY_ERR__FAIL_TO_CREATE_INOTIFY_FILE_DESCRITPTOR;
}
self->watch_descriptor_ = inotify_add_watch(self->file_descriptor_, watch_folder_path.c_str(), watch_mask);
if (self->watch_descriptor_ < 0) {
error = INOTIFY_ERR__FAIL_TO_CREATE_WATCH_DESCRIPTOR;
return nullptr;
}
self->watch_descriptor_ = inotify_add_watch(self->file_descriptor_, watch_folder_path.c_str(), watch_mask);
if (self->watch_descriptor_ < 0) {
return INOTIFY_ERR__FAIL_TO_CREATE_WATCH_DESCRIPTOR;
}
self->running_ = false;
self->on_event_ = on_event;
self->running_ = false;
self->on_event_ = on_event;
self->on_event_arg1_ = on_event_arg1;
error = INOTIFY_ERR__OK;
return self;
}
ref = self;
return INOTIFY_ERR__OK;
void InotifyHelper::start()
{
if(running_) {
return;
}
running_ = true;
internal_thread_handle_ = new std::thread(&InotifyHelper::internal_thread_, this);
}
void InotifyHelper::start()
{
if(running_) {
return;
}
running_ = true;
internal_thread_handle_ = new std::thread(&InotifyHelper::internal_thread_, this);
void InotifyHelper::stop()
{
running_ = false;
if(internal_thread_handle_) {
internal_thread_handle_->join();
}
}
void InotifyHelper::internal_thread_()
{
std::cout << "Hello world" << std::endl;
char buffer[EVENT_BUF_LEN];
ssize_t length;
while(running_) {
fd_set read_fds, write_fds, except_fds;
FD_ZERO(&read_fds);
FD_ZERO(&write_fds);
FD_ZERO(&except_fds);
FD_SET(file_descriptor_, &read_fds);
struct timeval timeout;
timeout.tv_sec = 1;
timeout.tv_usec = 0;
void InotifyHelper::stop()
{
running_ = false;
if(internal_thread_handle_) {
internal_thread_handle_->join();
if (select(file_descriptor_ + 1, &read_fds, &write_fds, &except_fds, &timeout) == 1) {
length = read(file_descriptor_, buffer, EVENT_BUF_LEN);
} else {
continue;// A timeout occurred
}
}
void InotifyHelper::internal_thread_()
{
std::cout << "Hello world" << std::endl;
char buffer[EVENT_BUF_LEN];
ssize_t length;
while(running_) {
fd_set read_fds, write_fds, except_fds;
FD_ZERO(&read_fds);
FD_ZERO(&write_fds);
FD_ZERO(&except_fds);
FD_SET(file_descriptor_, &read_fds);
struct timeval timeout;
timeout.tv_sec = 1;
timeout.tv_usec = 0;
if (select(file_descriptor_ + 1, &read_fds, &write_fds, &except_fds, &timeout) == 1) {
length = read(file_descriptor_, buffer, EVENT_BUF_LEN);
} else {
continue;// A timeout occurred
}
int event_pointer = 0;
/*checking for error*/
if (length < 0) {
perror("read");
}
while (event_pointer < length && running_) {
inotify_event* event = (inotify_event*) &(buffer[event_pointer]);
inotify_event* copy = (inotify_event *) malloc(sizeof(inotify_event) + event->len);
memmove(copy, event, sizeof(inotify_event) + event->len);
on_event_(on_event_arg1_, copy);
event_pointer += EVENT_SIZE + event->len;
}
/*checking for error*/
if (length < 0) {
perror("read");//TODO what to do here?
}
}
void InotifyHelper::free_event(inotify_event* event)
{
free(event);
unsigned int event_pointer = 0;
while (event_pointer < length && running_) {
inotify_event* event = (inotify_event*) &(buffer[event_pointer]);
InotifyEvent* copy = (InotifyEvent *) malloc(sizeof(inotify_event) + event->len);
memmove(copy, event, sizeof(inotify_event) + event->len);
on_event_(copy);
event_pointer += EVENT_SIZE + event->len;
}
}
}
void InotifyHelper::free_event(InotifyEvent* event)
{
free(event);
}
}
#ifndef HIDRA2__INOTIFYEVENTDETECTOR_INOTIFYHELPER_H
#define HIDRA2__INOTIFYEVENTDETECTOR_INOTIFYHELPER_H
#include <string>
#include <cstdint>
#include <unistd.h>
#include <sys/inotify.h>
#include <thread>
namespace HIDRA2
{
enum InotifyError {
INOTIFY_ERR__OK,
INOTIFY_ERR__FAIL_TO_CREATE_WATCH_DESCRIPTOR,
INOTIFY_ERR__FAIL_TO_CREATE_INOTIFY_FILE_DESCRITPTOR,
};
enum InotifyWatchMask : uint32_t {
INOTIFY_WATCH_MASK__IN_CLOSE_WRITE = IN_CLOSE_WRITE,
INOTIFY_WATCH_MASK__IN_CLOSE_NOWRITE = IN_CLOSE_NOWRITE,
INOTIFY_WATCH_MASK__IN_CLOSE = IN_CLOSE,
};
struct InotifyEvent {
int watch_descriptor;
uint32_t mask;
uint32_t cookie;
uint32_t filename_length;
char filename[];
};
typedef std::function<void(InotifyEvent* event)> InotifyEventFunction;//void InotifyEventFunction(InotifyEvent* event, void* opaque);
class InotifyHelper
{
private:
InotifyHelper() = default;
bool running_;
InotifyEventFunction on_event_;
int file_descriptor_;
int watch_descriptor_;
std::thread* internal_thread_handle_;
void internal_thread_();
public:
InotifyHelper(const InotifyHelper&) = delete;
InotifyHelper& operator=(const InotifyHelper&) = delete;
~InotifyHelper();
static InotifyHelper* create(std::string watch_folder_path, InotifyWatchMask watch_mask, InotifyEventFunction on_event, InotifyError& error);
void start();
void stop();
void free_event(InotifyEvent* event);
};
}
#endif //HIDRA2__INOTIFYEVENTDETECTOR_INOTIFYHELPER_H
#include <producer/producer.h>
#include <inotify-event-detector-cpp/inotify_helper.h>
#include <inotify-event-detector-cpp/Inotify_event_detector.h>
#include "../../api/src/producer_impl.h"
#include "inotify_helper.h"
#include "Inotify_event_detector.h"
#include <iostream>
int main (int argc, char* argv[])
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment