mirror of
https://github.com/logos-messaging/logos-delivery.git
synced 2026-08-27 03:21:16 +00:00
Start using nim-ffi to implement libwaku (#3656)
* deep changes in libwaku to adap to nim-ffi * start using ffi pragma in library * update some binding examples * add missing declare_lib.nim file * properly rename api files in library folder
This commit is contained in:
+144
-139
@@ -21,37 +21,43 @@ pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
|
||||
pthread_cond_t cond = PTHREAD_COND_INITIALIZER;
|
||||
int callback_executed = 0;
|
||||
|
||||
void waitForCallback() {
|
||||
void waitForCallback()
|
||||
{
|
||||
pthread_mutex_lock(&mutex);
|
||||
while (!callback_executed) {
|
||||
while (!callback_executed)
|
||||
{
|
||||
pthread_cond_wait(&cond, &mutex);
|
||||
}
|
||||
callback_executed = 0;
|
||||
pthread_mutex_unlock(&mutex);
|
||||
}
|
||||
|
||||
void signal_cond() {
|
||||
void signal_cond()
|
||||
{
|
||||
pthread_mutex_lock(&mutex);
|
||||
callback_executed = 1;
|
||||
pthread_cond_signal(&cond);
|
||||
pthread_mutex_unlock(&mutex);
|
||||
}
|
||||
|
||||
#define WAKU_CALL(call) \
|
||||
do { \
|
||||
int ret = call; \
|
||||
if (ret != 0) { \
|
||||
std::cout << "Failed the call to: " << #call << ". Code: " << ret << "\n"; \
|
||||
} \
|
||||
waitForCallback(); \
|
||||
} while (0)
|
||||
#define WAKU_CALL(call) \
|
||||
do \
|
||||
{ \
|
||||
int ret = call; \
|
||||
if (ret != 0) \
|
||||
{ \
|
||||
std::cout << "Failed the call to: " << #call << ". Code: " << ret << "\n"; \
|
||||
} \
|
||||
waitForCallback(); \
|
||||
} while (0)
|
||||
|
||||
struct ConfigNode {
|
||||
char host[128];
|
||||
int port;
|
||||
char key[128];
|
||||
int relay;
|
||||
char peers[2048];
|
||||
struct ConfigNode
|
||||
{
|
||||
char host[128];
|
||||
int port;
|
||||
char key[128];
|
||||
int relay;
|
||||
char peers[2048];
|
||||
};
|
||||
|
||||
// Arguments parsing
|
||||
@@ -59,70 +65,76 @@ static char doc[] = "\nC example that shows how to use the waku library.";
|
||||
static char args_doc[] = "";
|
||||
|
||||
static struct argp_option options[] = {
|
||||
{ "host", 'h', "HOST", 0, "IP to listen for for LibP2P traffic. (default: \"0.0.0.0\")"},
|
||||
{ "port", 'p', "PORT", 0, "TCP listening port. (default: \"60000\")"},
|
||||
{ "key", 'k', "KEY", 0, "P2P node private key as 64 char hex string."},
|
||||
{ "relay", 'r', "RELAY", 0, "Enable relay protocol: 1 or 0. (default: 1)"},
|
||||
{ "peers", 'a', "PEERS", 0, "Comma-separated list of peer-multiaddress to connect\
|
||||
{"host", 'h', "HOST", 0, "IP to listen for for LibP2P traffic. (default: \"0.0.0.0\")"},
|
||||
{"port", 'p', "PORT", 0, "TCP listening port. (default: \"60000\")"},
|
||||
{"key", 'k', "KEY", 0, "P2P node private key as 64 char hex string."},
|
||||
{"relay", 'r', "RELAY", 0, "Enable relay protocol: 1 or 0. (default: 1)"},
|
||||
{"peers", 'a', "PEERS", 0, "Comma-separated list of peer-multiaddress to connect\
|
||||
to. (default: \"\") e.g. \"/ip4/127.0.0.1/tcp/60001/p2p/16Uiu2HAmVFXtAfSj4EiR7mL2KvL4EE2wztuQgUSBoj2Jx2KeXFLN\""},
|
||||
{ 0 }
|
||||
};
|
||||
{0}};
|
||||
|
||||
static error_t parse_opt(int key, char *arg, struct argp_state *state) {
|
||||
static error_t parse_opt(int key, char *arg, struct argp_state *state)
|
||||
{
|
||||
|
||||
struct ConfigNode *cfgNode = (ConfigNode *) state->input;
|
||||
switch (key) {
|
||||
case 'h':
|
||||
snprintf(cfgNode->host, 128, "%s", arg);
|
||||
break;
|
||||
case 'p':
|
||||
cfgNode->port = atoi(arg);
|
||||
break;
|
||||
case 'k':
|
||||
snprintf(cfgNode->key, 128, "%s", arg);
|
||||
break;
|
||||
case 'r':
|
||||
cfgNode->relay = atoi(arg);
|
||||
break;
|
||||
case 'a':
|
||||
snprintf(cfgNode->peers, 2048, "%s", arg);
|
||||
break;
|
||||
case ARGP_KEY_ARG:
|
||||
if (state->arg_num >= 1) /* Too many arguments. */
|
||||
struct ConfigNode *cfgNode = (ConfigNode *)state->input;
|
||||
switch (key)
|
||||
{
|
||||
case 'h':
|
||||
snprintf(cfgNode->host, 128, "%s", arg);
|
||||
break;
|
||||
case 'p':
|
||||
cfgNode->port = atoi(arg);
|
||||
break;
|
||||
case 'k':
|
||||
snprintf(cfgNode->key, 128, "%s", arg);
|
||||
break;
|
||||
case 'r':
|
||||
cfgNode->relay = atoi(arg);
|
||||
break;
|
||||
case 'a':
|
||||
snprintf(cfgNode->peers, 2048, "%s", arg);
|
||||
break;
|
||||
case ARGP_KEY_ARG:
|
||||
if (state->arg_num >= 1) /* Too many arguments. */
|
||||
argp_usage(state);
|
||||
break;
|
||||
case ARGP_KEY_END:
|
||||
break;
|
||||
default:
|
||||
return ARGP_ERR_UNKNOWN;
|
||||
}
|
||||
break;
|
||||
case ARGP_KEY_END:
|
||||
break;
|
||||
default:
|
||||
return ARGP_ERR_UNKNOWN;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void event_handler(const char* msg, size_t len) {
|
||||
void event_handler(const char *msg, size_t len)
|
||||
{
|
||||
printf("Receiving event: %s\n", msg);
|
||||
}
|
||||
|
||||
void handle_error(const char* msg, size_t len) {
|
||||
void handle_error(const char *msg, size_t len)
|
||||
{
|
||||
printf("handle_error: %s\n", msg);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
template <class F>
|
||||
auto cify(F&& f) {
|
||||
static F fn = std::forward<F>(f);
|
||||
return [](int callerRet, const char* msg, size_t len, void* userData) {
|
||||
signal_cond();
|
||||
return fn(msg, len);
|
||||
};
|
||||
auto cify(F &&f)
|
||||
{
|
||||
static F fn = std::forward<F>(f);
|
||||
return [](int callerRet, const char *msg, size_t len, void *userData)
|
||||
{
|
||||
signal_cond();
|
||||
return fn(msg, len);
|
||||
};
|
||||
}
|
||||
|
||||
static struct argp argp = { options, parse_opt, args_doc, doc, 0, 0, 0 };
|
||||
static struct argp argp = {options, parse_opt, args_doc, doc, 0, 0, 0};
|
||||
|
||||
// Beginning of UI program logic
|
||||
|
||||
enum PROGRAM_STATE {
|
||||
enum PROGRAM_STATE
|
||||
{
|
||||
MAIN_MENU,
|
||||
SUBSCRIBE_TOPIC_MENU,
|
||||
CONNECT_TO_OTHER_NODE_MENU,
|
||||
@@ -131,18 +143,21 @@ enum PROGRAM_STATE {
|
||||
|
||||
enum PROGRAM_STATE current_state = MAIN_MENU;
|
||||
|
||||
void show_main_menu() {
|
||||
void show_main_menu()
|
||||
{
|
||||
printf("\nPlease, select an option:\n");
|
||||
printf("\t1.) Subscribe to topic\n");
|
||||
printf("\t2.) Connect to other node\n");
|
||||
printf("\t3.) Publish a message\n");
|
||||
}
|
||||
|
||||
void handle_user_input(void* ctx) {
|
||||
void handle_user_input(void *ctx)
|
||||
{
|
||||
char cmd[1024];
|
||||
memset(cmd, 0, 1024);
|
||||
int numRead = read(0, cmd, 1024);
|
||||
if (numRead <= 0) {
|
||||
if (numRead <= 0)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -154,12 +169,11 @@ void handle_user_input(void* ctx) {
|
||||
char pubsubTopic[128];
|
||||
scanf("%127s", pubsubTopic);
|
||||
|
||||
WAKU_CALL( waku_relay_subscribe(ctx,
|
||||
pubsubTopic,
|
||||
cify([&](const char* msg, size_t len) {
|
||||
event_handler(msg, len);
|
||||
}),
|
||||
nullptr) );
|
||||
WAKU_CALL(waku_relay_subscribe(ctx,
|
||||
cify([&](const char *msg, size_t len)
|
||||
{ event_handler(msg, len); }),
|
||||
nullptr,
|
||||
pubsubTopic));
|
||||
printf("The subscription went well\n");
|
||||
|
||||
show_main_menu();
|
||||
@@ -171,15 +185,14 @@ void handle_user_input(void* ctx) {
|
||||
printf("e.g.: /ip4/127.0.0.1/tcp/60001/p2p/16Uiu2HAmVFXtAfSj4EiR7mL2KvL4EE2wztuQgUSBoj2Jx2KeXFLN\n");
|
||||
char peerAddr[512];
|
||||
scanf("%511s", peerAddr);
|
||||
WAKU_CALL( waku_connect(ctx,
|
||||
peerAddr,
|
||||
10000 /* timeoutMs */,
|
||||
cify([&](const char* msg, size_t len) {
|
||||
event_handler(msg, len);
|
||||
}),
|
||||
nullptr));
|
||||
WAKU_CALL(waku_connect(ctx,
|
||||
cify([&](const char *msg, size_t len)
|
||||
{ event_handler(msg, len); }),
|
||||
nullptr,
|
||||
peerAddr,
|
||||
10000 /* timeoutMs */));
|
||||
show_main_menu();
|
||||
break;
|
||||
break;
|
||||
|
||||
case PUBLISH_MESSAGE_MENU:
|
||||
{
|
||||
@@ -193,28 +206,26 @@ void handle_user_input(void* ctx) {
|
||||
|
||||
std::string contentTopic;
|
||||
waku_content_topic(ctx,
|
||||
cify([&contentTopic](const char *msg, size_t len)
|
||||
{ contentTopic = msg; }),
|
||||
nullptr,
|
||||
"appName",
|
||||
1,
|
||||
"contentTopicName",
|
||||
"encoding",
|
||||
cify([&contentTopic](const char* msg, size_t len) {
|
||||
contentTopic = msg;
|
||||
}),
|
||||
nullptr);
|
||||
1,
|
||||
"contentTopicName",
|
||||
"encoding");
|
||||
|
||||
snprintf(jsonWakuMsg,
|
||||
2048,
|
||||
"{\"payload\":\"%s\",\"contentTopic\":\"%s\"}",
|
||||
msgPayload.data(), contentTopic.c_str());
|
||||
|
||||
WAKU_CALL( waku_relay_publish(ctx,
|
||||
"/waku/2/rs/16/32",
|
||||
jsonWakuMsg,
|
||||
10000 /*timeout ms*/,
|
||||
cify([&](const char* msg, size_t len) {
|
||||
event_handler(msg, len);
|
||||
}),
|
||||
nullptr) );
|
||||
WAKU_CALL(waku_relay_publish(ctx,
|
||||
cify([&](const char *msg, size_t len)
|
||||
{ event_handler(msg, len); }),
|
||||
nullptr,
|
||||
"/waku/2/rs/16/32",
|
||||
jsonWakuMsg,
|
||||
10000 /*timeout ms*/));
|
||||
|
||||
show_main_menu();
|
||||
}
|
||||
@@ -227,12 +238,14 @@ void handle_user_input(void* ctx) {
|
||||
|
||||
// End of UI program logic
|
||||
|
||||
void show_help_and_exit() {
|
||||
void show_help_and_exit()
|
||||
{
|
||||
printf("Wrong parameters\n");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
int main(int argc, char** argv) {
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
struct ConfigNode cfgNode;
|
||||
// default values
|
||||
snprintf(cfgNode.host, 128, "0.0.0.0");
|
||||
@@ -241,8 +254,8 @@ int main(int argc, char** argv) {
|
||||
cfgNode.port = 60000;
|
||||
cfgNode.relay = 1;
|
||||
|
||||
if (argp_parse(&argp, argc, argv, 0, 0, &cfgNode)
|
||||
== ARGP_ERR_UNKNOWN) {
|
||||
if (argp_parse(&argp, argc, argv, 0, 0, &cfgNode) == ARGP_ERR_UNKNOWN)
|
||||
{
|
||||
show_help_and_exit();
|
||||
}
|
||||
|
||||
@@ -260,72 +273,64 @@ int main(int argc, char** argv) {
|
||||
\"discv5UdpPort\": 9999, \
|
||||
\"dnsDiscoveryUrl\": \"enrtree://AMOJVZX4V6EXP7NTJPMAYJYST2QP6AJXYW76IU6VGJS7UVSNDYZG4@boot.prod.status.nodes.status.im\", \
|
||||
\"dnsDiscoveryNameServers\": [\"8.8.8.8\", \"1.0.0.1\"] \
|
||||
}", cfgNode.host,
|
||||
cfgNode.port);
|
||||
}",
|
||||
cfgNode.host,
|
||||
cfgNode.port);
|
||||
|
||||
void* ctx =
|
||||
void *ctx =
|
||||
waku_new(jsonConfig,
|
||||
cify([](const char* msg, size_t len) {
|
||||
std::cout << "waku_new feedback: " << msg << std::endl;
|
||||
}
|
||||
),
|
||||
nullptr
|
||||
);
|
||||
cify([](const char *msg, size_t len)
|
||||
{ std::cout << "waku_new feedback: " << msg << std::endl; }),
|
||||
nullptr);
|
||||
waitForCallback();
|
||||
|
||||
// example on how to retrieve a value from the `libwaku` callback.
|
||||
std::string defaultPubsubTopic;
|
||||
WAKU_CALL(
|
||||
waku_default_pubsub_topic(
|
||||
ctx,
|
||||
cify([&defaultPubsubTopic](const char* msg, size_t len) {
|
||||
defaultPubsubTopic = msg;
|
||||
}
|
||||
),
|
||||
nullptr));
|
||||
ctx,
|
||||
cify([&defaultPubsubTopic](const char *msg, size_t len)
|
||||
{ defaultPubsubTopic = msg; }),
|
||||
nullptr));
|
||||
|
||||
std::cout << "Default pubsub topic: " << defaultPubsubTopic << std::endl;
|
||||
|
||||
WAKU_CALL(waku_version(ctx,
|
||||
cify([&](const char* msg, size_t len) {
|
||||
std::cout << "Git Version: " << msg << std::endl;
|
||||
}),
|
||||
WAKU_CALL(waku_version(ctx,
|
||||
cify([&](const char *msg, size_t len)
|
||||
{ std::cout << "Git Version: " << msg << std::endl; }),
|
||||
nullptr));
|
||||
|
||||
printf("Bind addr: %s:%u\n", cfgNode.host, cfgNode.port);
|
||||
printf("Waku Relay enabled: %s\n", cfgNode.relay == 1 ? "YES": "NO");
|
||||
printf("Waku Relay enabled: %s\n", cfgNode.relay == 1 ? "YES" : "NO");
|
||||
|
||||
std::string pubsubTopic;
|
||||
WAKU_CALL(waku_pubsub_topic(ctx,
|
||||
"example",
|
||||
cify([&](const char* msg, size_t len) {
|
||||
pubsubTopic = msg;
|
||||
}),
|
||||
nullptr));
|
||||
WAKU_CALL(waku_pubsub_topic(ctx,
|
||||
cify([&](const char *msg, size_t len)
|
||||
{ pubsubTopic = msg; }),
|
||||
nullptr,
|
||||
"example"));
|
||||
|
||||
std::cout << "Custom pubsub topic: " << pubsubTopic << std::endl;
|
||||
|
||||
waku_set_event_callback(ctx,
|
||||
cify([&](const char* msg, size_t len) {
|
||||
event_handler(msg, len);
|
||||
}),
|
||||
nullptr);
|
||||
set_event_callback(ctx,
|
||||
cify([&](const char *msg, size_t len)
|
||||
{ event_handler(msg, len); }),
|
||||
nullptr);
|
||||
|
||||
WAKU_CALL( waku_start(ctx,
|
||||
cify([&](const char* msg, size_t len) {
|
||||
event_handler(msg, len);
|
||||
}),
|
||||
nullptr));
|
||||
WAKU_CALL(waku_start(ctx,
|
||||
cify([&](const char *msg, size_t len)
|
||||
{ event_handler(msg, len); }),
|
||||
nullptr));
|
||||
|
||||
WAKU_CALL( waku_relay_subscribe(ctx,
|
||||
defaultPubsubTopic.c_str(),
|
||||
cify([&](const char* msg, size_t len) {
|
||||
event_handler(msg, len);
|
||||
}),
|
||||
nullptr) );
|
||||
WAKU_CALL(waku_relay_subscribe(ctx,
|
||||
cify([&](const char *msg, size_t len)
|
||||
{ event_handler(msg, len); }),
|
||||
nullptr,
|
||||
defaultPubsubTopic.c_str()));
|
||||
|
||||
show_main_menu();
|
||||
while(1) {
|
||||
while (1)
|
||||
{
|
||||
handle_user_input(ctx);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user