Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Binary file modified dist/arm64-osx/lib/Release/libstreamrproxyclient.dylib
Binary file not shown.
81 changes: 81 additions & 0 deletions shim.c
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
#include <dlfcn.h>
#include <stdio.h>
#include "shim.h"
#include <stdint.h>

void (*proxyClientInitLibraryPtr)(void); // NOLINT
void (*proxyClientCleanupLibraryPtr)(void); // NOLINT
Expand All @@ -12,6 +13,18 @@ void (*proxyClientDisconnectPtr)(const ProxyResult**, uint64_t);
uint64_t (*proxyClientPublishPtr)(const ProxyResult**, uint64_t, const char*, uint64_t, const char*);
void* proxyClientLibrary;

uint64_t (*streamrNodeNewPtr)(const StreamrResult**, const char*, const StreamrNodeConfig*);
void (*streamrNodeDeletePtr)(const StreamrResult**, uint64_t);
void (*streamrNodeStartPtr)(const StreamrResult**, uint64_t);
void (*streamrNodeStopPtr)(const StreamrResult**, uint64_t);
void (*streamrNodeJoinStreamPartPtr)(const StreamrResult**, uint64_t, const char*, const StreamrPeer*, uint64_t);
void (*streamrNodeLeaveStreamPartPtr)(const StreamrResult**, uint64_t, const char*);
void (*streamrNodePublishPtr)(const StreamrResult**, uint64_t, const char*, const char*, uint64_t, const char*);
uint64_t (*streamrNodeSubscribePtr)(const StreamrResult**, uint64_t, const char*, StreamrNodeMessageCallback, void*);
void (*streamrNodeUnsubscribePtr)(const StreamrResult**, uint64_t, uint64_t);
uint64_t (*streamrNodeGetNeighborCountPtr)(const StreamrResult**, uint64_t, const char*);
void (*streamrNodeSetProxiesPtr)(const StreamrResult**, uint64_t, const char*, const StreamrPeer*, uint64_t, StreamrProxyDirection, uint64_t);

void loadSharedLibrary(const char* libFilePath) {
proxyClientLibrary = dlopen(libFilePath, RTLD_LOCAL | RTLD_LAZY);
proxyClientInitLibraryPtr = (void (*)(void))dlsym(proxyClientLibrary, "proxyClientInitLibrary"); // NOLINT
Expand All @@ -22,6 +35,26 @@ void loadSharedLibrary(const char* libFilePath) {
proxyClientConnectPtr = (uint64_t (*)(const ProxyResult**, uint64_t, const Proxy*, uint64_t))dlsym(proxyClientLibrary, "proxyClientConnect");
proxyClientDisconnectPtr = (void (*)(const ProxyResult**, uint64_t))dlsym(proxyClientLibrary, "proxyClientDisconnect");
proxyClientPublishPtr = (uint64_t (*)(const ProxyResult**, uint64_t, const char*, uint64_t, const char*))dlsym(proxyClientLibrary, "proxyClientPublish");
streamrNodeNewPtr = (uint64_t (*)(const StreamrResult**, const char*, const StreamrNodeConfig*))dlsym(proxyClientLibrary, "streamrNodeNew");
streamrNodeDeletePtr = (void (*)(const StreamrResult**, uint64_t))dlsym(proxyClientLibrary, "streamrNodeDelete");
streamrNodeStartPtr = (void (*)(const StreamrResult**, uint64_t))dlsym(proxyClientLibrary, "streamrNodeStart");
streamrNodeStopPtr = (void (*)(const StreamrResult**, uint64_t))dlsym(proxyClientLibrary, "streamrNodeStop");
streamrNodeJoinStreamPartPtr = (void (*)(const StreamrResult**, uint64_t, const char*, const StreamrPeer*, uint64_t))dlsym(proxyClientLibrary, "streamrNodeJoinStreamPart");
streamrNodeLeaveStreamPartPtr = (void (*)(const StreamrResult**, uint64_t, const char*))dlsym(proxyClientLibrary, "streamrNodeLeaveStreamPart");
streamrNodePublishPtr = (void (*)(const StreamrResult**, uint64_t, const char*, const char*, uint64_t, const char*))dlsym(proxyClientLibrary, "streamrNodePublish");
streamrNodeSubscribePtr = (uint64_t (*)(const StreamrResult**, uint64_t, const char*, StreamrNodeMessageCallback, void*))dlsym(proxyClientLibrary, "streamrNodeSubscribe");
streamrNodeUnsubscribePtr = (void (*)(const StreamrResult**, uint64_t, uint64_t))dlsym(proxyClientLibrary, "streamrNodeUnsubscribe");
streamrNodeGetNeighborCountPtr = (uint64_t (*)(const StreamrResult**, uint64_t, const char*))dlsym(proxyClientLibrary, "streamrNodeGetNeighborCount");
streamrNodeSetProxiesPtr = (void (*)(const StreamrResult**, uint64_t, const char*, const StreamrPeer*, uint64_t, StreamrProxyDirection, uint64_t))dlsym(proxyClientLibrary, "streamrNodeSetProxies");
}

// Defined by cgo (//export goStreamrNodeMessage in streamrnode.go).
extern void goStreamrNodeMessage(uint64_t nodeHandle, char* streamPartId, char* content, uint64_t contentLength, void* userData);

// C-ABI trampoline handed to streamrNodeSubscribe: bridges the const
// signature of the C API to the cgo export.
static void shimStreamrNodeMessageCallback(uint64_t nodeHandle, const char* streamPartId, const char* content, uint64_t contentLength, void* userData) {
goStreamrNodeMessage(nodeHandle, (char*)streamPartId, (char*)content, contentLength, userData);
}

void closeSharedLibrary() {
Expand Down Expand Up @@ -60,3 +93,51 @@ void proxyClientDisconnectWrapper(const ProxyResult** result, uint64_t id) {
uint64_t proxyClientPublishWrapper(const ProxyResult** result, uint64_t id, const char* content, uint64_t contentLength, const char* ethereumPrivateKey) {
return proxyClientPublishPtr(result, id, content, contentLength, ethereumPrivateKey);
}

uint64_t streamrNodeNewWrapper(const StreamrResult** result, const char* ownEthereumAddress, const StreamrNodeConfig* config) {
return streamrNodeNewPtr(result, ownEthereumAddress, config);
}

void streamrNodeDeleteWrapper(const StreamrResult** result, uint64_t nodeHandle) {
streamrNodeDeletePtr(result, nodeHandle);
}

void streamrNodeStartWrapper(const StreamrResult** result, uint64_t nodeHandle) {
streamrNodeStartPtr(result, nodeHandle);
}

void streamrNodeStopWrapper(const StreamrResult** result, uint64_t nodeHandle) {
streamrNodeStopPtr(result, nodeHandle);
}

void streamrNodeJoinStreamPartWrapper(const StreamrResult** result, uint64_t nodeHandle, const char* streamPartId, const StreamrPeer* entryPoints, uint64_t numEntryPoints) {
streamrNodeJoinStreamPartPtr(result, nodeHandle, streamPartId, entryPoints, numEntryPoints);
}

void streamrNodeLeaveStreamPartWrapper(const StreamrResult** result, uint64_t nodeHandle, const char* streamPartId) {
streamrNodeLeaveStreamPartPtr(result, nodeHandle, streamPartId);
}

void streamrNodePublishWrapper(const StreamrResult** result, uint64_t nodeHandle, const char* streamPartId, const char* content, uint64_t contentLength, const char* ethereumPrivateKey) {
streamrNodePublishPtr(result, nodeHandle, streamPartId, content, contentLength, ethereumPrivateKey);
}

uint64_t streamrNodeSubscribeWrapper(const StreamrResult** result, uint64_t nodeHandle, const char* streamPartId, uintptr_t callbackKey) {
return streamrNodeSubscribePtr(result, nodeHandle, streamPartId, shimStreamrNodeMessageCallback, (void*)callbackKey);
}

void streamrNodeUnsubscribeWrapper(const StreamrResult** result, uint64_t nodeHandle, uint64_t subscriptionHandle) {
streamrNodeUnsubscribePtr(result, nodeHandle, subscriptionHandle);
}

uint64_t streamrNodeGetNeighborCountWrapper(const StreamrResult** result, uint64_t nodeHandle, const char* streamPartId) {
return streamrNodeGetNeighborCountPtr(result, nodeHandle, streamPartId);
}

void streamrNodeSetProxiesWrapper(const StreamrResult** result, uint64_t nodeHandle, const char* streamPartId, const StreamrPeer* proxies, uint64_t numProxies, int direction, uint64_t connectionCount) {
streamrNodeSetProxiesPtr(result, nodeHandle, streamPartId, proxies, numProxies, (StreamrProxyDirection)direction, connectionCount);
}

const StreamrPeer* streamrErrorGetPeerWrapper(const StreamrError* error) {
return error->peer;
}
20 changes: 20 additions & 0 deletions shim.h
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
#define SHIM_H

#include "streamrproxyclient.h"
#include "streamrnode.h"

#ifdef __cplusplus
extern "C" {
Expand All @@ -19,6 +20,25 @@ uint64_t proxyClientConnectWrapper(const ProxyResult** result, uint64_t id, cons
void proxyClientDisconnectWrapper(const ProxyResult** result, uint64_t id);
uint64_t proxyClientPublishWrapper(const ProxyResult** result, uint64_t id, const char* content, uint64_t contentLength, const char* ethereumPrivateKey);

// cgo cannot address members of anonymous unions, so the StreamrError
// peer/proxy union member is read through this accessor.
const StreamrPeer* streamrErrorGetPeerWrapper(const StreamrError* error);

// Full-node API (streamrnode.h). streamrNodeSubscribeWrapper installs the
// cgo-exported Go trampoline as the message callback; callbackKey is the
// Go-side registry key carried through userData.
uint64_t streamrNodeNewWrapper(const StreamrResult** result, const char* ownEthereumAddress, const StreamrNodeConfig* config);
void streamrNodeDeleteWrapper(const StreamrResult** result, uint64_t nodeHandle);
void streamrNodeStartWrapper(const StreamrResult** result, uint64_t nodeHandle);
void streamrNodeStopWrapper(const StreamrResult** result, uint64_t nodeHandle);
void streamrNodeJoinStreamPartWrapper(const StreamrResult** result, uint64_t nodeHandle, const char* streamPartId, const StreamrPeer* entryPoints, uint64_t numEntryPoints);
void streamrNodeLeaveStreamPartWrapper(const StreamrResult** result, uint64_t nodeHandle, const char* streamPartId);
void streamrNodePublishWrapper(const StreamrResult** result, uint64_t nodeHandle, const char* streamPartId, const char* content, uint64_t contentLength, const char* ethereumPrivateKey);
uint64_t streamrNodeSubscribeWrapper(const StreamrResult** result, uint64_t nodeHandle, const char* streamPartId, uintptr_t callbackKey);
void streamrNodeUnsubscribeWrapper(const StreamrResult** result, uint64_t nodeHandle, uint64_t subscriptionHandle);
uint64_t streamrNodeGetNeighborCountWrapper(const StreamrResult** result, uint64_t nodeHandle, const char* streamPartId);
void streamrNodeSetProxiesWrapper(const StreamrResult** result, uint64_t nodeHandle, const char* streamPartId, const StreamrPeer* proxies, uint64_t numProxies, int direction, uint64_t connectionCount);

#ifdef __cplusplus
}
#endif
Expand Down
102 changes: 102 additions & 0 deletions streamrcommon.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,102 @@
#ifndef STREAMR_COMMON_H
#define STREAMR_COMMON_H

// Shared infrastructure of the Streamr shared-library C APIs: the result
// and error types, the peer locator struct, and the library lifecycle.
// Used by both the full-node API (streamrnode.h) and the proxy-client API
// (streamrproxyclient.h). These are the FINAL, API-neutral names decided
// in phase D3 of trackerless-network-completion-plan.md; the former
// proxy-prefixed names remain available as deprecated aliases in
// streamrproxyclient.h for one release.

// NOLINTNEXTLINE
#include <stdint.h>

#if defined(__clang__) || defined(__GNUC__)
#define SHARED_EXPORT __attribute__((visibility("default")))
#define SHARED_LOCAL __attribute__((visibility("hidden")))
#define STREAMR_DEPRECATED(msg) __attribute__((deprecated(msg)))
#else
#define SHARED_EXPORT
#define SHARED_LOCAL
#define STREAMR_DEPRECATED(msg)
#endif

#ifdef __cplusplus
#define EXTERN_C extern "C"
#else
#define EXTERN_C
#endif

// Error codes shared by both APIs.
#define ERROR_INVALID_ETHEREUM_ADDRESS "INVALID_ETHEREUM_ADDRESS"
#define ERROR_INVALID_STREAM_PART_ID "INVALID_STREAM_PART_ID"

/**
* @brief A peer locator: the websocket URL a node listens on plus the
* ethereum address its node id is derived from. Used both for the proxies
* of the proxy-client API and for the entry points of the full-node API.
*/
// NOLINTNEXTLINE
typedef struct StreamrPeer {
const char* websocketUrl;
const char* ethereumAddress;
} StreamrPeer;

/**
* @brief One error of a failed or partially failed call. code is one of
* the ERROR_* constants; peer points at the peer the error concerns, or
* NULL when the error is not peer-specific.
*/
// NOLINTNEXTLINE
typedef struct StreamrError {
const char* message;
const char* code;
// The peer this error concerns. The member is accessible both as
// `peer` (final name) and as `proxy` (the pre-3.0 spelling, kept for
// source compatibility with proxy-API consumers; same storage).
union {
const struct StreamrPeer* peer;
const struct StreamrPeer* proxy;
};
} StreamrError;

/**
* @brief The result of every call in both APIs, returned through a
* const StreamrResult** out parameter. Every returned result — success or
* error — MUST be freed with streamrResultDelete(). Calls that cannot
* partially succeed leave `successful`/`numSuccessful` unused.
*/
// NOLINTNEXTLINE
typedef struct StreamrResult {
StreamrError* errors;
uint64_t numErrors;
StreamrPeer* successful;
uint64_t numSuccessful;
} StreamrResult;

/**
* @brief Delete a StreamrResult. Must be called on every result returned
* by any call of either API.
*/
EXTERN_C SHARED_EXPORT void streamrResultDelete(
const StreamrResult* streamrResult);

/**
* @brief Initialize the library. Called automatically when the library is
* loaded, but can be called explicitly to force a re-initialization (e.g.
* after streamrCleanupLibrary()).
*/
EXTERN_C SHARED_EXPORT void streamrInitLibrary(void);

/**
* @brief Clean up the library. MUST be called before the program exits:
* the standard dynamic-library destructor runs after static variables
* have already been destroyed, too late to tear down the objects that
* depend on them. Safe to call multiple times. The library may be used
* again after a cleanup: any API call re-initializes it automatically
* (an explicit streamrInitLibrary() call is also fine).
*/
EXTERN_C SHARED_EXPORT void streamrCleanupLibrary(void);

#endif /* STREAMR_COMMON_H */
Loading