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

Stop using custom logger

Stop using a custom logger for subscriber.
When drone logs are required during execution (a.k.a debug mode), they are now
send through OPC-UA.
parent 19d6f938
......@@ -5,7 +5,7 @@
#include "autopilot_wrapper.h"
#include "pubsub.h"
#define DRONE_VARIABLE_NB 3
#define DRONE_VARIABLE_NB 4
#define SUBSCRIBER_VARIABLE_NB 1
struct messageNode {
char *message;
......@@ -22,7 +22,7 @@ UA_UInt32 positionArrayDims[] = {POSITION_ARRAY_SIZE};
UA_Double speedArray[SPEED_ARRAY_SIZE] = { 0 };
UA_UInt32 speedArrayDims[] = {SPEED_ARRAY_SIZE};
UA_String message = {
UA_String initial_ua_string = {
.length = 0,
.data = NULL,
};
......@@ -55,7 +55,7 @@ VariableData droneVariableArray[] = {
{
.name = "message",
.description = "Message to send to the other drones",
.value = &message,
.value = &initial_ua_string,
.type = UA_TYPES_STRING,
.builtInType = UA_NS0ID_STRING,
.valueRank = UA_VALUERANK_SCALAR,
......@@ -63,6 +63,17 @@ VariableData droneVariableArray[] = {
.arrayDimensions = NULL,
.getter.getString = get_message,
},
{
.name = "log",
.description = "Message to send to the other drones",
.value = &initial_ua_string,
.type = UA_TYPES_STRING,
.builtInType = UA_NS0ID_STRING,
.valueRank = UA_VALUERANK_SCALAR,
.arrayDimensionsSize = 0,
.arrayDimensions = NULL,
.getter.getString = get_log,
},
};
VariableStruct droneVariables = {
......@@ -74,7 +85,7 @@ VariableData subscriberVariableArray[] = {
{
.name = "message",
.description = "Message to send to the other drones",
.value = &message,
.value = &initial_ua_string,
.type = UA_TYPES_STRING,
.builtInType = UA_NS0ID_STRING,
.valueRank = UA_VALUERANK_SCALAR,
......@@ -89,7 +100,4 @@ VariableStruct subscriberVariables = {
.variableArray = subscriberVariableArray,
};
void Subscriber_log(void *context, UA_LogLevel level, UA_LogCategory category,
const char *msg, va_list args);
#endif /* __DRONEDGE_H__ */
......@@ -31,6 +31,8 @@ typedef struct {
UA_Float climbRate;
char message[MAX_MESSAGE_SIZE];
UA_UInt32 messageId;
char log[MAX_MESSAGE_SIZE];
UA_UInt32 logId;
} JSDroneData;
typedef struct {
......@@ -79,6 +81,8 @@ int runPubsub(const UA_Logger *logger, UA_String *transportProfile,
UA_String get_message(void);
UA_String get_log(void);
UA_UInt16 get_drone_id(UA_UInt32 nb);
void init_drone_node_id(UA_UInt32 id, UA_UInt32 nb, UA_UInt32 magic);
......
......@@ -2,14 +2,6 @@
#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 JSClassID jsPositionClassId;
......@@ -19,30 +11,19 @@ static UA_Boolean pubsubExited = true;
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;
UA_String currentLog;
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"};
bool isADrone;
bool debug;
FILE *quickjsLogFptr;
// Position class functions
......@@ -158,10 +139,21 @@ static JSValue js_drone_init(JSContext *ctx, JSValueConst thisVal,
return JS_UNDEFINED;
}
static JSValue readDroneDataStr(JSContext *ctx, char *str)
{
JSValue res;
pthread_mutex_lock(&mutex);
res = JS_NewString(ctx, str);
strcpy(str, "");
pthread_cond_signal(&threadCond);
pthread_mutex_unlock(&mutex);
return res;
}
static JSValue js_drone_get(JSContext *ctx, JSValueConst thisVal, int magic)
{
JSDroneData *s = (JSDroneData *) JS_GetOpaque2(ctx, thisVal, jsDroneClassId);
JSValue res;
if (!s)
return JS_EXCEPTION;
switch(magic) {
......@@ -182,13 +174,10 @@ static JSValue js_drone_get(JSContext *ctx, JSValueConst thisVal, int magic)
case 7:
return JS_NewFloat64(ctx, s->climbRate);
case 8:
pthread_mutex_lock(&mutex);
res = JS_NewString(ctx, s->message);
strcpy(s->message, "");
pthread_cond_signal(&threadCond);
pthread_mutex_unlock(&mutex);
return res;
return readDroneDataStr(ctx, s->message);
case 9:
return readDroneDataStr(ctx, s->log);
case 10:
return JS_NewInt64(ctx, s->timestamp);
default:
return JS_EXCEPTION;
......@@ -216,7 +205,7 @@ static JSValue js_drone_set_message(JSContext *ctx, JSValueConst thisVal,
const char *message;
message = JS_ToCString(ctx, argv[0]);
if (strlen(message) > MAX_MESSAGE_SIZE) {
UA_LOG_ERROR(logger, UA_LOGCATEGORY_SERVER, "Message too long");
UA_LOG_ERROR(UA_Log_Stdout, UA_LOGCATEGORY_SERVER, "Message too long");
return JS_EXCEPTION;
}
......@@ -253,6 +242,16 @@ UA_String get_message(void)
return currentMessage;
}
UA_String get_log(void)
{
char log_str[MAX_MESSAGE_SIZE];
if (debug && isADrone && fread(log_str, sizeof(char), MAX_MESSAGE_SIZE, quickjsLogFptr) > 0) {
clear_message(currentLog);
currentLog = UA_STRING_ALLOC(log_str);
}
return currentLog;
}
static JSClassDef jsDroneClass = {
"Drone",
.finalizer = js_drone_finalizer,
......@@ -268,7 +267,8 @@ static const JSCFunctionListEntry js_drone_proto_funcs[] = {
JS_CGETSET_MAGIC_DEF("speed", js_drone_get, NULL, 6),
JS_CGETSET_MAGIC_DEF("climbRate", js_drone_get, NULL, 7),
JS_CGETSET_MAGIC_DEF("message", js_drone_get, NULL, 8),
JS_CGETSET_MAGIC_DEF("timestamp", js_drone_get, NULL, 9),
JS_CGETSET_MAGIC_DEF("log", js_drone_get, NULL, 9),
JS_CGETSET_MAGIC_DEF("timestamp", js_drone_get, NULL, 10),
JS_CFUNC_DEF("init", 1, js_drone_init),
};
......@@ -295,7 +295,7 @@ VariableData pubsub_get_value(UA_String identifier) {
*(UA_String*)varDetails.value = varDetails.getter.getString();
break;
default:
UA_LOG_ERROR(logger, UA_LOGCATEGORY_SERVER, "UA_TYPE not handled");
UA_LOG_ERROR(UA_Log_Stdout, UA_LOGCATEGORY_SERVER, "UA_TYPE not handled");
break;
}
break;
......@@ -317,14 +317,14 @@ VariableData pubsub_get_value(UA_String identifier) {
ptrd += type.memSize;
}
if(retval != UA_STATUSCODE_GOOD)
UA_LOG_ERROR(logger, UA_LOGCATEGORY_SERVER, "Failed to update array");
UA_LOG_ERROR(UA_Log_Stdout, UA_LOGCATEGORY_SERVER, "Failed to update array");
}
free(array);
break;
default:
UA_LOG_ERROR(logger, UA_LOGCATEGORY_SERVER, "UA_VALUERANK not handled");
UA_LOG_ERROR(UA_Log_Stdout, UA_LOGCATEGORY_SERVER, "UA_VALUERANK not handled");
break;
}
}
......@@ -345,8 +345,11 @@ void init_drone_node_id(UA_UInt32 id, UA_UInt32 nb, UA_UInt32 magic) {
case 2:
s->messageId = id;
break;
case 3:
s->logId = id;
break;
default:
UA_LOG_ERROR(logger, UA_LOGCATEGORY_USERLAND, "Unknown variable id");
UA_LOG_ERROR(UA_Log_Stdout, UA_LOGCATEGORY_USERLAND, "Unknown variable id");
break;
}
}
......@@ -358,15 +361,27 @@ void init_subscriber_node_id(UA_UInt32 id, UA_UInt32 nb, UA_UInt32 magic) {
s->messageId = id;
break;
default:
UA_LOG_ERROR(logger, UA_LOGCATEGORY_USERLAND, "Unknown variable id");
UA_LOG_ERROR(UA_Log_Stdout, UA_LOGCATEGORY_USERLAND, "Unknown variable id");
break;
}
}
static void setDroneDataStr(void *data, char *str)
{
UA_String uaStr = *(UA_String*) data;
pthread_mutex_lock(&mutex);
while(strlen(str) != 0)
pthread_cond_wait(&threadCond, &mutex);
memcpy(str, uaStr.data, uaStr.length);
str[uaStr.length] = '\0';
pthread_mutex_unlock(&mutex);
}
static void pubsub_update_variables(UA_UInt32 id, const UA_DataValue *var, bool print)
{
JSDroneData* s;
UA_String uaStr;
UA_Int64* positionArray;
UA_Float* speedArray;
......@@ -381,7 +396,7 @@ static void pubsub_update_variables(UA_UInt32 id, const UA_DataValue *var, bool
s->timestamp = positionArray[4];
if (print) {
UA_LOG_INFO(logger, UA_LOGCATEGORY_CLIENT,
UA_LOG_INFO(UA_Log_Stdout, UA_LOGCATEGORY_CLIENT,
"Received position of drone %d: %.6f ° %.6f ° %.2f m %.2f m",
s->id, s->latitude, s->longitude, s->altitudeAbs, s->altitudeRel);
}
......@@ -393,70 +408,22 @@ static void pubsub_update_variables(UA_UInt32 id, const UA_DataValue *var, bool
s->climbRate = speedArray[2];
if (print) {
UA_LOG_INFO(logger, UA_LOGCATEGORY_CLIENT,
UA_LOG_INFO(UA_Log_Stdout, 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);
memcpy(s->message, uaStr.data, uaStr.length);
s->message[uaStr.length] = '\0';
pthread_mutex_unlock(&mutex);
setDroneDataStr(var->value.data, s->message);
return;
} else if (s->logId == id) {
if (!isADrone) {
setDroneDataStr(var->value.data, s->log);
}
return;
}
}
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;
UA_LOG_ERROR(UA_Log_Stdout, UA_LOGCATEGORY_CLIENT, "NodeId not found");
}
/*
......@@ -476,7 +443,6 @@ static JSValue js_run_pubsub(JSContext *ctx, JSValueConst this_val,
char urlBuffer[44];
UA_UInt32 id;
UA_Duration interval;
bool isADrone;
VariableStruct variables;
InstanceData *instanceArray;
UA_UInt32 nbPeer = nbDrone + nbSubscriber;
......@@ -503,7 +469,6 @@ 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++) {
......@@ -516,8 +481,8 @@ static JSValue js_run_pubsub(JSContext *ctx, JSValueConst this_val,
}
pubsubExited = false;
res = runPubsub(logger, &transportProfile, &networkAddressUrl, variables,
id, instanceArray, nbPeer,
res = runPubsub(UA_Log_Stdout, &transportProfile, &networkAddressUrl,
variables, id, instanceArray, nbPeer,
fmax(DRONE_VARIABLE_NB, SUBSCRIBER_VARIABLE_NB), interval,
get_drone_id, pubsub_get_value, pubsub_update_variables,
&pubsubShouldRun);
......@@ -541,6 +506,7 @@ static JSValue js_init_pubsub(JSContext *ctx, JSValueConst thisVal,
return JS_EXCEPTION;
currentMessage = UA_STRING("");
currentLog = UA_STRING("");
droneObjectIdList = (JSValue *) malloc((nbDrone + nbSubscriber) * sizeof(JSValueConst));
return JS_NewInt32(ctx, 0);
}
......@@ -561,11 +527,10 @@ static JSValue js_stop_pubsub(JSContext *ctx, JSValueConst thisVal,
delete_message_node(current);
}
clear_message(currentMessage);
clear_message(currentLog);
while(logQueue.head != NULL) {
current = logQueue.head;
logQueue.head = current->next;
delete_message_node(current);
if (quickjsLogFptr != NULL) {
fclose(quickjsLogFptr);
}
return JS_NewInt32(ctx, 0);
......@@ -577,7 +542,8 @@ static JSValue js_start(JSContext *ctx, JSValueConst thisVal,
int argc, JSValueConst *argv)
{
const char *ip;
const char *log_file;
const char *mavsdk_log_file;
const char *quickjs_log_file;
int port;
int timeout;
int res;
......@@ -585,13 +551,19 @@ static JSValue js_start(JSContext *ctx, JSValueConst thisVal,
ip = JS_ToCString(ctx, argv[0]);
if (JS_ToInt32(ctx, &port, argv[1]))
return JS_EXCEPTION;
log_file = JS_ToCString(ctx, argv[2]);
if (JS_ToInt32(ctx, &timeout, argv[3]))
mavsdk_log_file = JS_ToCString(ctx, argv[2]);
quickjs_log_file = JS_ToCString(ctx, argv[3]);
if (JS_ToInt32(ctx, &timeout, argv[4]))
return JS_EXCEPTION;
debug = JS_ToBool(ctx, argv[5]);
if (debug) {
quickjsLogFptr = fopen(quickjs_log_file, "r");
}
res = start(ip, port, log_file, timeout);
res = start(ip, port, mavsdk_log_file, timeout);
JS_FreeCString(ctx, ip);
JS_FreeCString(ctx, log_file);
JS_FreeCString(ctx, mavsdk_log_file);
JS_FreeCString(ctx, quickjs_log_file);
return JS_NewInt32(ctx, res);
}
......@@ -771,7 +743,7 @@ static const JSCFunctionListEntry js_funcs[] = {
JS_CFUNC_DEF("setMessage", 1, js_drone_set_message ),
JS_CFUNC_DEF("runPubsub", 6, js_run_pubsub ),
JS_CFUNC_DEF("stopPubsub", 0, js_stop_pubsub ),
JS_CFUNC_DEF("start", 4, js_start ),
JS_CFUNC_DEF("start", 6, js_start ),
JS_CFUNC_DEF("stop", 0, js_stop ),
JS_CFUNC_DEF("reboot", 0, js_reboot ),
JS_CFUNC_DEF("arm", 0, js_arm ),
......@@ -794,7 +766,6 @@ static const JSCFunctionListEntry js_funcs[] = {
JS_CFUNC_DEF("isLanding", 0, js_isLanding ),
JS_CFUNC_DEF("healthAllOk", 0, js_healthAllOk ),
JS_CFUNC_DEF("initPubsub", 2, js_init_pubsub ),
JS_CFUNC_DEF("getLog", 0, js_get_log ),
JS_CFUNC_DEF("updateLogAndProjection", 0, js_updateLogAndProjection ),
};
......
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