Commit fcc254d1 authored by Léo-Paul Géneau's avatar Léo-Paul Géneau 👾

Redirect pubsub logs for subscriber

parent bf812553
...@@ -89,4 +89,7 @@ VariableStruct subscriberVariables = { ...@@ -89,4 +89,7 @@ VariableStruct subscriberVariables = {
.variableArray = subscriberVariableArray, .variableArray = subscriberVariableArray,
}; };
void Subscriber_log(void *context, UA_LogLevel level, UA_LogCategory category,
const char *msg, va_list args);
#endif /* __DRONEDGE_H__ */ #endif /* __DRONEDGE_H__ */
...@@ -59,7 +59,7 @@ typedef struct { ...@@ -59,7 +59,7 @@ typedef struct {
void (*init_node_id)(UA_UInt32 id, UA_UInt32 nb, UA_UInt32 magic); void (*init_node_id)(UA_UInt32 id, UA_UInt32 nb, UA_UInt32 magic);
} InstanceData; } InstanceData;
int runPubsub(UA_String *transportProfile, int runPubsub(const UA_Logger *logger, UA_String *transportProfile,
UA_NetworkAddressUrlDataType *networkAddressUrl, UA_NetworkAddressUrlDataType *networkAddressUrl,
VariableStruct variables, UA_UInt32 id, VariableStruct variables, UA_UInt32 id,
InstanceData *readerArray, UA_UInt32 nbReader, InstanceData *readerArray, UA_UInt32 nbReader,
......
...@@ -11,6 +11,8 @@ UA_NodeId connectionIdent, publishedDataSetIdent, writerGroupIdent, ...@@ -11,6 +11,8 @@ UA_NodeId connectionIdent, publishedDataSetIdent, writerGroupIdent,
UA_DataSetReaderConfig readerConfig; UA_DataSetReaderConfig readerConfig;
const UA_Logger *pubsubLogger;
VariableData (*pubsubGetValue)(UA_String identifier); VariableData (*pubsubGetValue)(UA_String identifier);
static void (*callbackUpdate)(UA_UInt32, const UA_DataValue*, bool print); static void (*callbackUpdate)(UA_UInt32, const UA_DataValue*, bool print);
...@@ -90,7 +92,7 @@ readVariable(UA_Server *server, ...@@ -90,7 +92,7 @@ readVariable(UA_Server *server,
} }
if(retval != UA_STATUSCODE_GOOD) if(retval != UA_STATUSCODE_GOOD)
UA_LOG_ERROR(UA_Log_Stdout, UA_LOGCATEGORY_USERLAND, "read returned value %d", retval); UA_LOG_ERROR(pubsubLogger, UA_LOGCATEGORY_USERLAND, "read returned value %d", retval);
dataValue->hasValue = true; dataValue->hasValue = true;
return retval; return retval;
} }
...@@ -100,7 +102,7 @@ writeVariable(UA_Server *server, ...@@ -100,7 +102,7 @@ writeVariable(UA_Server *server,
const UA_NodeId *sessionId, void *sessionContext, const UA_NodeId *sessionId, void *sessionContext,
const UA_NodeId *nodeId, void *nodeContext, const UA_NodeId *nodeId, void *nodeContext,
const UA_NumericRange *range, const UA_DataValue *data) { const UA_NumericRange *range, const UA_DataValue *data) {
UA_LOG_INFO(UA_Log_Stdout, UA_LOGCATEGORY_USERLAND, UA_LOG_INFO(pubsubLogger, UA_LOGCATEGORY_USERLAND,
"Updating variables manually is not implemented"); "Updating variables manually is not implemented");
return UA_STATUSCODE_BADINTERNALERROR; return UA_STATUSCODE_BADINTERNALERROR;
} }
...@@ -360,7 +362,7 @@ static void fillDataSetMetaData(UA_DataSetMetaDataType *pMetaData, ...@@ -360,7 +362,7 @@ static void fillDataSetMetaData(UA_DataSetMetaDataType *pMetaData,
/* Definition of number of fields sizeto create different /* Definition of number of fields sizeto create different
* targetVariables of distinct datatype */ * targetVariables of distinct datatype */
pMetaData->fieldsSize = variables.nbVariable; pMetaData->fieldsSize = variables.nbVariable;
UA_LOG_INFO(UA_Log_Stdout, UA_LOGCATEGORY_USERLAND, "fieldsSize %d", (int) pMetaData->fieldsSize); UA_LOG_INFO(pubsubLogger, UA_LOGCATEGORY_USERLAND, "fieldsSize %d", (int) pMetaData->fieldsSize);
pMetaData->fields = (UA_FieldMetaData*)UA_Array_new (pMetaData->fieldsSize, pMetaData->fields = (UA_FieldMetaData*)UA_Array_new (pMetaData->fieldsSize,
&UA_TYPES[UA_TYPES_FIELDMETADATA]); &UA_TYPES[UA_TYPES_FIELDMETADATA]);
...@@ -406,7 +408,7 @@ setVariableType(UA_Server *server, VariableStruct variables) { ...@@ -406,7 +408,7 @@ setVariableType(UA_Server *server, VariableStruct variables) {
break; break;
default: default:
UA_LOG_ERROR(UA_Log_Stdout, UA_LOGCATEGORY_USERLAND, "Valuerank not handled"); UA_LOG_ERROR(pubsubLogger, UA_LOGCATEGORY_USERLAND, "Valuerank not handled");
break; break;
} }
} }
...@@ -470,7 +472,7 @@ subscribe(UA_Server *server, InstanceData *instanceArray, UA_UInt32 id, ...@@ -470,7 +472,7 @@ subscribe(UA_Server *server, InstanceData *instanceArray, UA_UInt32 id,
return retval; return retval;
} }
int runPubsub(UA_String *transportProfile, int runPubsub(const UA_Logger *logger, UA_String *transportProfile,
UA_NetworkAddressUrlDataType *networkAddressUrl, UA_NetworkAddressUrlDataType *networkAddressUrl,
VariableStruct variables, UA_UInt32 id, VariableStruct variables, UA_UInt32 id,
InstanceData *readerArray, UA_UInt32 nbReader, InstanceData *readerArray, UA_UInt32 nbReader,
...@@ -481,6 +483,7 @@ int runPubsub(UA_String *transportProfile, ...@@ -481,6 +483,7 @@ int runPubsub(UA_String *transportProfile,
UA_Boolean *running) { UA_Boolean *running) {
UA_Server *server; UA_Server *server;
UA_StatusCode retval; UA_StatusCode retval;
pubsubLogger = logger;
server = setServer(transportProfile, networkAddressUrl, id); server = setServer(transportProfile, networkAddressUrl, id);
setVariableType(server, variables); setVariableType(server, variables);
......
#include <pthread.h> #include <pthread.h>
#include "dronedge.h" #include "dronedge.h"
# define ANSI_COLOR_RED "\x1b[31m"
# define ANSI_COLOR_GREEN "\x1b[32m"
# define ANSI_COLOR_YELLOW "\x1b[33m"
# define ANSI_COLOR_BLUE "\x1b[34m"
# define ANSI_COLOR_MAGENTA "\x1b[35m"
# define ANSI_COLOR_CYAN "\x1b[36m"
# define ANSI_COLOR_RESET "\x1b[0m"
static JSClassID jsDroneClassId; static JSClassID jsDroneClassId;
static UA_Boolean pubsubShouldRun = true; static UA_Boolean pubsubShouldRun = true;
...@@ -9,15 +17,31 @@ static UA_Boolean pubsubExited = false; ...@@ -9,15 +17,31 @@ static UA_Boolean pubsubExited = false;
static UA_UInt32 nbDrone; static UA_UInt32 nbDrone;
static UA_UInt32 nbSubscriber; static UA_UInt32 nbSubscriber;
static JSValueConst *droneObjectIdList; static JSValueConst *droneObjectIdList;
static MessageQueue logQueue = {
.head = NULL,
.tail = NULL,
};
static MessageQueue messageQueue = { static MessageQueue messageQueue = {
.head = NULL, .head = NULL,
.tail = NULL, .tail = NULL,
}; };
UA_String currentMessage; UA_String currentMessage;
const UA_Logger Subscriber_Log = {Subscriber_log, NULL, UA_Log_Stdout_clear};
const UA_Logger *logger;
pthread_mutex_t mutex; pthread_mutex_t mutex;
pthread_cond_t threadCond; pthread_cond_t threadCond;
const char *logLevelNames[6] = {"trace", "debug",
ANSI_COLOR_GREEN "info",
ANSI_COLOR_YELLOW "warn",
ANSI_COLOR_RED "error",
ANSI_COLOR_MAGENTA "fatal"};
const char *logCategoryNames[10] =
{"network", "channel", "session", "server", "client",
"userland", "securitypolicy", "eventloop", "pubsub", "discovery"};
// Drone class functions // Drone class functions
static void js_drone_finalizer(JSRuntime *rt, JSValue val) static void js_drone_finalizer(JSRuntime *rt, JSValue val)
...@@ -104,29 +128,32 @@ static JSValue js_drone_get(JSContext *ctx, JSValueConst thisVal, int magic) ...@@ -104,29 +128,32 @@ static JSValue js_drone_get(JSContext *ctx, JSValueConst thisVal, int magic)
} }
} }
static void addMessageToQueue(const char* msg, MessageQueue* pQueue)
{
struct messageNode *newNode;
newNode = (struct messageNode*)malloc(sizeof(struct messageNode));
newNode->message = strdup(msg);
newNode->next = NULL;
if (pQueue->tail == NULL) {
pQueue->head = pQueue->tail = newNode;
} else {
pQueue->tail->next = newNode;
pQueue->tail = newNode;
}
}
static JSValue js_drone_set_message(JSContext *ctx, JSValueConst thisVal, static JSValue js_drone_set_message(JSContext *ctx, JSValueConst thisVal,
int argc, JSValueConst *argv) int argc, JSValueConst *argv)
{ {
struct messageNode *newNode;
const char *message; const char *message;
message = JS_ToCString(ctx, argv[0]); message = JS_ToCString(ctx, argv[0]);
if (strlen(message) > MAX_MESSAGE_SIZE) { if (strlen(message) > MAX_MESSAGE_SIZE) {
UA_LOG_ERROR(UA_Log_Stdout, UA_LOGCATEGORY_SERVER, "Message too long"); UA_LOG_ERROR(logger, UA_LOGCATEGORY_SERVER, "Message too long");
return JS_EXCEPTION; return JS_EXCEPTION;
} }
newNode = (struct messageNode*)malloc(sizeof(struct messageNode)); addMessageToQueue(message, &messageQueue);
newNode->message = strdup(message);
newNode->next = NULL;
if (messageQueue.tail == NULL) {
messageQueue.head = messageQueue.tail = newNode;
} else {
messageQueue.tail->next = newNode;
messageQueue.tail = newNode;
}
JS_FreeCString(ctx, message); JS_FreeCString(ctx, message);
return JS_UNDEFINED; return JS_UNDEFINED;
} }
...@@ -200,7 +227,7 @@ VariableData pubsub_get_value(UA_String identifier) { ...@@ -200,7 +227,7 @@ VariableData pubsub_get_value(UA_String identifier) {
*(UA_String*)varDetails.value = varDetails.getter.getString(); *(UA_String*)varDetails.value = varDetails.getter.getString();
break; break;
default: default:
UA_LOG_ERROR(UA_Log_Stdout, UA_LOGCATEGORY_SERVER, "UA_TYPE not handled"); UA_LOG_ERROR(logger, UA_LOGCATEGORY_SERVER, "UA_TYPE not handled");
break; break;
} }
break; break;
...@@ -222,14 +249,14 @@ VariableData pubsub_get_value(UA_String identifier) { ...@@ -222,14 +249,14 @@ VariableData pubsub_get_value(UA_String identifier) {
ptrd += type.memSize; ptrd += type.memSize;
} }
if(retval != UA_STATUSCODE_GOOD) if(retval != UA_STATUSCODE_GOOD)
UA_LOG_ERROR(UA_Log_Stdout, UA_LOGCATEGORY_SERVER, "Failed to update array"); UA_LOG_ERROR(logger, UA_LOGCATEGORY_SERVER, "Failed to update array");
} }
free(array); free(array);
break; break;
default: default:
UA_LOG_ERROR(UA_Log_Stdout, UA_LOGCATEGORY_SERVER, "UA_VALUERANK not handled"); UA_LOG_ERROR(logger, UA_LOGCATEGORY_SERVER, "UA_VALUERANK not handled");
break; break;
} }
} }
...@@ -251,7 +278,7 @@ void init_drone_node_id(UA_UInt32 id, UA_UInt32 nb, UA_UInt32 magic) { ...@@ -251,7 +278,7 @@ void init_drone_node_id(UA_UInt32 id, UA_UInt32 nb, UA_UInt32 magic) {
s->messageId = id; s->messageId = id;
break; break;
default: default:
UA_LOG_ERROR(UA_Log_Stdout, UA_LOGCATEGORY_USERLAND, "Unknown variable id"); UA_LOG_ERROR(logger, UA_LOGCATEGORY_USERLAND, "Unknown variable id");
break; break;
} }
} }
...@@ -263,7 +290,7 @@ void init_subscriber_node_id(UA_UInt32 id, UA_UInt32 nb, UA_UInt32 magic) { ...@@ -263,7 +290,7 @@ void init_subscriber_node_id(UA_UInt32 id, UA_UInt32 nb, UA_UInt32 magic) {
s->messageId = id; s->messageId = id;
break; break;
default: default:
UA_LOG_ERROR(UA_Log_Stdout, UA_LOGCATEGORY_USERLAND, "Unknown variable id"); UA_LOG_ERROR(logger, UA_LOGCATEGORY_USERLAND, "Unknown variable id");
break; break;
} }
} }
...@@ -285,8 +312,8 @@ static void pubsub_update_variables(UA_UInt32 id, const UA_DataValue *var, bool ...@@ -285,8 +312,8 @@ static void pubsub_update_variables(UA_UInt32 id, const UA_DataValue *var, bool
s->altitudeRel = positionArray[3]; s->altitudeRel = positionArray[3];
if (print) { if (print) {
UA_LOG_INFO(UA_Log_Stdout, UA_LOGCATEGORY_CLIENT, UA_LOG_INFO(logger, UA_LOGCATEGORY_CLIENT,
"Received position of drone %d: %f° %f° %fm %fm", "Received position of drone %d: %.6f ° %.6f ° %.2f m %.2f m",
s->id, s->latitude, s->longitude, s->altitudeAbs, s->altitudeRel); s->id, s->latitude, s->longitude, s->altitudeAbs, s->altitudeRel);
} }
return; return;
...@@ -297,14 +324,13 @@ static void pubsub_update_variables(UA_UInt32 id, const UA_DataValue *var, bool ...@@ -297,14 +324,13 @@ static void pubsub_update_variables(UA_UInt32 id, const UA_DataValue *var, bool
s->climbRate = speedArray[2]; s->climbRate = speedArray[2];
if (print) { if (print) {
UA_LOG_INFO(UA_Log_Stdout, UA_LOGCATEGORY_CLIENT, UA_LOG_INFO(logger, UA_LOGCATEGORY_CLIENT,
"Received speed of drone %d: %f° %fm/s %fm/s", "Received speed of drone %d: %.2f ° %.2f m/s %.2f m/s",
s->id, s->yaw, s->speed, s->climbRate); s->id, s->yaw, s->speed, s->climbRate);
} }
return; return;
} else if (s->messageId == id) { } else if (s->messageId == id) {
uaStr = *(UA_String*) var->value.data; uaStr = *(UA_String*) var->value.data;
pthread_mutex_lock(&mutex); pthread_mutex_lock(&mutex);
while(strlen(s->message) != 0) while(strlen(s->message) != 0)
pthread_cond_wait(&threadCond, &mutex); pthread_cond_wait(&threadCond, &mutex);
...@@ -316,7 +342,52 @@ static void pubsub_update_variables(UA_UInt32 id, const UA_DataValue *var, bool ...@@ -316,7 +342,52 @@ static void pubsub_update_variables(UA_UInt32 id, const UA_DataValue *var, bool
return; return;
} }
} }
UA_LOG_ERROR(UA_Log_Stdout, UA_LOGCATEGORY_CLIENT, "NodeId not found"); UA_LOG_ERROR(logger, UA_LOGCATEGORY_CLIENT, "NodeId not found");
}
void Subscriber_log(void *context, UA_LogLevel level, UA_LogCategory category,
const char *msg, va_list args) {
char log_str[MAX_MESSAGE_SIZE];
char formatted_msg[MAX_MESSAGE_SIZE];
/* MinLevel encoded in the context pointer */
UA_LogLevel minLevel = (UA_LogLevel)(uintptr_t)context;
if(minLevel > level)
return;
UA_Int64 tOffset = UA_DateTime_localTimeUtcOffset();
UA_DateTimeStruct dts = UA_DateTime_toStruct(UA_DateTime_now() + tOffset);
int logLevelSlot = (int)level;
if(logLevelSlot < 0 || logLevelSlot > 5)
logLevelSlot = 5; /* Set to fatal if the level is outside the range */
/* Log */
snprintf(log_str, MAX_MESSAGE_SIZE,
"[%04u-%02u-%02u %02u:%02u:%02u.%03u (UTC%+05d)] %s/%s" ANSI_COLOR_RESET "\t",
dts.year, dts.month, dts.day, dts.hour, dts.min, dts.sec, dts.milliSec,
(int)(tOffset / UA_DATETIME_SEC / 36), logLevelNames[logLevelSlot],
logCategoryNames[category]);
vsnprintf(formatted_msg, MAX_MESSAGE_SIZE, msg, args);
strncat(log_str, formatted_msg, MAX_MESSAGE_SIZE - strlen(log_str) - 1);
strcat(log_str, "\n");
addMessageToQueue(log_str, &logQueue);
}
static JSValue js_get_log(JSContext *ctx, JSValueConst this_val,
int argc, JSValueConst *argv) {
JSValue res;
struct messageNode *current;
current = logQueue.head;
if (current != NULL) {
res = JS_NewString(ctx, current->message);
logQueue.head = current->next == NULL ? (logQueue.tail = NULL) : current->next;
delete_message_node(current);
} else {
res = JS_NewString(ctx, "");
}
return res;
} }
/* /*
...@@ -328,8 +399,7 @@ static void pubsub_update_variables(UA_UInt32 id, const UA_DataValue *var, bool ...@@ -328,8 +399,7 @@ static void pubsub_update_variables(UA_UInt32 id, const UA_DataValue *var, bool
* arg 5 (bool): true if there will be data to publish * arg 5 (bool): true if there will be data to publish
*/ */
static JSValue js_run_pubsub(JSContext *ctx, JSValueConst this_val, static JSValue js_run_pubsub(JSContext *ctx, JSValueConst this_val,
int argc, JSValueConst *argv) int argc, JSValueConst *argv) {
{
const char *ipv6; const char *ipv6;
const char *port; const char *port;
const char *netIface; const char *netIface;
...@@ -364,6 +434,7 @@ static JSValue js_run_pubsub(JSContext *ctx, JSValueConst this_val, ...@@ -364,6 +434,7 @@ static JSValue js_run_pubsub(JSContext *ctx, JSValueConst this_val,
isADrone = JS_ToBool(ctx, argv[5]); isADrone = JS_ToBool(ctx, argv[5]);
variables = isADrone ? droneVariables : subscriberVariables; variables = isADrone ? droneVariables : subscriberVariables;
logger = isADrone ? UA_Log_Stdout : &Subscriber_Log;
instanceArray = (InstanceData *) malloc((nbPeer) * sizeof(InstanceData)); instanceArray = (InstanceData *) malloc((nbPeer) * sizeof(InstanceData));
for(UA_UInt32 i = 0; i < nbDrone; i++) { for(UA_UInt32 i = 0; i < nbDrone; i++) {
...@@ -375,8 +446,8 @@ static JSValue js_run_pubsub(JSContext *ctx, JSValueConst this_val, ...@@ -375,8 +446,8 @@ static JSValue js_run_pubsub(JSContext *ctx, JSValueConst this_val,
instanceArray[i].init_node_id = init_subscriber_node_id; instanceArray[i].init_node_id = init_subscriber_node_id;
} }
res = runPubsub(&transportProfile, &networkAddressUrl, variables, id, res = runPubsub(logger, &transportProfile, &networkAddressUrl, variables,
instanceArray, nbPeer, MAX_VARIABLE_NB, interval, id, instanceArray, nbPeer, MAX_VARIABLE_NB, interval,
get_drone_id, pubsub_get_value, pubsub_update_variables, get_drone_id, pubsub_get_value, pubsub_update_variables,
&pubsubShouldRun); &pubsubShouldRun);
pubsubExited = true; pubsubExited = true;
...@@ -420,6 +491,12 @@ static JSValue js_stop_pubsub(JSContext *ctx, JSValueConst thisVal, ...@@ -420,6 +491,12 @@ static JSValue js_stop_pubsub(JSContext *ctx, JSValueConst thisVal,
} }
clear_message(currentMessage); clear_message(currentMessage);
while(logQueue.head != NULL) {
current = logQueue.head;
logQueue.head = current->next;
delete_message_node(current);
}
return JS_NewInt32(ctx, 0); return JS_NewInt32(ctx, 0);
} }
...@@ -645,6 +722,7 @@ static const JSCFunctionListEntry js_funcs[] = { ...@@ -645,6 +722,7 @@ static const JSCFunctionListEntry js_funcs[] = {
JS_CFUNC_DEF("getClimbRate", 0, js_getClimbRate ), JS_CFUNC_DEF("getClimbRate", 0, js_getClimbRate ),
JS_CFUNC_DEF("healthAllOk", 0, js_healthAllOk ), JS_CFUNC_DEF("healthAllOk", 0, js_healthAllOk ),
JS_CFUNC_DEF("initPubsub", 2, js_init_pubsub ), JS_CFUNC_DEF("initPubsub", 2, js_init_pubsub ),
JS_CFUNC_DEF("getLog", 0, js_get_log ),
}; };
static int js_init(JSContext *ctx, JSModuleDef *m) static int js_init(JSContext *ctx, JSModuleDef *m)
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment