NagyZoltanPeter 3603b838b9
feat: liblogosdelivery FFI library of new API (#3714)
* Initial for liblogosdelivery library (static & dynamic) based on current state of API. 
* nix build support added.
* logosdelivery_example
* Added support for missing logLevel/logFormat in new API create_node
* Added full JSON to NodeConfig support
* Added ctx and ctx.myLib check to avoid uninitialzed calls and crash. Adjusted logosdelivery_example with proper error handling and JSON config format
* target aware install phase
* Fix base64 decode of payload
2026-02-17 10:38:35 +01:00

194 lines
6.1 KiB
C
Raw Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

#include "../liblogosdelivery.h"
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <stdlib.h>
static int create_node_ok = -1;
// Helper function to extract a JSON string field value
// Very basic parser - for production use a proper JSON library
const char* extract_json_field(const char *json, const char *field, char *buffer, size_t bufSize) {
char searchStr[256];
snprintf(searchStr, sizeof(searchStr), "\"%s\":\"", field);
const char *start = strstr(json, searchStr);
if (!start) {
return NULL;
}
start += strlen(searchStr);
const char *end = strchr(start, '"');
if (!end) {
return NULL;
}
size_t len = end - start;
if (len >= bufSize) {
len = bufSize - 1;
}
memcpy(buffer, start, len);
buffer[len] = '\0';
return buffer;
}
// Event callback that handles message events
void event_callback(int ret, const char *msg, size_t len, void *userData) {
if (ret != RET_OK || msg == NULL || len == 0) {
return;
}
// Create null-terminated string for easier parsing
char *eventJson = malloc(len + 1);
if (!eventJson) {
return;
}
memcpy(eventJson, msg, len);
eventJson[len] = '\0';
// Extract eventType
char eventType[64];
if (!extract_json_field(eventJson, "eventType", eventType, sizeof(eventType))) {
free(eventJson);
return;
}
// Handle different event types
if (strcmp(eventType, "message_sent") == 0) {
char requestId[128];
char messageHash[128];
extract_json_field(eventJson, "requestId", requestId, sizeof(requestId));
extract_json_field(eventJson, "messageHash", messageHash, sizeof(messageHash));
printf("📤 [EVENT] Message sent - RequestID: %s, Hash: %s\n", requestId, messageHash);
} else if (strcmp(eventType, "message_error") == 0) {
char requestId[128];
char messageHash[128];
char error[256];
extract_json_field(eventJson, "requestId", requestId, sizeof(requestId));
extract_json_field(eventJson, "messageHash", messageHash, sizeof(messageHash));
extract_json_field(eventJson, "error", error, sizeof(error));
printf("❌ [EVENT] Message error - RequestID: %s, Hash: %s, Error: %s\n",
requestId, messageHash, error);
} else if (strcmp(eventType, "message_propagated") == 0) {
char requestId[128];
char messageHash[128];
extract_json_field(eventJson, "requestId", requestId, sizeof(requestId));
extract_json_field(eventJson, "messageHash", messageHash, sizeof(messageHash));
printf("✅ [EVENT] Message propagated - RequestID: %s, Hash: %s\n", requestId, messageHash);
} else {
printf(" [EVENT] Unknown event type: %s\n", eventType);
}
free(eventJson);
}
// Simple callback that prints results
void simple_callback(int ret, const char *msg, size_t len, void *userData) {
const char *operation = (const char *)userData;
if (operation != NULL && strcmp(operation, "create_node") == 0) {
create_node_ok = (ret == RET_OK) ? 1 : 0;
}
if (ret == RET_OK) {
if (len > 0) {
printf("[%s] Success: %.*s\n", operation, (int)len, msg);
} else {
printf("[%s] Success\n", operation);
}
} else {
printf("[%s] Error: %.*s\n", operation, (int)len, msg);
}
}
int main() {
printf("=== Logos Messaging API (LMAPI) Example ===\n\n");
// Configuration JSON for creating a node
const char *config = "{"
"\"logLevel\": \"DEBUG\","
// "\"mode\": \"Edge\","
"\"mode\": \"Core\","
"\"protocolsConfig\": {"
"\"entryNodes\": [\"/dns4/node-01.do-ams3.misc.logos-chat.status.im/tcp/30303/p2p/16Uiu2HAkxoqUTud5LUPQBRmkeL2xP4iKx2kaABYXomQRgmLUgf78\"],"
"\"clusterId\": 42,"
"\"autoShardingConfig\": {"
"\"numShardsInCluster\": 8"
"}"
"},"
"\"networkingConfig\": {"
"\"listenIpv4\": \"0.0.0.0\","
"\"p2pTcpPort\": 60000,"
"\"discv5UdpPort\": 9000"
"}"
"}";
printf("1. Creating node...\n");
void *ctx = logosdelivery_create_node(config, simple_callback, (void *)"create_node");
if (ctx == NULL) {
printf("Failed to create node\n");
return 1;
}
// Wait a bit for the callback
sleep(1);
if (create_node_ok != 1) {
printf("Create node failed, stopping example early.\n");
logosdelivery_destroy(ctx, simple_callback, (void *)"destroy");
return 1;
}
printf("\n2. Setting up event callback...\n");
logosdelivery_set_event_callback(ctx, event_callback, NULL);
printf("Event callback registered for message events\n");
printf("\n3. Starting node...\n");
logosdelivery_start_node(ctx, simple_callback, (void *)"start_node");
// Wait for node to start
sleep(2);
printf("\n4. Subscribing to content topic...\n");
const char *contentTopic = "/example/1/chat/proto";
logosdelivery_subscribe(ctx, simple_callback, (void *)"subscribe", contentTopic);
// Wait for subscription
sleep(1);
printf("\n5. Sending a message...\n");
printf("Watch for message events (sent, propagated, or error):\n");
// Create base64-encoded payload: "Hello, Logos Messaging!"
const char *message = "{"
"\"contentTopic\": \"/example/1/chat/proto\","
"\"payload\": \"SGVsbG8sIExvZ29zIE1lc3NhZ2luZyE=\","
"\"ephemeral\": false"
"}";
logosdelivery_send(ctx, simple_callback, (void *)"send", message);
// Wait for message events to arrive
printf("Waiting for message delivery events...\n");
sleep(60);
printf("\n6. Unsubscribing from content topic...\n");
logosdelivery_unsubscribe(ctx, simple_callback, (void *)"unsubscribe", contentTopic);
sleep(1);
printf("\n7. Stopping node...\n");
logosdelivery_stop_node(ctx, simple_callback, (void *)"stop_node");
sleep(1);
printf("\n8. Destroying context...\n");
logosdelivery_destroy(ctx, simple_callback, (void *)"destroy");
printf("\n=== Example completed ===\n");
return 0;
}