mirror of
https://github.com/intrepidcs/libicsneo.git
synced 2026-08-05 01:18:36 +02:00
Add device sharing support
This commit is contained in:
@@ -4,15 +4,49 @@
|
||||
#include <stdint.h>
|
||||
#include <time.h>
|
||||
|
||||
#ifdef _MSC_VER
|
||||
#pragma warning(push)
|
||||
#pragma warning(disable : 4201) // nameless struct/union
|
||||
#endif
|
||||
|
||||
typedef struct {
|
||||
const char* description;
|
||||
time_t timestamp;
|
||||
uint32_t eventNumber;
|
||||
uint8_t severity;
|
||||
char serial[7];
|
||||
} neoeventcontext_t;
|
||||
|
||||
typedef struct {
|
||||
time_t timestamp;
|
||||
union {
|
||||
struct {
|
||||
uint32_t eventNumber;
|
||||
int8_t severity;
|
||||
char serial[7];
|
||||
};
|
||||
neoeventcontext_t eventContext;
|
||||
};
|
||||
} neosocketevent_t;
|
||||
|
||||
typedef neoeventcontext_t neosocketeventfilter_t;
|
||||
|
||||
typedef struct {
|
||||
const char* description;
|
||||
union {
|
||||
struct {
|
||||
time_t timestamp;
|
||||
uint32_t eventNumber;
|
||||
uint8_t severity;
|
||||
char serial[7];
|
||||
};
|
||||
neosocketevent_t socketEvent;
|
||||
};
|
||||
uint8_t reserved[16];
|
||||
} neoevent_t;
|
||||
|
||||
#ifdef _MSC_VER
|
||||
#pragma warning(pop)
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
|
||||
#include <vector>
|
||||
@@ -49,6 +83,7 @@ public:
|
||||
ValueNotYetPresent = 0x1013,
|
||||
Timeout = 0x1014,
|
||||
WiVINotSupported = 0x1015,
|
||||
TestEvent = 0x1016,
|
||||
|
||||
// Device Events
|
||||
PollingMessageOverflow = 0x2000,
|
||||
@@ -103,7 +138,31 @@ public:
|
||||
PCAPCouldNotStart = 0x3102,
|
||||
PCAPCouldNotFindDevices = 0x3103,
|
||||
PacketDecodingError = 0x3104,
|
||||
|
||||
|
||||
// Device Sharing Server Events
|
||||
SharedMemoryDataIsNull = 0x4001,
|
||||
SharedMemoryFailedToClose = 0x4002,
|
||||
SharedMemoryFailedToOpen = 0x4003,
|
||||
SharedMemoryFailedToUnlink = 0x4004,
|
||||
SharedMemoryFileTruncateError = 0x4005,
|
||||
SharedMemoryMappingError = 0x4006,
|
||||
SharedMemoryUnmapError = 0x4007,
|
||||
SharedSemaphoreFailedToClose = 0x4008,
|
||||
SharedSemaphoreFailedToOpen = 0x4009,
|
||||
SharedSemaphoreFailedToPost = 0x4010,
|
||||
SharedSemaphoreFailedToUnlink = 0x4011,
|
||||
SharedSemaphoreFailedToWait = 0x4012,
|
||||
SharedSemaphoreNotOpenForPost = 0x4013,
|
||||
SharedSemaphoreNotOpenForWait = 0x4014,
|
||||
SocketFailedToOpen = 0x4015,
|
||||
SocketFailedToClose = 0x4016,
|
||||
SocketFailedToConnect = 0x4017,
|
||||
SocketFailedToRead = 0x4018,
|
||||
SocketFailedToWrite = 0x4019,
|
||||
SocketAcceptorFailedToBind = 0x4020,
|
||||
SocketAcceptorFailedToListen = 0x4021,
|
||||
|
||||
// Other Errors
|
||||
NoErrorFound = 0xFFFFFFFD,
|
||||
TooManyEvents = 0xFFFFFFFE,
|
||||
Unknown = 0xFFFFFFFF
|
||||
@@ -117,8 +176,10 @@ public:
|
||||
|
||||
APIEvent() : eventStruct({}), serial(), timepoint(), device(nullptr) {}
|
||||
APIEvent(APIEvent::Type event, APIEvent::Severity severity, const Device* device = nullptr);
|
||||
APIEvent(neosocketevent_t evStruct, const Device* device = nullptr);
|
||||
|
||||
const neoevent_t* getNeoEvent() const noexcept { return &eventStruct; }
|
||||
neosocketevent_t getNeoSocketEvent() const noexcept;
|
||||
Type getType() const noexcept { return Type(eventStruct.eventNumber); }
|
||||
Severity getSeverity() const noexcept { return Severity(eventStruct.severity); }
|
||||
std::string getDescription() const noexcept { return std::string(eventStruct.description); }
|
||||
@@ -157,8 +218,12 @@ public:
|
||||
EventFilter(const Device* device, APIEvent::Severity severity) : severity(severity), matchOnDevicePtr(true), device(device) {}
|
||||
EventFilter(std::string serial, APIEvent::Type type = APIEvent::Type::Any, APIEvent::Severity severity = APIEvent::Severity::Any) : type(type), severity(severity), serial(serial) {}
|
||||
EventFilter(std::string serial, APIEvent::Severity severity) : severity(severity), serial(serial) {}
|
||||
EventFilter(neosocketeventfilter_t evFilterSt) : type(static_cast<APIEvent::Type>(evFilterSt.eventNumber)),
|
||||
severity(static_cast<APIEvent::Severity>(evFilterSt.severity)),
|
||||
serial(std::string(evFilterSt.serial)) {}
|
||||
|
||||
bool match(const APIEvent& event) const noexcept;
|
||||
neosocketeventfilter_t getNeoSocketEventFilter() const noexcept;
|
||||
|
||||
APIEvent::Type type = APIEvent::Type::Any;
|
||||
APIEvent::Severity severity = APIEvent::Severity::Any;
|
||||
|
||||
@@ -10,6 +10,7 @@
|
||||
#include <map>
|
||||
#include <thread>
|
||||
#include <algorithm>
|
||||
#include <optional>
|
||||
#include "icsneo/api/event.h"
|
||||
#include "icsneo/api/eventcallback.h"
|
||||
|
||||
@@ -34,6 +35,8 @@ public:
|
||||
// If this thread exists in the map, turn off downgrading
|
||||
void cancelErrorDowngradingOnCurrentThread();
|
||||
|
||||
void removeEventMirror(const std::thread::id& id);
|
||||
|
||||
bool isDowngradingErrorsOnCurrentThread() const;
|
||||
|
||||
int addEventCallback(const EventCallback &cb);
|
||||
@@ -108,6 +111,10 @@ private:
|
||||
bool enforceLimit(); // Returns whether the limit enforcement resulted in an overflow
|
||||
|
||||
void discardOldest(size_t count = 1);
|
||||
|
||||
#ifdef ICSNEO_ENABLE_DEVICE_SHARING
|
||||
std::optional<std::vector<neosocketevent_t>> getServerEvents(const size_t& max);
|
||||
#endif
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
@@ -21,11 +21,14 @@
|
||||
#include <thread>
|
||||
#include <queue>
|
||||
#include <map>
|
||||
#include <list>
|
||||
|
||||
namespace icsneo {
|
||||
|
||||
class Communication {
|
||||
public:
|
||||
typedef std::function<void(std::vector<uint8_t>&)> RawCallback;
|
||||
|
||||
// Note that the Packetizer is not created by the constructor,
|
||||
// and should be done once the Communication module is in place.
|
||||
Communication(
|
||||
@@ -45,6 +48,7 @@ public:
|
||||
void modeChangeIncoming() { driver->modeChangeIncoming(); }
|
||||
void awaitModeChangeComplete() { driver->awaitModeChangeComplete(); }
|
||||
bool rawWrite(const std::vector<uint8_t>& bytes) { return driver->write(bytes); }
|
||||
void modifyRawCallbacks(std::function<void(std::list<Communication::RawCallback>&)>&& cb);
|
||||
virtual bool sendPacket(std::vector<uint8_t>& bytes);
|
||||
bool redirectRead(std::function<void(std::vector<uint8_t>&&)> redirectTo);
|
||||
void clearRedirectRead();
|
||||
@@ -88,6 +92,8 @@ protected:
|
||||
std::atomic<bool> redirectingRead{false};
|
||||
std::function<void(std::vector<uint8_t>&&)> redirectionFn;
|
||||
std::mutex redirectingReadMutex; // Don't allow read to be disabled while in the redirectionFn
|
||||
std::mutex rawCallbacksMutex;
|
||||
std::list<std::function<void(std::vector<uint8_t>&)>> rawCallbacks;
|
||||
std::mutex syncMessageMutex;
|
||||
|
||||
void dispatchMessage(const std::shared_ptr<Message>& msg);
|
||||
|
||||
@@ -9,6 +9,7 @@
|
||||
#include <thread>
|
||||
#include <mutex>
|
||||
#include <condition_variable>
|
||||
#include "icsneo/device/neodevice.h"
|
||||
#include "icsneo/api/eventmanager.h"
|
||||
#include "icsneo/third-party/concurrentqueue/blockingconcurrentqueue.h"
|
||||
|
||||
@@ -16,7 +17,7 @@ namespace icsneo {
|
||||
|
||||
class Driver {
|
||||
public:
|
||||
Driver(const device_eventhandler_t& handler) : report(handler) {}
|
||||
Driver(const device_eventhandler_t& handler, neodevice_t& forDevice) : report(handler), device(forDevice) {}
|
||||
virtual ~Driver() {}
|
||||
virtual bool open() = 0;
|
||||
virtual bool isOpen() = 0;
|
||||
@@ -24,12 +25,14 @@ public:
|
||||
virtual void awaitModeChangeComplete() {}
|
||||
virtual bool isDisconnected() { return disconnected; };
|
||||
virtual bool close() = 0;
|
||||
virtual bool enableHeartbeat() const { return false; }
|
||||
bool read(std::vector<uint8_t>& bytes, size_t limit = 0);
|
||||
bool readWait(std::vector<uint8_t>& bytes, std::chrono::milliseconds timeout = std::chrono::milliseconds(100), size_t limit = 0);
|
||||
bool write(const std::vector<uint8_t>& bytes);
|
||||
virtual bool isEthernet() const { return false; }
|
||||
|
||||
device_eventhandler_t report;
|
||||
neodevice_t& device;
|
||||
|
||||
size_t writeQueueSize = 50;
|
||||
bool writeBlocks = true; // Otherwise it just fails when the queue is full
|
||||
|
||||
@@ -0,0 +1,42 @@
|
||||
#ifndef __INTERPROCESSMAILBOX_H_
|
||||
#define __INTERPROCESSMAILBOX_H_
|
||||
|
||||
#ifdef __cplusplus
|
||||
|
||||
#include <cstdint>
|
||||
#include "icsneo/platform/sharedmemory.h"
|
||||
#include "icsneo/platform/sharedsemaphore.h"
|
||||
|
||||
static constexpr uint16_t MESSAGE_COUNT = 1024;
|
||||
static constexpr uint16_t BLOCK_SIZE = 2048;
|
||||
using LengthFieldType = uint16_t;
|
||||
static constexpr uint8_t LENGTH_FIELD_SIZE = sizeof(LengthFieldType);
|
||||
static constexpr uint16_t MAX_DATA_SIZE = BLOCK_SIZE - LENGTH_FIELD_SIZE;
|
||||
|
||||
namespace icsneo {
|
||||
|
||||
class InterprocessMailbox {
|
||||
public:
|
||||
bool open(const std::string& name, bool create = false /* create the shared resources or not */);
|
||||
bool close();
|
||||
operator bool() const;
|
||||
|
||||
// data must be large enough to hold at least MAX_DATA_SIZE
|
||||
// messageLength can be larger than MAX_DATA_SIZE if the message spans multiple blocks, only MAX_DATA_SIZE will be read
|
||||
bool read(void* data, LengthFieldType& messageLength, const std::chrono::milliseconds& timeout);
|
||||
|
||||
// if messageLength is larger than MAX_DATA_SIZE it's expected that future write() calls will send the remaining data
|
||||
bool write(const void* data, LengthFieldType messageLength, const std::chrono::milliseconds& timeout);
|
||||
private:
|
||||
icsneo::SharedSemaphore queuedSem;
|
||||
icsneo::SharedSemaphore emptySem;
|
||||
icsneo::SharedMemory sharedMem;
|
||||
unsigned index = 0; // index into messages;
|
||||
bool valid = false;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif // __cplusplus
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,34 @@
|
||||
#ifndef __SDIO_H_
|
||||
#define __SDIO_H_
|
||||
|
||||
#ifdef __cplusplus
|
||||
|
||||
#include "icsneo/communication/driver.h"
|
||||
#include "icsneo/communication/interprocessmailbox.h"
|
||||
|
||||
namespace icsneo {
|
||||
|
||||
class SDIO : public Driver {
|
||||
public:
|
||||
static void Find(std::vector<FoundDevice>& found);
|
||||
|
||||
SDIO(const device_eventhandler_t& err, neodevice_t& forDevice) : Driver(err, forDevice) {}
|
||||
~SDIO() { if(isOpen()) close(); }
|
||||
bool open() override;
|
||||
bool close() override;
|
||||
bool isOpen() override;
|
||||
bool enableHeartbeat() const override { return true; }
|
||||
|
||||
private:
|
||||
void readTask() override;
|
||||
void writeTask() override;
|
||||
bool deviceOpen = false;
|
||||
InterprocessMailbox outboundIO;
|
||||
InterprocessMailbox inboundIO;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif // __cplusplus
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,124 @@
|
||||
#ifndef __SOCKET_H_
|
||||
#define __SOCKET_H_
|
||||
|
||||
#ifdef __cplusplus
|
||||
|
||||
#include <vector>
|
||||
#include <optional>
|
||||
#include <string>
|
||||
#include <memory>
|
||||
#include <functional>
|
||||
#include <mutex>
|
||||
#include <atomic>
|
||||
|
||||
#ifdef _WIN32
|
||||
#define NOMINMAX
|
||||
#include <winsock2.h>
|
||||
#include <ws2tcpip.h>
|
||||
typedef SOCKET SocketFileDescriptor;
|
||||
#elif defined(__unix__) || (defined(__APPLE__) && defined(__MACH__))
|
||||
#include <sys/socket.h>
|
||||
#include <sys/types.h>
|
||||
#include <arpa/inet.h>
|
||||
#include <netinet/in.h>
|
||||
#include <unistd.h>
|
||||
#include <signal.h>
|
||||
#include <cerrno>
|
||||
#include <string.h>
|
||||
typedef int SocketFileDescriptor;
|
||||
#endif
|
||||
|
||||
namespace icsneo {
|
||||
|
||||
enum class RPC {
|
||||
DEVICE_FINDER_FIND_ALL,
|
||||
DEVICE_FINDER_GET_SUPORTED_DEVICES,
|
||||
DEVICE_OPEN,
|
||||
DEVICE_GO_ONLINE,
|
||||
DEVICE_GO_OFFLINE,
|
||||
DEVICE_CLOSE,
|
||||
DEVICE_LOCK,
|
||||
DEVICE_UNLOCK,
|
||||
SDIO_OPEN,
|
||||
SDIO_CLOSE,
|
||||
GET_EVENTS,
|
||||
GET_LAST_ERROR,
|
||||
GET_EVENT_COUNT,
|
||||
DISCARD_EVENTS,
|
||||
SET_EVENT_LIMIT,
|
||||
GET_EVENT_LIMIT
|
||||
};
|
||||
|
||||
static constexpr uint16_t RPC_PORT = 54949;
|
||||
|
||||
class SocketBase {
|
||||
public:
|
||||
enum class Protocol {
|
||||
TCP = SOCK_STREAM,
|
||||
};
|
||||
|
||||
bool open();
|
||||
bool close();
|
||||
bool connect();
|
||||
bool isOpen();
|
||||
bool isConnected();
|
||||
bool read(void* output, std::size_t length);
|
||||
bool write(const void* input, std::size_t length);
|
||||
bool writeString(const std::string& str);
|
||||
bool readString(std::string& str);
|
||||
|
||||
template<typename... Ts>
|
||||
bool writeTyped(Ts... input) {
|
||||
return (... && write(&input, sizeof(input)));
|
||||
}
|
||||
|
||||
template<typename... Ts>
|
||||
bool readTyped(Ts&... output) {
|
||||
return (... && read(&output, sizeof(output)));
|
||||
}
|
||||
|
||||
protected:
|
||||
Protocol protocol;
|
||||
uint16_t port;
|
||||
SocketFileDescriptor sockFileDescriptor;
|
||||
bool sockIsOpen = false;
|
||||
bool sockIsConnected = false;
|
||||
|
||||
void setIgnoreSIGPIPE();
|
||||
};
|
||||
|
||||
// RAII Socket
|
||||
class ActiveSocket : public SocketBase {
|
||||
public:
|
||||
ActiveSocket(SocketFileDescriptor sockFD);
|
||||
ActiveSocket(Protocol protocol, uint16_t port);
|
||||
~ActiveSocket();
|
||||
};
|
||||
|
||||
// RAII Socket IO
|
||||
class LockedSocket : public SocketBase {
|
||||
public:
|
||||
LockedSocket(SocketBase& socket, std::unique_lock<std::mutex>&& lock);
|
||||
private:
|
||||
std::unique_lock<std::mutex> lock;
|
||||
};
|
||||
|
||||
class Acceptor : public ActiveSocket {
|
||||
public:
|
||||
Acceptor(Protocol protocol, uint16_t port);
|
||||
bool initialize();
|
||||
std::shared_ptr<ActiveSocket> accept();
|
||||
|
||||
private:
|
||||
bool isValid = false;
|
||||
bool bind();
|
||||
bool listen();
|
||||
};
|
||||
|
||||
LockedSocket lockSocket();
|
||||
|
||||
}
|
||||
|
||||
#endif // __cplusplus
|
||||
|
||||
#endif
|
||||
@@ -3,7 +3,7 @@
|
||||
|
||||
// Hold the length of the longest name, so that C applications can allocate memory accordingly
|
||||
// Currently the longest is "Intrepid Ethernet Evaluation Board"
|
||||
#define ICSNEO_DEVICETYPE_LONGEST_NAME (35 + 1) // Add 1 so that if someone forgets, they still have space for null terminator
|
||||
#define ICSNEO_DEVICETYPE_LONGEST_NAME (145 + 1) // Add 1 so that if someone forgets, they still have space for null terminator
|
||||
#define ICSNEO_DEVICETYPE_LONGEST_DESCRIPTION (ICSNEO_DEVICETYPE_LONGEST_NAME + 7) // 6 character serial, plus space
|
||||
|
||||
#ifndef __cplusplus
|
||||
|
||||
@@ -11,7 +11,7 @@ typedef std::function< std::unique_ptr<Driver>(device_eventhandler_t err, neodev
|
||||
class FoundDevice {
|
||||
public:
|
||||
neodevice_handle_t handle = 0;
|
||||
char serial[7] = {};
|
||||
deviceserial_t serial = {};
|
||||
uint16_t productId = 0;
|
||||
driver_factory_t makeDriver;
|
||||
};
|
||||
|
||||
@@ -18,6 +18,7 @@ typedef void* devicehandle_t;
|
||||
#endif
|
||||
|
||||
typedef int32_t neodevice_handle_t;
|
||||
typedef char deviceserial_t[7];
|
||||
|
||||
#pragma pack(push, 1)
|
||||
|
||||
@@ -31,7 +32,7 @@ typedef struct {
|
||||
devicehandle_t device; // Pointer back to the C++ device object
|
||||
neodevice_handle_t handle; // Handle for use by the underlying driver
|
||||
devicetype_t type;
|
||||
char serial[7];
|
||||
deviceserial_t serial;
|
||||
} neodevice_t;
|
||||
|
||||
#pragma pack(pop)
|
||||
|
||||
@@ -25,7 +25,7 @@ public:
|
||||
* in cdcacmlinux.cpp and cdcacmdarwin.cpp respectively
|
||||
* Other POSIX systems (BSDs, QNX, etc) will need bespoke code written in the future
|
||||
*/
|
||||
CDCACM(const device_eventhandler_t& err, neodevice_t& forDevice) : Driver(err), device(forDevice) {}
|
||||
CDCACM(const device_eventhandler_t& err, neodevice_t& forDevice) : Driver(err, forDevice) {}
|
||||
~CDCACM();
|
||||
static void Find(std::vector<FoundDevice>& found);
|
||||
|
||||
@@ -37,7 +37,6 @@ public:
|
||||
void awaitModeChangeComplete() override;
|
||||
|
||||
private:
|
||||
neodevice_t& device;
|
||||
int fd = -1;
|
||||
std::optional<ino_t> disallowedInode;
|
||||
std::atomic<bool> modeChanging{false};
|
||||
|
||||
@@ -60,8 +60,6 @@ private:
|
||||
void readTask();
|
||||
void writeTask();
|
||||
bool openable; // Set to false in the constructor if the object has not been found in searchResultDevices
|
||||
|
||||
neodevice_t& device;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
@@ -24,9 +24,9 @@ public:
|
||||
bool isOpen() override;
|
||||
bool close() override;
|
||||
bool isEthernet() const override { return true; }
|
||||
bool enableHeartbeat() const override { return true; }
|
||||
private:
|
||||
char errbuf[PCAP_ERRBUF_SIZE] = { 0 };
|
||||
neodevice_t& device;
|
||||
uint8_t deviceMAC[6];
|
||||
bool openable = true;
|
||||
EthernetPacketizer ethPacketizer;
|
||||
|
||||
@@ -0,0 +1,36 @@
|
||||
#ifndef __SHAREDMEMORY_POSIX_H_
|
||||
#define __SHAREDMEMORY_POSIX_H_
|
||||
|
||||
#ifdef __cplusplus
|
||||
|
||||
#include <string>
|
||||
#include <optional>
|
||||
#include "icsneo/api/eventmanager.h"
|
||||
|
||||
namespace icsneo {
|
||||
|
||||
class SharedMemory {
|
||||
public:
|
||||
SharedMemory() : report(makeEventHandler()) {};
|
||||
~SharedMemory();
|
||||
bool open(const std::string& name, uint32_t size, bool create = false);
|
||||
bool close();
|
||||
uint8_t* data();
|
||||
|
||||
private:
|
||||
virtual device_eventhandler_t makeEventHandler() {
|
||||
return [](APIEvent::Type type, APIEvent::Severity severity)
|
||||
{ EventManager::GetInstance().add(type, severity); };
|
||||
}
|
||||
|
||||
device_eventhandler_t report;
|
||||
std::optional<std::string> mName;
|
||||
std::optional<std::pair<uint8_t*, uint32_t>> mData;
|
||||
std::optional<bool> mCreated;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif // __cplusplus
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,40 @@
|
||||
#ifndef __SHAREDSEMAPHORE_POSIX_H_
|
||||
#define __SHAREDSEMAPHORE_POSIX_H_
|
||||
|
||||
#ifdef __cplusplus
|
||||
|
||||
#include <string>
|
||||
#include <optional>
|
||||
#include <atomic>
|
||||
#include <semaphore.h>
|
||||
#include "icsneo/api/eventmanager.h"
|
||||
|
||||
namespace icsneo {
|
||||
|
||||
class SharedSemaphore {
|
||||
public:
|
||||
~SharedSemaphore();
|
||||
bool open(const std::string& name, bool create = false, unsigned initialCount = 0);
|
||||
bool close();
|
||||
bool wait(const std::chrono::milliseconds& timeout);
|
||||
bool post();
|
||||
|
||||
private:
|
||||
virtual device_eventhandler_t makeEventHandler() {
|
||||
return [](APIEvent::Type type, APIEvent::Severity severity)
|
||||
{ EventManager::GetInstance().add(type, severity); };
|
||||
}
|
||||
|
||||
std::atomic<bool> closing = false;
|
||||
std::atomic<bool> waiting = false;
|
||||
device_eventhandler_t report = makeEventHandler();
|
||||
std::optional<const std::string> mName;
|
||||
std::optional<sem_t*> semaphore;
|
||||
std::optional<const bool> created;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif // __cplusplus
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,12 @@
|
||||
#ifndef __SHAREDMEMORY_H_
|
||||
#define __SHAREDMEMORY_H_
|
||||
|
||||
#ifdef _WIN32
|
||||
#include "icsneo/platform/windows/sharedmemory.h"
|
||||
#elif defined(__unix__) || (defined(__APPLE__) && defined(__MACH__))
|
||||
#include "icsneo/platform/posix/sharedmemory.h"
|
||||
#else
|
||||
#warning "Shared memory are not supported on this platform"
|
||||
#endif
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,12 @@
|
||||
#ifndef __SHAREDSEMAPHORE_H_
|
||||
#define __SHAREDSEMAPHORE_H_
|
||||
|
||||
#ifdef _WIN32
|
||||
#include "icsneo/platform/windows/sharedsemaphore.h"
|
||||
#elif defined(__unix__) || (defined(__APPLE__) && defined(__MACH__))
|
||||
#include "icsneo/platform/posix/sharedsemaphore.h"
|
||||
#else
|
||||
#warning "Shared semaphores are not supported on this platform"
|
||||
#endif
|
||||
|
||||
#endif
|
||||
@@ -24,10 +24,10 @@ public:
|
||||
bool isOpen() override;
|
||||
bool close() override;
|
||||
bool isEthernet() const override { return true; }
|
||||
bool enableHeartbeat() const override { return true; }
|
||||
private:
|
||||
const PCAPDLL& pcap;
|
||||
char errbuf[PCAP_ERRBUF_SIZE] = { 0 };
|
||||
neodevice_t& device;
|
||||
uint8_t deviceMAC[6];
|
||||
bool openable = true;
|
||||
EthernetPacketizer ethPacketizer;
|
||||
|
||||
@@ -0,0 +1,37 @@
|
||||
#ifndef __SHAREDMEMORY_WINDOWS_H_
|
||||
#define __SHAREDMEMORY_WINDOWS_H_
|
||||
|
||||
#ifdef __cplusplus
|
||||
|
||||
#include <string>
|
||||
#include <optional>
|
||||
#include "icsneo/platform/windows.h"
|
||||
#include "icsneo/api/eventmanager.h"
|
||||
|
||||
namespace icsneo {
|
||||
|
||||
class SharedMemory {
|
||||
public:
|
||||
SharedMemory() : report(makeEventHandler()) {};
|
||||
~SharedMemory();
|
||||
bool open(const std::string& name, uint32_t size, bool create = false);
|
||||
bool close();
|
||||
uint8_t* data();
|
||||
|
||||
private:
|
||||
virtual device_eventhandler_t makeEventHandler() {
|
||||
return [](APIEvent::Type type, APIEvent::Severity severity)
|
||||
{ EventManager::GetInstance().add(type, severity); };
|
||||
}
|
||||
|
||||
device_eventhandler_t report;
|
||||
std::optional<HANDLE> mHandle;
|
||||
std::optional<std::pair<uint8_t*, uint32_t>> mData;
|
||||
std::optional<bool> mCreated;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif // __cplusplus
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,38 @@
|
||||
#ifndef __SHAREDSEMAPHORE_WINDOWS_H_
|
||||
#define __SHAREDSEMAPHORE_WINDOWS_H_
|
||||
|
||||
#ifdef __cplusplus
|
||||
|
||||
#include <string>
|
||||
#include <chrono>
|
||||
#include <optional>
|
||||
#include "icsneo/platform/windows.h"
|
||||
#include "icsneo/api/eventmanager.h"
|
||||
|
||||
namespace icsneo {
|
||||
|
||||
class SharedSemaphore {
|
||||
public:
|
||||
~SharedSemaphore();
|
||||
bool open(const std::string& name, bool create = false, unsigned initialCount = 0);
|
||||
bool close();
|
||||
bool wait(const std::chrono::milliseconds& timeout);
|
||||
bool post();
|
||||
|
||||
private:
|
||||
virtual device_eventhandler_t makeEventHandler() {
|
||||
return [](APIEvent::Type type, APIEvent::Severity severity)
|
||||
{ EventManager::GetInstance().add(type, severity); };
|
||||
}
|
||||
|
||||
bool closing = false;
|
||||
device_eventhandler_t report = makeEventHandler();
|
||||
std::optional<HANDLE> semaphore;
|
||||
std::optional<bool> created;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif // __cplusplus
|
||||
|
||||
#endif
|
||||
@@ -31,7 +31,6 @@ public:
|
||||
private:
|
||||
bool open(bool fromAsync);
|
||||
bool opening = false;
|
||||
neodevice_t& device;
|
||||
|
||||
struct Detail;
|
||||
std::shared_ptr<Detail> detail;
|
||||
|
||||
Reference in New Issue
Block a user