Untitled

 avatar
unknown
c_cpp
3 months ago
3.6 kB
16
Indexable
#include <string>
#include <atomic>
#include <vector>
#include <signal.h>
#include <syslog.h>
#include <glib.h>
#include <axsdk/axevent.h>

// Global variables
GMainLoop* g_main_loop = nullptr;
std::atomic<bool> shutdownRequested(false);
AXEventHandler* m_EventHandler = nullptr;
std::vector<guint> declaration_ids;  // Store declaration IDs

// Declaration complete callback
void declarationCompleteCallback(guint declaration, void* user_data) {
    syslog(LOG_INFO, "Declaration complete for event ID: %u", declaration);
}

void cleanup() {
    syslog(LOG_INFO, "Starting cleanup sequence");
    if (m_EventHandler) {
        // Undeclare all events
        for (guint declaration_id : declaration_ids) {
            ax_event_handler_undeclare(m_EventHandler, declaration_id, NULL);
            syslog(LOG_INFO, "Undeclared event ID: %u", declaration_id);
        }
        declaration_ids.clear();
        syslog(LOG_INFO, "Freeing event handler");
        ax_event_handler_free(m_EventHandler);
        m_EventHandler = nullptr;
    }
    syslog(LOG_INFO, "Events shutdown complete");
}

gboolean idleShutdown(gpointer data) {
    if (shutdownRequested.load()) {
        syslog(LOG_INFO, "Idle function initiating main loop quit");
        g_main_loop_quit(g_main_loop);
        return G_SOURCE_REMOVE;
    }
    return G_SOURCE_CONTINUE;
}

void signalHandler(int signum) {
    shutdownRequested.store(true);
}

void declareActionConfig(int conditionNo, const char* name) {
    AXEventKeyValueSet* key_value_set = ax_event_key_value_set_new();
    ax_event_key_value_set_add_key_values(
        key_value_set,
        NULL,
        "topic0",
        "tnsaxis",
        name,
        AX_VALUE_TYPE_STRING,
        NULL);

    guint declaration;
    GError* error = NULL;
    // Provide the declaration complete callback instead of NULL.
    if (!ax_event_handler_declare(m_EventHandler, key_value_set, false, &declaration,
                                    declarationCompleteCallback, NULL, &error)) {
        syslog(LOG_ERR, "Declaration failed: %s", error->message);
    } else {
        declaration_ids.push_back(declaration);  // Store the declaration ID
        syslog(LOG_INFO, "Declared event ID: %u", declaration);
    }

    ax_event_key_value_set_free(key_value_set);
}

void runApp() {
    syslog(LOG_INFO, "Service started");

    m_EventHandler = ax_event_handler_new();
    if (!m_EventHandler) {
        syslog(LOG_ERR, "Failed to create event handler");
        return;
    }

    // Declare 5 events
    for (int i = 0; i < 5; i++) {
        std::string name = "Event_" + std::to_string(i);
        declareActionConfig(i, name.c_str());
    }

    g_main_loop = g_main_loop_new(nullptr, FALSE);
    syslog(LOG_INFO, "App initialization completed");

    // Set up an idle function to check for shutdown
    g_idle_add(idleShutdown, nullptr);
    g_main_loop_run(g_main_loop);
}

int main(int argc, char *argv[]) {
    // Set up signal handling
    struct sigaction sigAct;
    sigAct.sa_handler = signalHandler;
    sigemptyset(&sigAct.sa_mask);
    sigAct.sa_flags = 0; // Do not set SA_RESTART

    sigaction(SIGINT, &sigAct, nullptr);
    sigaction(SIGTERM, &sigAct, nullptr);

    // Open syslog for logging
    openlog(NULL, LOG_PID, LOG_USER);
    runApp();
    cleanup();

    if (g_main_loop) {
        g_main_loop_unref(g_main_loop);
        g_main_loop = nullptr;
    }

    syslog(LOG_INFO, "Application shutdown complete");
    closelog();

    return 0;
}
Editor is loading...
Leave a Comment