1
0
mirror of https://github.com/Ylianst/MeshAgent synced 2025-12-15 07:43:50 +00:00
Files
MeshAgent/microscript/ILibDuktape_NetworkMonitor.c
2017-10-25 21:08:41 -07:00

147 lines
5.2 KiB
C

#include "duktape.h"
#include "ILibDuktapeModSearch.h"
#include "ILibDuktape_EventEmitter.h"
#include "ILibDuktape_Helpers.h"
#include "../microstack/ILibParsers.h"
#include "../microstack/ILibIPAddressMonitor.h"
#define ILibDuktape_NetworkMonitor_PTR "\xFF_ILibDuktape_NetworkMonitor"
typedef struct ILibDuktape_NetworkMonitor
{
duk_context *ctx;
ILibDuktape_EventEmitter *emitter;
ILibIPAddressMonitor addressMonitor;
ILibHashtable *addressTable;
void *OnChange;
void *OnAdded;
void *OnRemoved;
}ILibDuktape_NetworkMonitor;
ILibHashtable ILibDuktape_NetworkMonitor_CreateTable(duk_context *ctx)
{
int i;
duk_size_t bufferLen;
char *buffer;
ILibHashtable retVal = NULL;
if (duk_peval_string(ctx, "require('os').networkInterfaces();") != 0)
{
ILibDuktape_Process_UncaughtExceptionEx(ctx, "NetworkMonitor: ");
duk_pop(ctx);
}
else
{ // [networkInterfaces]
retVal = ILibHashtable_Create();
duk_enum(ctx, -1, DUK_ENUM_OWN_PROPERTIES_ONLY); // [networkInterfaces][enum]
while (duk_next(ctx, -1, 1))
{
// [networkInterfaces][enum][adapter][array]
int count = (int)duk_get_length(ctx, -1);
for (i = 0; i < count; ++i)
{
duk_get_prop_index(ctx, -1, i); // [networkInterfaces][enum][adapter][array][obj]
if (duk_has_prop_string(ctx, -1, "address") && strcmp(Duktape_GetStringPropertyValue(ctx, -1, "status", "up"), "up") == 0)
{
duk_get_prop_string(ctx, -1, "address");// [networkInterfaces][enum][adapter][array][obj][address]
buffer = (char*)duk_get_lstring(ctx, -1, &bufferLen);
ILibHashtable_Put(retVal, NULL, buffer, (int)bufferLen, (void*)0x01);
duk_pop(ctx); // [networkInterfaces][enum][adapter][array][obj]
}
duk_pop(ctx); // [networkInterfaces][enum][adapter][array]
}
duk_pop_2(ctx); // [networkInterfaces][enum]
}
duk_pop_2(ctx); // ...
}
return(retVal);
}
void ILibDuktape_NetworkMonitor_EventSink_OnEnumerateCurrent(ILibHashtable sender, void *Key1, char* Key2, int Key2Len, void *Data, void *user)
{
duk_context *ctx = (duk_context*)((void**)user)[0];
void *OnEvent = ((void**)user)[1];
void *Self = ((void**)user)[2];
ILibHashtable other = (ILibHashtable)((void**)user)[3];
if (ILibHashtable_Get(other, NULL, Key2, Key2Len) == NULL)
{
if (OnEvent != NULL)
{
duk_push_heapptr(ctx, OnEvent); // [func]
duk_push_heapptr(ctx, Self); // [func][this]
duk_push_lstring(ctx, Key2, (duk_size_t)Key2Len); // [func][this][address]
if (duk_pcall_method(ctx, 1) != 0) { ILibDuktape_Process_UncaughtExceptionEx(ctx, "NetworkMonitor.OnAdd/Remove(): "); }
duk_pop(ctx);
}
}
}
void ILibDuktape_NetworkMonitor_EventSink(ILibIPAddressMonitor sender, void *user)
{
ILibDuktape_NetworkMonitor *nm = (ILibDuktape_NetworkMonitor*)user;
if (nm->OnChange != NULL)
{
duk_push_heapptr(nm->ctx, nm->OnChange); // [func]
duk_push_heapptr(nm->ctx, nm->emitter->object); // [func][this]
if (duk_pcall_method(nm->ctx, 0) != 0) { ILibDuktape_Process_UncaughtExceptionEx(nm->ctx, "NetworkMonitor.change(): "); }
duk_pop(nm->ctx); // ...
}
ILibHashtable current = ILibDuktape_NetworkMonitor_CreateTable(nm->ctx);
if (nm->OnAdded != NULL)
{
void *data[] = { nm->ctx, nm->OnAdded, nm->emitter->object, nm->addressTable };
ILibHashtable_Enumerate(current, ILibDuktape_NetworkMonitor_EventSink_OnEnumerateCurrent, data);
}
if(nm->OnRemoved != NULL)
{
void *data[] = { nm->ctx, nm->OnRemoved, nm->emitter->object, current };
ILibHashtable_Enumerate(nm->addressTable, ILibDuktape_NetworkMonitor_EventSink_OnEnumerateCurrent, data);
}
ILibHashtable_Destroy(nm->addressTable);
nm->addressTable = current;
}
duk_ret_t ILibDuktape_NetworkMonitor_Finalizer(duk_context *ctx)
{
if (ILibIsChainBeingDestroyed(Duktape_GetChain(ctx)) != 0) { return(0); }
duk_get_prop_string(ctx, 0, ILibDuktape_NetworkMonitor_PTR);
ILibDuktape_NetworkMonitor *nm = (ILibDuktape_NetworkMonitor*)Duktape_GetBuffer(ctx, -1, NULL);
ILibChain_SafeRemoveEx(Duktape_GetChain(ctx), nm->addressMonitor);
if (nm->addressTable != NULL) { ILibHashtable_Destroy(nm->addressTable); }
return(0);
}
void ILibDuktape_NetworkMonitor_PUSH(duk_context *ctx, void *chain)
{
duk_push_object(ctx);
duk_push_fixed_buffer(ctx, sizeof(ILibDuktape_NetworkMonitor));
ILibDuktape_NetworkMonitor *nm = (ILibDuktape_NetworkMonitor*)Duktape_GetBuffer(ctx, -1, NULL);
memset(nm, 0, sizeof(ILibDuktape_NetworkMonitor));
duk_put_prop_string(ctx, -2, ILibDuktape_NetworkMonitor_PTR);
nm->ctx = ctx;
nm->emitter = ILibDuktape_EventEmitter_Create(ctx);
nm->addressMonitor = ILibIPAddressMonitor_Create(chain, ILibDuktape_NetworkMonitor_EventSink, nm);
ILibDuktape_EventEmitter_CreateEvent(nm->emitter, "change", &(nm->OnChange));
ILibDuktape_EventEmitter_CreateEvent(nm->emitter, "add", &(nm->OnAdded));
ILibDuktape_EventEmitter_CreateEvent(nm->emitter, "remove", &(nm->OnRemoved));
ILibDuktape_CreateFinalizer(ctx, ILibDuktape_NetworkMonitor_Finalizer);
//
// Get initial list of addresses
//
nm->addressTable = ILibDuktape_NetworkMonitor_CreateTable(ctx);
}
void ILibDuktape_NetworkMonitor_Init(duk_context *ctx)
{
ILibDuktape_ModSearch_AddHandler(ctx, "NetworkMonitor", ILibDuktape_NetworkMonitor_PUSH);
}