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 = {
.variableArray = subscriberVariableArray,
};
void Subscriber_log(void *context, UA_LogLevel level, UA_LogCategory category,
const char *msg, va_list args);
#endif /* __DRONEDGE_H__ */
......@@ -59,7 +59,7 @@ typedef struct {
void (*init_node_id)(UA_UInt32 id, UA_UInt32 nb, UA_UInt32 magic);
} InstanceData;
int runPubsub(UA_String *transportProfile,
int runPubsub(const UA_Logger *logger, UA_String *transportProfile,
UA_NetworkAddressUrlDataType *networkAddressUrl,
VariableStruct variables, UA_UInt32 id,
InstanceData *readerArray, UA_UInt32 nbReader,
......
......@@ -11,6 +11,8 @@ UA_NodeId connectionIdent, publishedDataSetIdent, writerGroupIdent,
UA_DataSetReaderConfig readerConfig;
const UA_Logger *pubsubLogger;
VariableData (*pubsubGetValue)(UA_String identifier);
static void (*callbackUpdate)(UA_UInt32, const UA_DataValue*, bool print);
......@@ -90,7 +92,7 @@ readVariable(UA_Server *server,
}
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;
return retval;
}
......@@ -100,7 +102,7 @@ writeVariable(UA_Server *server,
const UA_NodeId *sessionId, void *sessionContext,
const UA_NodeId *nodeId, void *nodeContext,
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");
return UA_STATUSCODE_BADINTERNALERROR;
}
......@@ -360,7 +362,7 @@ static void fillDataSetMetaData(UA_DataSetMetaDataType *pMetaData,
/* Definition of number of fields sizeto create different
* targetVariables of distinct datatype */
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,
&UA_TYPES[UA_TYPES_FIELDMETADATA]);
......@@ -406,7 +408,7 @@ setVariableType(UA_Server *server, VariableStruct variables) {
break;
default:
UA_LOG_ERROR(UA_Log_Stdout, UA_LOGCATEGORY_USERLAND, "Valuerank not handled");
UA_LOG_ERROR(pubsubLogger, UA_LOGCATEGORY_USERLAND, "Valuerank not handled");
break;
}
}
......@@ -470,7 +472,7 @@ subscribe(UA_Server *server, InstanceData *instanceArray, UA_UInt32 id,
return retval;
}
int runPubsub(UA_String *transportProfile,
int runPubsub(const UA_Logger *logger, UA_String *transportProfile,
UA_NetworkAddressUrlDataType *networkAddressUrl,
VariableStruct variables, UA_UInt32 id,
InstanceData *readerArray, UA_UInt32 nbReader,
......@@ -481,6 +483,7 @@ int runPubsub(UA_String *transportProfile,
UA_Boolean *running) {
UA_Server *server;
UA_StatusCode retval;
pubsubLogger = logger;
server = setServer(transportProfile, networkAddressUrl, id);
setVariableType(server, variables);
......
#include <pthread.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 UA_Boolean pubsubShouldRun = true;
......@@ -9,15 +17,31 @@ static UA_Boolean pubsubExited = false;
static UA_UInt32 nbDrone;
static UA_UInt32 nbSubscriber;
static JSValueConst *droneObjectIdList;
static MessageQueue logQueue = {
.head = NULL,
.tail = NULL,
};
static MessageQueue messageQueue = {
.head = NULL,
.tail = NULL,
};
UA_String currentMessage;
const UA_Logger Subscriber_Log = {Subscriber_log, NULL, UA_Log_Stdout_clear};
const UA_Logger *logger;
pthread_mutex_t mutex;
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
static void js_drone_finalizer(JSRuntime *rt, JSValue val)
......@@ -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,
int argc, JSValueConst *argv)
{
struct messageNode *newNode;
const char *message;
message = JS_ToCString(ctx, argv[0]);
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;
}
newNode = (struct messageNode*)malloc(sizeof(struct messageNode));
newNode->message = strdup(message);
newNode->next = NULL;
if (messageQueue.tail == NULL) {
messageQueue.head = messageQueue.tail = newNode;
} else {
messageQueue.tail->next = newNode;
messageQueue.tail = newNode;
}
addMessageToQueue(message, &messageQueue);
JS_FreeCString(ctx, message);
return JS_UNDEFINED;
}
......@@ -200,7 +227,7 @@ VariableData pubsub_get_value(UA_String identifier) {
*(UA_String*)varDetails.value = varDetails.getter.getString();
break;
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;
......@@ -222,14 +249,14 @@ VariableData pubsub_get_value(UA_String identifier) {
ptrd += type.memSize;
}
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);
break;
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;
}
}
......@@ -251,7 +278,7 @@ void init_drone_node_id(UA_UInt32 id, UA_UInt32 nb, UA_UInt32 magic) {
s->messageId = id;
break;
default:
UA_LOG_ERROR(UA_Log_Stdout, UA_LOGCATEGORY_USERLAND, "Unknown variable id");
UA_LOG_ERROR(logger, UA_LOGCATEGORY_USERLAND, "Unknown variable id");
break;
}
}
......@@ -263,7 +290,7 @@ void init_subscriber_node_id(UA_UInt32 id, UA_UInt32 nb, UA_UInt32 magic) {
s->messageId = id;
break;
default:
UA_LOG_ERROR(UA_Log_Stdout, UA_LOGCATEGORY_USERLAND, "Unknown variable id");
UA_LOG_ERROR(logger, UA_LOGCATEGORY_USERLAND, "Unknown variable id");
break;
}
}
......@@ -285,8 +312,8 @@ static void pubsub_update_variables(UA_UInt32 id, const UA_DataValue *var, bool
s->altitudeRel = positionArray[3];
if (print) {
UA_LOG_INFO(UA_Log_Stdout, UA_LOGCATEGORY_CLIENT,
"Received position of drone %d: %f° %f° %fm %fm",
UA_LOG_INFO(logger, UA_LOGCATEGORY_CLIENT,
"Received position of drone %d: %.6f ° %.6f ° %.2f m %.2f m",
s->id, s->latitude, s->longitude, s->altitudeAbs, s->altitudeRel);
}
return;
......@@ -297,14 +324,13 @@ static void pubsub_update_variables(UA_UInt32 id, const UA_DataValue *var, bool
s->climbRate = speedArray[2];
if (print) {
UA_LOG_INFO(UA_Log_Stdout, UA_LOGCATEGORY_CLIENT,
"Received speed of drone %d: %f° %fm/s %fm/s",
UA_LOG_INFO(logger, UA_LOGCATEGORY_CLIENT,
"Received speed of drone %d: %.2f ° %.2f m/s %.2f m/s",
s->id, s->yaw, s->speed, s->climbRate);
}
return;
} else if (s->messageId == id) {
uaStr = *(UA_String*) var->value.data;
pthread_mutex_lock(&mutex);
while(strlen(s->message) != 0)
pthread_cond_wait(&threadCond, &mutex);
......@@ -316,7 +342,52 @@ static void pubsub_update_variables(UA_UInt32 id, const UA_DataValue *var, bool
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
* arg 5 (bool): true if there will be data to publish
*/
static JSValue js_run_pubsub(JSContext *ctx, JSValueConst this_val,
int argc, JSValueConst *argv)
{
int argc, JSValueConst *argv) {
const char *ipv6;
const char *port;
const char *netIface;
......@@ -364,6 +434,7 @@ static JSValue js_run_pubsub(JSContext *ctx, JSValueConst this_val,
isADrone = JS_ToBool(ctx, argv[5]);
variables = isADrone ? droneVariables : subscriberVariables;
logger = isADrone ? UA_Log_Stdout : &Subscriber_Log;
instanceArray = (InstanceData *) malloc((nbPeer) * sizeof(InstanceData));
for(UA_UInt32 i = 0; i < nbDrone; i++) {
......@@ -375,8 +446,8 @@ static JSValue js_run_pubsub(JSContext *ctx, JSValueConst this_val,
instanceArray[i].init_node_id = init_subscriber_node_id;
}
res = runPubsub(&transportProfile, &networkAddressUrl, variables, id,
instanceArray, nbPeer, MAX_VARIABLE_NB, interval,
res = runPubsub(logger, &transportProfile, &networkAddressUrl, variables,
id, instanceArray, nbPeer, MAX_VARIABLE_NB, interval,
get_drone_id, pubsub_get_value, pubsub_update_variables,
&pubsubShouldRun);
pubsubExited = true;
......@@ -420,6 +491,12 @@ static JSValue js_stop_pubsub(JSContext *ctx, JSValueConst thisVal,
}
clear_message(currentMessage);
while(logQueue.head != NULL) {
current = logQueue.head;
logQueue.head = current->next;
delete_message_node(current);
}
return JS_NewInt32(ctx, 0);
}
......@@ -645,6 +722,7 @@ static const JSCFunctionListEntry js_funcs[] = {
JS_CFUNC_DEF("getClimbRate", 0, js_getClimbRate ),
JS_CFUNC_DEF("healthAllOk", 0, js_healthAllOk ),
JS_CFUNC_DEF("initPubsub", 2, js_init_pubsub ),
JS_CFUNC_DEF("getLog", 0, js_get_log ),
};
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