fixed memory leaks, added cleanup code, added valgrind scripts to test binaries
This commit is contained in:
1
.gitignore
vendored
1
.gitignore
vendored
@@ -5,3 +5,4 @@ aqhome.db
|
|||||||
aqhome.log
|
aqhome.log
|
||||||
aqhomed.vg
|
aqhomed.vg
|
||||||
aqhome-mqttlog.vg
|
aqhome-mqttlog.vg
|
||||||
|
aqhome-storage.vg
|
||||||
|
|||||||
@@ -42,6 +42,7 @@
|
|||||||
fini.h
|
fini.h
|
||||||
loop.h
|
loop.h
|
||||||
loop_http.h
|
loop_http.h
|
||||||
|
cleanup.h
|
||||||
u_login.h
|
u_login.h
|
||||||
u_rooms.h
|
u_rooms.h
|
||||||
aqhomehttp.h
|
aqhomehttp.h
|
||||||
@@ -57,6 +58,7 @@
|
|||||||
fini.c
|
fini.c
|
||||||
loop.c
|
loop.c
|
||||||
loop_http.c
|
loop_http.c
|
||||||
|
cleanup.c
|
||||||
u_login.c
|
u_login.c
|
||||||
u_rooms.c
|
u_rooms.c
|
||||||
main.c
|
main.c
|
||||||
|
|||||||
@@ -48,7 +48,7 @@ void AqHomeHttpService_Extend(AQH_SERVICE *sv)
|
|||||||
GWEN_INHERIT_SETDATA(AQH_SERVICE, AQHOME_HTTP, sv, xsv, _freeData);
|
GWEN_INHERIT_SETDATA(AQH_SERVICE, AQHOME_HTTP, sv, xsv, _freeData);
|
||||||
|
|
||||||
xsv->contentTree=AQH_HttpContent_new("root");
|
xsv->contentTree=AQH_HttpContent_new("root");
|
||||||
|
xsv->storageMutex=GWEN_Mutex_new();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -62,6 +62,7 @@ void _freeData(void *bp, void *p)
|
|||||||
xsv->storage=NULL;
|
xsv->storage=NULL;
|
||||||
AQH_HttpContent_free(xsv->contentTree);
|
AQH_HttpContent_free(xsv->contentTree);
|
||||||
xsv->contentTree=NULL;
|
xsv->contentTree=NULL;
|
||||||
|
GWEN_Mutex_free(xsv->storageMutex);
|
||||||
|
|
||||||
GWEN_FREE_OBJECT(xsv);
|
GWEN_FREE_OBJECT(xsv);
|
||||||
}
|
}
|
||||||
@@ -124,6 +125,65 @@ void AqHomeHttpService_SetContentTree(AQH_SERVICE *sv, AQH_HTTP_CONTENT *c)
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
void AqHomeHttpService_MarkStorageChanged(AQH_SERVICE *sv)
|
||||||
|
{
|
||||||
|
if (sv) {
|
||||||
|
AQHOME_HTTP *xsv;
|
||||||
|
|
||||||
|
xsv=GWEN_INHERIT_GETDATA(AQH_SERVICE, AQHOME_HTTP, sv);
|
||||||
|
if (xsv) {
|
||||||
|
AQH_Storage_AddRuntimeFlags(xsv->storage, AQH_STORAGE_RTFLAGS_MODIFIED);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
int AqHomeHttpService_LockStorage(AQH_SERVICE *sv)
|
||||||
|
{
|
||||||
|
if (sv) {
|
||||||
|
AQHOME_HTTP *xsv;
|
||||||
|
|
||||||
|
xsv=GWEN_INHERIT_GETDATA(AQH_SERVICE, AQHOME_HTTP, sv);
|
||||||
|
if (xsv) {
|
||||||
|
int rv;
|
||||||
|
|
||||||
|
rv=GWEN_Mutex_Lock(xsv->storageMutex);
|
||||||
|
if (rv<0) {
|
||||||
|
DBG_ERROR(AQH_LOGDOMAIN, "Error obtaining lock on storage mutex");
|
||||||
|
return rv;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return GWEN_ERROR_GENERIC;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
int AqHomeHttpService_UnlockStorage(AQH_SERVICE *sv)
|
||||||
|
{
|
||||||
|
if (sv) {
|
||||||
|
AQHOME_HTTP *xsv;
|
||||||
|
|
||||||
|
xsv=GWEN_INHERIT_GETDATA(AQH_SERVICE, AQHOME_HTTP, sv);
|
||||||
|
if (xsv) {
|
||||||
|
int rv;
|
||||||
|
|
||||||
|
rv=GWEN_Mutex_Unlock(xsv->storageMutex);
|
||||||
|
if (rv<0) {
|
||||||
|
DBG_ERROR(AQH_LOGDOMAIN, "Error releasing lock on storage mutex");
|
||||||
|
return rv;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return GWEN_ERROR_GENERIC;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -50,7 +50,9 @@ AQH_HTTP_CONTENT *AqHomeHttpService_GetContentTree(const AQH_SERVICE *sv);
|
|||||||
void AqHomeHttpService_SetContentTree(AQH_SERVICE *sv, AQH_HTTP_CONTENT *c);
|
void AqHomeHttpService_SetContentTree(AQH_SERVICE *sv, AQH_HTTP_CONTENT *c);
|
||||||
|
|
||||||
|
|
||||||
|
int AqHomeHttpService_LockStorage(AQH_SERVICE *sv);
|
||||||
|
int AqHomeHttpService_UnlockStorage(AQH_SERVICE *sv);
|
||||||
|
void AqHomeHttpService_MarkStorageChanged(AQH_SERVICE *sv);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|||||||
@@ -12,10 +12,14 @@
|
|||||||
|
|
||||||
#include "./aqhomehttp.h"
|
#include "./aqhomehttp.h"
|
||||||
|
|
||||||
|
#include <gwenhywfar/mutex.h>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
typedef struct AQHOME_HTTP AQHOME_HTTP;
|
typedef struct AQHOME_HTTP AQHOME_HTTP;
|
||||||
struct AQHOME_HTTP {
|
struct AQHOME_HTTP {
|
||||||
AQH_STORAGE *storage; /* do not release */
|
AQH_STORAGE *storage; /* do not release */
|
||||||
|
GWEN_MUTEX *storageMutex;
|
||||||
|
|
||||||
AQH_HTTP_CONTENT *contentTree;
|
AQH_HTTP_CONTENT *contentTree;
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -36,16 +36,16 @@ AQHOME_STORAGE *AqHomeStorage_new()
|
|||||||
void AqHomeStorage_free(AQHOME_STORAGE *aqh)
|
void AqHomeStorage_free(AQHOME_STORAGE *aqh)
|
||||||
{
|
{
|
||||||
if (aqh) {
|
if (aqh) {
|
||||||
|
AQH_Service_free(aqh->httpService);
|
||||||
|
aqh->httpService=NULL;
|
||||||
AQH_Storage_free(aqh->storage);
|
AQH_Storage_free(aqh->storage);
|
||||||
GWEN_MsgEndpoint_free(aqh->rootEndpoint);
|
|
||||||
GWEN_MsgEndpoint_free(aqh->rootEndpoint);
|
|
||||||
GWEN_DB_Group_free(aqh->dbArgs);
|
|
||||||
|
|
||||||
aqh->storage=NULL;
|
aqh->storage=NULL;
|
||||||
|
GWEN_MsgEndpoint_free(aqh->rootEndpoint);
|
||||||
aqh->rootEndpoint=NULL;
|
aqh->rootEndpoint=NULL;
|
||||||
aqh->ipcdEndpoint=NULL;
|
aqh->ipcdEndpoint=NULL;
|
||||||
aqh->mqttEndpoint=NULL;
|
aqh->mqttEndpoint=NULL;
|
||||||
aqh->httpdEndpoint=NULL;
|
aqh->httpdEndpoint=NULL;
|
||||||
|
GWEN_DB_Group_free(aqh->dbArgs);
|
||||||
aqh->dbArgs=NULL;
|
aqh->dbArgs=NULL;
|
||||||
free(aqh->pidFile);
|
free(aqh->pidFile);
|
||||||
|
|
||||||
@@ -114,6 +114,13 @@ void AqHomeStorage_SetPidFile(AQHOME_STORAGE *aqh, const char *s)
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
int AqHomeStorage_GetTimeout(const AQHOME_STORAGE *aqh)
|
||||||
|
{
|
||||||
|
return aqh?aqh->timeout:0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -35,6 +35,8 @@ AQH_STORAGE *AqHomeStorage_GetStorage(const AQHOME_STORAGE *aqh);
|
|||||||
const char *AqHomeStorage_GetPidFile(const AQHOME_STORAGE *aqh);
|
const char *AqHomeStorage_GetPidFile(const AQHOME_STORAGE *aqh);
|
||||||
void AqHomeStorage_SetPidFile(AQHOME_STORAGE *aqh, const char *s);
|
void AqHomeStorage_SetPidFile(AQHOME_STORAGE *aqh, const char *s);
|
||||||
|
|
||||||
|
int AqHomeStorage_GetTimeout(const AQHOME_STORAGE *aqh);
|
||||||
|
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|||||||
@@ -27,6 +27,8 @@
|
|||||||
|
|
||||||
#define AQHOME_STORAGE_DEFAULT_STATEFILE "/var/lib/aqhomestorage/config/statefile"
|
#define AQHOME_STORAGE_DEFAULT_STATEFILE "/var/lib/aqhomestorage/config/statefile"
|
||||||
|
|
||||||
|
#define AQHOME_STORAGE_DEFAULT_MAXSESSIONAGE (30*60)
|
||||||
|
|
||||||
#define AQHOME_STORAGE_SITEHEADER "site-header.html"
|
#define AQHOME_STORAGE_SITEHEADER "site-header.html"
|
||||||
#define AQHOME_STORAGE_SITEFOOTER "site-footer.html"
|
#define AQHOME_STORAGE_SITEFOOTER "site-footer.html"
|
||||||
|
|
||||||
@@ -35,9 +37,9 @@
|
|||||||
struct AQHOME_STORAGE {
|
struct AQHOME_STORAGE {
|
||||||
GWEN_MSG_ENDPOINT *rootEndpoint;
|
GWEN_MSG_ENDPOINT *rootEndpoint;
|
||||||
|
|
||||||
GWEN_MSG_ENDPOINT *ipcdEndpoint;
|
GWEN_MSG_ENDPOINT *ipcdEndpoint; /* don't release, will be released by freeing rootEndpoint! */
|
||||||
GWEN_MSG_ENDPOINT *mqttEndpoint;
|
GWEN_MSG_ENDPOINT *mqttEndpoint; /* don't release, will be released by freeing rootEndpoint! */
|
||||||
GWEN_MSG_ENDPOINT *httpdEndpoint;
|
GWEN_MSG_ENDPOINT *httpdEndpoint; /* don't release, will be released by freeing rootEndpoint! */
|
||||||
|
|
||||||
GWEN_DB_NODE *dbArgs;
|
GWEN_DB_NODE *dbArgs;
|
||||||
|
|
||||||
@@ -45,6 +47,10 @@ struct AQHOME_STORAGE {
|
|||||||
AQH_STORAGE *storage;
|
AQH_STORAGE *storage;
|
||||||
|
|
||||||
char *pidFile;
|
char *pidFile;
|
||||||
|
|
||||||
|
int maxSessionAgeInSeconds;
|
||||||
|
|
||||||
|
int timeout; /* timeout for run e.g. inside valgrind */
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
61
apps/aqhome-storage/cleanup.c
Normal file
61
apps/aqhome-storage/cleanup.c
Normal file
@@ -0,0 +1,61 @@
|
|||||||
|
/****************************************************************************
|
||||||
|
* This file is part of the project AqHome.
|
||||||
|
* AqHome (c) by 2023 Martin Preuss, all rights reserved.
|
||||||
|
*
|
||||||
|
* The license for this file can be found in the file COPYING which you
|
||||||
|
* should have received along with this file.
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
#ifdef HAVE_CONFIG_H
|
||||||
|
# include <config.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
#include "./cleanup.h"
|
||||||
|
#include "./aqhomehttp.h"
|
||||||
|
#include "./aqhomestorage_p.h"
|
||||||
|
#include "aqhome/http/httpservice_conf.h"
|
||||||
|
|
||||||
|
#include <gwenhywfar/gwenhywfar.h>
|
||||||
|
#include <gwenhywfar/args.h>
|
||||||
|
#include <gwenhywfar/debug.h>
|
||||||
|
#include <gwenhywfar/endpoint.h>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/* ------------------------------------------------------------------------------------------------
|
||||||
|
* defines
|
||||||
|
* ------------------------------------------------------------------------------------------------
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/* ------------------------------------------------------------------------------------------------
|
||||||
|
* forward declarations
|
||||||
|
* ------------------------------------------------------------------------------------------------
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/* ------------------------------------------------------------------------------------------------
|
||||||
|
* implementations
|
||||||
|
* ------------------------------------------------------------------------------------------------
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
void AqHomeStorage_Cleanup(AQHOME_STORAGE *aqh)
|
||||||
|
{
|
||||||
|
|
||||||
|
int rv;
|
||||||
|
|
||||||
|
rv=AQH_HttpService_CleanupSessions(aqh->httpService, aqh->maxSessionAgeInSeconds);
|
||||||
|
if (rv<0) {
|
||||||
|
DBG_INFO(NULL, "here (%d)", rv);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
25
apps/aqhome-storage/cleanup.h
Normal file
25
apps/aqhome-storage/cleanup.h
Normal file
@@ -0,0 +1,25 @@
|
|||||||
|
/****************************************************************************
|
||||||
|
* This file is part of the project AqHome.
|
||||||
|
* AqHome (c) by 2023 Martin Preuss, all rights reserved.
|
||||||
|
*
|
||||||
|
* The license for this file can be found in the file COPYING which you
|
||||||
|
* should have received along with this file.
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
#ifndef AQHOME_STORAGE_CLEANUP_H
|
||||||
|
#define AQHOME_STORAGE_CLEANUP_H
|
||||||
|
|
||||||
|
|
||||||
|
#include "./aqhomestorage.h"
|
||||||
|
|
||||||
|
|
||||||
|
void AqHomeStorage_Cleanup(AQHOME_STORAGE *aqh);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@@ -96,6 +96,9 @@ int AqHomeStorage_Init(AQHOME_STORAGE *aqh, int argc, char **argv)
|
|||||||
}
|
}
|
||||||
aqh->dbArgs=dbArgs;
|
aqh->dbArgs=dbArgs;
|
||||||
|
|
||||||
|
aqh->maxSessionAgeInSeconds=GWEN_DB_GetIntValue(dbArgs, "maxSessionAge", 0, AQHOME_STORAGE_DEFAULT_MAXSESSIONAGE);
|
||||||
|
aqh->timeout=GWEN_DB_GetIntValue(dbArgs, "timeout", 0, 0);
|
||||||
|
|
||||||
s=GWEN_DB_GetCharValue(dbArgs, "pidfile", 0, AQHOME_STORAGE_DEFAULT_PIDFILE);
|
s=GWEN_DB_GetCharValue(dbArgs, "pidfile", 0, AQHOME_STORAGE_DEFAULT_PIDFILE);
|
||||||
if (s && *s) {
|
if (s && *s) {
|
||||||
AqHomeStorage_SetPidFile(aqh, s);
|
AqHomeStorage_SetPidFile(aqh, s);
|
||||||
@@ -415,6 +418,17 @@ int _readArgs(int argc, char **argv, GWEN_DB_NODE *dbArgs)
|
|||||||
I18S("Specify the port to listen on for HTTP connections"),
|
I18S("Specify the port to listen on for HTTP connections"),
|
||||||
I18S("Specify the port to listen on for HTTP connections")
|
I18S("Specify the port to listen on for HTTP connections")
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
GWEN_ARGS_FLAGS_HAS_ARGUMENT, /* flags */
|
||||||
|
GWEN_ArgsType_Int, /* type */
|
||||||
|
"maxSessionAge", /* name */
|
||||||
|
0, /* minnum */
|
||||||
|
1, /* maxnum */
|
||||||
|
NULL, /* short option */
|
||||||
|
"maxsessionage", /* long option */
|
||||||
|
I18S("Specify maximum session age in seconds (default: 30mins)"),
|
||||||
|
I18S("Specify maximum session age in seconds (default: 30mins)")
|
||||||
|
},
|
||||||
{
|
{
|
||||||
GWEN_ARGS_FLAGS_HAS_ARGUMENT, /* flags */
|
GWEN_ARGS_FLAGS_HAS_ARGUMENT, /* flags */
|
||||||
GWEN_ArgsType_Char, /* type */
|
GWEN_ArgsType_Char, /* type */
|
||||||
|
|||||||
@@ -151,7 +151,7 @@ int _setupHttpService(AQHOME_STORAGE *aqh, GWEN_DB_NODE *dbArgs)
|
|||||||
DBG_ERROR(NULL, "Error loading config for HTTP service (%d)", rv);
|
DBG_ERROR(NULL, "Error loading config for HTTP service (%d)", rv);
|
||||||
return GWEN_ERROR_GENERIC;
|
return GWEN_ERROR_GENERIC;
|
||||||
}
|
}
|
||||||
|
AQH_HttpService_LoadAllSessions(aqh->httpService);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -13,7 +13,9 @@
|
|||||||
|
|
||||||
#include "./loop.h"
|
#include "./loop.h"
|
||||||
#include "./loop_http.h"
|
#include "./loop_http.h"
|
||||||
|
#include "./aqhomehttp.h"
|
||||||
#include "./aqhomestorage_p.h"
|
#include "./aqhomestorage_p.h"
|
||||||
|
#include "aqhome/http/httpservice_conf.h"
|
||||||
|
|
||||||
#include <gwenhywfar/gwenhywfar.h>
|
#include <gwenhywfar/gwenhywfar.h>
|
||||||
#include <gwenhywfar/args.h>
|
#include <gwenhywfar/args.h>
|
||||||
@@ -34,6 +36,7 @@
|
|||||||
* ------------------------------------------------------------------------------------------------
|
* ------------------------------------------------------------------------------------------------
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
static int _writeModifiedSessions(AQHOME_STORAGE *aqh);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@@ -48,9 +51,97 @@ void AqHomeStorage_Loop(AQHOME_STORAGE *aqh, int timeoutInMsecs)
|
|||||||
GWEN_MsgEndpoint_ChildrenIoLoop(aqh->rootEndpoint, timeoutInMsecs);
|
GWEN_MsgEndpoint_ChildrenIoLoop(aqh->rootEndpoint, timeoutInMsecs);
|
||||||
AqHomeStorage_ReadAndHandleHttpMessages(aqh);
|
AqHomeStorage_ReadAndHandleHttpMessages(aqh);
|
||||||
// AqHomeStorage_ReadAndHandleIpcMessages(aqh);
|
// AqHomeStorage_ReadAndHandleIpcMessages(aqh);
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
int AqHomeStorage_WriteStorageIfChanged(AQHOME_STORAGE *aqh)
|
||||||
|
{
|
||||||
|
if (AQH_Storage_GetRuntimeFlags(aqh->storage) & AQH_STORAGE_RTFLAGS_MODIFIED) {
|
||||||
|
int rv;
|
||||||
|
|
||||||
|
DBG_INFO(NULL, "Storage modified, writing statefile");
|
||||||
|
rv=AqHomeHttpService_LockStorage(aqh->httpService);
|
||||||
|
if (rv<0) {
|
||||||
|
DBG_INFO(NULL, "Error locking storage (%d)", rv);
|
||||||
|
return rv;
|
||||||
|
}
|
||||||
|
rv=AQH_Storage_WriteState(aqh->storage);
|
||||||
|
if (rv<0) {
|
||||||
|
DBG_INFO(NULL, "Error writing state file (%d)", rv);
|
||||||
|
AqHomeHttpService_UnlockStorage(aqh->httpService);
|
||||||
|
return rv;
|
||||||
|
}
|
||||||
|
|
||||||
|
rv=AqHomeHttpService_UnlockStorage(aqh->httpService);
|
||||||
|
if (rv<0) {
|
||||||
|
DBG_INFO(NULL, "Error unlocking storage (%d)", rv);
|
||||||
|
return rv;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
int AqHomeStorage_WriteServiceIfChanged(AQHOME_STORAGE *aqh)
|
||||||
|
{
|
||||||
|
int rv;
|
||||||
|
|
||||||
|
rv=_writeModifiedSessions(aqh);
|
||||||
|
if (rv<0) {
|
||||||
|
DBG_INFO(NULL, "here (%d)", rv);
|
||||||
|
return rv;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
int _writeModifiedSessions(AQHOME_STORAGE *aqh)
|
||||||
|
{
|
||||||
|
AQH_SESSION_LIST *sessionList;
|
||||||
|
int rv;
|
||||||
|
|
||||||
|
rv=AQH_HttpService_LockSessions(aqh->httpService);
|
||||||
|
if (rv<0) {
|
||||||
|
DBG_INFO(NULL, "Error locking sessions (%d)", rv);
|
||||||
|
return rv;
|
||||||
|
}
|
||||||
|
|
||||||
|
sessionList=AQH_Service_GetSessionList(aqh->httpService);
|
||||||
|
if (sessionList) {
|
||||||
|
AQH_SESSION *session;
|
||||||
|
|
||||||
|
session=AQH_Session_List_First(sessionList);
|
||||||
|
while(session) {
|
||||||
|
if (AQH_Session_GetRuntimeFlags(session) & AQH_SESSION_RTFLAGS_MODIFIED) {
|
||||||
|
DBG_INFO(NULL, "Session \"%s\" modified, writing", AQH_Session_GetUid(session));
|
||||||
|
rv=AQH_HttpService_SaveSession(aqh->httpService, session);
|
||||||
|
if (rv<0) {
|
||||||
|
DBG_INFO(NULL, "Error writing session \"%s\" (%d)", AQH_Session_GetUid(session), rv);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
DBG_DEBUG(NULL, "Session \"%s\" written", AQH_Session_GetUid(session));
|
||||||
|
AQH_Session_SubRuntimeFlags(session, AQH_SESSION_RTFLAGS_MODIFIED);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
session=AQH_Session_List_Next(session);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
rv=AQH_HttpService_UnlockSessions(aqh->httpService);
|
||||||
|
if (rv<0) {
|
||||||
|
DBG_INFO(NULL, "Error unlocking sessions (%d)", rv);
|
||||||
|
return rv;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -15,6 +15,9 @@
|
|||||||
|
|
||||||
void AqHomeStorage_Loop(AQHOME_STORAGE *aqh, int timeoutInMsecs);
|
void AqHomeStorage_Loop(AQHOME_STORAGE *aqh, int timeoutInMsecs);
|
||||||
|
|
||||||
|
int AqHomeStorage_WriteStorageIfChanged(AQHOME_STORAGE *aqh);
|
||||||
|
|
||||||
|
int AqHomeStorage_WriteServiceIfChanged(AQHOME_STORAGE *aqh);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|||||||
@@ -17,6 +17,7 @@
|
|||||||
#include "./init.h"
|
#include "./init.h"
|
||||||
#include "./fini.h"
|
#include "./fini.h"
|
||||||
#include "./loop.h"
|
#include "./loop.h"
|
||||||
|
#include "./cleanup.h"
|
||||||
|
|
||||||
#include <gwenhywfar/gwenhywfar.h>
|
#include <gwenhywfar/gwenhywfar.h>
|
||||||
#include <gwenhywfar/logger.h>
|
#include <gwenhywfar/logger.h>
|
||||||
@@ -29,6 +30,14 @@
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
//#define CLEANUP_INTERVAL_IN_SECS (5*60)
|
||||||
|
//#define WRITE_INTERVAL_IN_SECS (5*60)
|
||||||
|
|
||||||
|
#define CLEANUP_INTERVAL_IN_SECS (60)
|
||||||
|
#define WRITE_INTERVAL_IN_SECS (60)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/* ------------------------------------------------------------------------------------------------
|
/* ------------------------------------------------------------------------------------------------
|
||||||
* defines
|
* defines
|
||||||
* ------------------------------------------------------------------------------------------------
|
* ------------------------------------------------------------------------------------------------
|
||||||
@@ -48,6 +57,9 @@ static int _setupSigAction(struct sigaction *sa, int sig);
|
|||||||
static void _signalHandler(int s);
|
static void _signalHandler(int s);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
static void _runService(AQHOME_STORAGE *aqh);
|
||||||
|
static void _writeCurrentState(AQHOME_STORAGE *aqh);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/* ------------------------------------------------------------------------------------------------
|
/* ------------------------------------------------------------------------------------------------
|
||||||
@@ -106,10 +118,7 @@ int main(int argc, char **argv)
|
|||||||
return 2;
|
return 2;
|
||||||
}
|
}
|
||||||
|
|
||||||
while(!stopService) {
|
_runService(aqh);
|
||||||
DBG_DEBUG(NULL, "Next loop");
|
|
||||||
AqHomeStorage_Loop(aqh, 2000);
|
|
||||||
}
|
|
||||||
|
|
||||||
AqHomeStorage_Fini(aqh);
|
AqHomeStorage_Fini(aqh);
|
||||||
AqHomeStorage_free(aqh);
|
AqHomeStorage_free(aqh);
|
||||||
@@ -122,6 +131,67 @@ int main(int argc, char **argv)
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
void _runService(AQHOME_STORAGE *aqh)
|
||||||
|
{
|
||||||
|
time_t timeStart;
|
||||||
|
time_t timeLastCleanup;
|
||||||
|
time_t timeLastWrite;
|
||||||
|
int timeout;
|
||||||
|
|
||||||
|
timeout=AqHomeStorage_GetTimeout(aqh);
|
||||||
|
timeStart=time(NULL);
|
||||||
|
timeLastCleanup=time(NULL);
|
||||||
|
timeLastWrite=time(NULL);
|
||||||
|
|
||||||
|
while(!stopService) {
|
||||||
|
time_t now;
|
||||||
|
|
||||||
|
DBG_DEBUG(NULL, "Next loop");
|
||||||
|
AqHomeStorage_Loop(aqh, 2000);
|
||||||
|
|
||||||
|
now=time(NULL);
|
||||||
|
|
||||||
|
if (((int)difftime(now, timeLastCleanup))>CLEANUP_INTERVAL_IN_SECS) {
|
||||||
|
DBG_INFO(NULL, "Cleanup time");
|
||||||
|
AqHomeStorage_Cleanup(aqh);
|
||||||
|
timeLastCleanup=now;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (((int)difftime(now, timeLastWrite))>WRITE_INTERVAL_IN_SECS) {
|
||||||
|
DBG_INFO(NULL, "Write time");
|
||||||
|
_writeCurrentState(aqh);
|
||||||
|
timeLastWrite=now;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
if (timeout && ((int)difftime(now, timeStart))>timeout) {
|
||||||
|
DBG_INFO(NULL, "Timeout");
|
||||||
|
_writeCurrentState(aqh);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
} /* while */
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
void _writeCurrentState(AQHOME_STORAGE *aqh)
|
||||||
|
{
|
||||||
|
int rv;
|
||||||
|
|
||||||
|
rv=AqHomeStorage_WriteStorageIfChanged(aqh);
|
||||||
|
if (rv<0) {
|
||||||
|
DBG_ERROR(NULL, "ATTENTION: Could not write storage statefile (%d)", rv);
|
||||||
|
}
|
||||||
|
|
||||||
|
rv=AqHomeStorage_WriteServiceIfChanged(aqh);
|
||||||
|
if (rv<0) {
|
||||||
|
DBG_ERROR(NULL, "ATTENTION: Could not write current config (%d)", rv);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
int _setSignalHandlers(void)
|
int _setSignalHandlers(void)
|
||||||
{
|
{
|
||||||
#ifdef HAVE_SIGNAL_H
|
#ifdef HAVE_SIGNAL_H
|
||||||
|
|||||||
@@ -308,8 +308,9 @@ AQH_SESSION *_generateSessionForUser(AQH_SERVICE *sv, AQH_USER *u)
|
|||||||
session=AQH_Session_new();
|
session=AQH_Session_new();
|
||||||
AQH_Session_SetUid(session, GWEN_Buffer_GetStart(buf));
|
AQH_Session_SetUid(session, GWEN_Buffer_GetStart(buf));
|
||||||
|
|
||||||
ts=GWEN_Timestamp_NowInGmTime();
|
ts=GWEN_Timestamp_NowInLocalTime();
|
||||||
AQH_Session_SetTimestampCreation(session, ts);
|
AQH_Session_SetTimestampCreation(session, ts);
|
||||||
|
AQH_Session_SetTimestampLastAccess(session, ts);
|
||||||
GWEN_Timestamp_free(ts);
|
GWEN_Timestamp_free(ts);
|
||||||
|
|
||||||
AQH_Session_SetUserAlias(session, AQH_User_GetAlias(u));
|
AQH_Session_SetUserAlias(session, AQH_User_GetAlias(u));
|
||||||
|
|||||||
@@ -36,14 +36,15 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
static int _handleUrl(AQH_HTTP_URLHANDLER *uh, AQH_HTTP_REQUEST *rq);
|
static int _handleUrl(AQH_HTTP_URLHANDLER *uh, AQH_HTTP_REQUEST *rq);
|
||||||
static int _handleGet(AQH_HTTP_URLHANDLER *uh, AQH_HTTP_REQUEST *rq);
|
static GWEN_MSG *_handleGet(AQH_HTTP_URLHANDLER *uh, AQH_HTTP_REQUEST *rq);
|
||||||
static int _handlePost(AQH_HTTP_URLHANDLER *uh, AQH_HTTP_REQUEST *rq);
|
static GWEN_MSG *_handlePost(AQH_HTTP_URLHANDLER *uh, AQH_HTTP_REQUEST *rq);
|
||||||
|
|
||||||
static void _handleGetList(AQH_HTTP_URLHANDLER *uh, AQH_HTTP_REQUEST *rq, GWEN_BUFFER *pageBuf);
|
static void _handleGetList(AQH_HTTP_URLHANDLER *uh, AQH_HTTP_REQUEST *rq, GWEN_BUFFER *pageBuf);
|
||||||
|
|
||||||
static void _handleGetAdd(AQH_HTTP_URLHANDLER *uh, AQH_HTTP_REQUEST *rq, GWEN_BUFFER *pageBuf);
|
static void _handleGetAdd(AQH_HTTP_URLHANDLER *uh, AQH_HTTP_REQUEST *rq, GWEN_BUFFER *pageBuf);
|
||||||
static int _handlePostAdd(AQH_HTTP_URLHANDLER *uh, AQH_HTTP_REQUEST *rq);
|
static GWEN_MSG *_handlePostAdd(AQH_HTTP_URLHANDLER *uh, AQH_HTTP_REQUEST *rq);
|
||||||
static int _writeAddPage(AQH_HTTP_URLHANDLER *uh, AQH_HTTP_REQUEST *rq, GWEN_DB_NODE *dbValues, GWEN_BUFFER *pageBuf);
|
static int _writeAddPage(AQH_HTTP_URLHANDLER *uh, AQH_HTTP_REQUEST *rq, GWEN_DB_NODE *dbValues, GWEN_BUFFER *pageBuf);
|
||||||
|
static GWEN_MSG *_addRoomCreateResponse(AQH_HTTP_URLHANDLER *uh, AQH_HTTP_REQUEST *rq);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@@ -68,7 +69,7 @@ int _handleUrl(AQH_HTTP_URLHANDLER *uh, AQH_HTTP_REQUEST *rq)
|
|||||||
{
|
{
|
||||||
const char *protocol;
|
const char *protocol;
|
||||||
const char *cmd;
|
const char *cmd;
|
||||||
GWEN_MSG *msgOut=NULL;
|
GWEN_MSG *msgOut;
|
||||||
|
|
||||||
AQH_HttpService_SetupModuleAndPerms(AQH_HttpUrlHandler_GetHttpService(uh), rq, "aqhome");
|
AQH_HttpService_SetupModuleAndPerms(AQH_HttpUrlHandler_GetHttpService(uh), rq, "aqhome");
|
||||||
AQH_HttpRequest_SetupUrlPathMembers(rq);
|
AQH_HttpRequest_SetupUrlPathMembers(rq);
|
||||||
@@ -76,26 +77,14 @@ int _handleUrl(AQH_HTTP_URLHANDLER *uh, AQH_HTTP_REQUEST *rq)
|
|||||||
protocol=AQH_HttpRequest_GetProtocol(rq);
|
protocol=AQH_HttpRequest_GetProtocol(rq);
|
||||||
cmd=AQH_HttpRequest_GetCommand(rq);
|
cmd=AQH_HttpRequest_GetCommand(rq);
|
||||||
if (cmd && *cmd) {
|
if (cmd && *cmd) {
|
||||||
int rv;
|
if (strcasecmp(cmd, "GET")==0)
|
||||||
|
msgOut=_handleGet(uh, rq);
|
||||||
if (strcasecmp(cmd, "GET")==0) {
|
else if (strcasecmp(cmd, "POST")==0)
|
||||||
rv=_handleGet(uh, rq);
|
msgOut=_handlePost(uh, rq);
|
||||||
if (rv<0) {
|
|
||||||
DBG_INFO(AQH_LOGDOMAIN, "here (%d)", rv);
|
|
||||||
return rv;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else if (strcasecmp(cmd, "POST")==0) {
|
|
||||||
rv=_handlePost(uh, rq);
|
|
||||||
if (rv<0) {
|
|
||||||
DBG_INFO(AQH_LOGDOMAIN, "here (%d)", rv);
|
|
||||||
return rv;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else {
|
else {
|
||||||
msgOut=AQH_HttpService_CreateResponseMsg(AQH_HttpUrlHandler_GetHttpService(uh), 405, "Method not allowed", protocol, NULL);
|
msgOut=AQH_HttpService_CreateResponseMsg(AQH_HttpUrlHandler_GetHttpService(uh), 405, "Method not allowed", protocol, NULL);
|
||||||
AQH_HttpRequest_SetResponseMsg(rq, msgOut);
|
|
||||||
}
|
}
|
||||||
|
AQH_HttpRequest_SetResponseMsg(rq, msgOut);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
@@ -106,7 +95,7 @@ int _handleUrl(AQH_HTTP_URLHANDLER *uh, AQH_HTTP_REQUEST *rq)
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
int _handleGet(AQH_HTTP_URLHANDLER *uh, AQH_HTTP_REQUEST *rq)
|
GWEN_MSG *_handleGet(AQH_HTTP_URLHANDLER *uh, AQH_HTTP_REQUEST *rq)
|
||||||
{
|
{
|
||||||
GWEN_BUFFER *pageBuf;
|
GWEN_BUFFER *pageBuf;
|
||||||
int rv;
|
int rv;
|
||||||
@@ -120,9 +109,7 @@ int _handleGet(AQH_HTTP_URLHANDLER *uh, AQH_HTTP_REQUEST *rq)
|
|||||||
if (rv<0) {
|
if (rv<0) {
|
||||||
DBG_ERROR(AQH_LOGDOMAIN, "Error adding headers");
|
DBG_ERROR(AQH_LOGDOMAIN, "Error adding headers");
|
||||||
GWEN_Buffer_free(pageBuf);
|
GWEN_Buffer_free(pageBuf);
|
||||||
msgOut=AQH_HttpService_CreateResponseMsg(AQH_HttpUrlHandler_GetHttpService(uh), 500, "Internal Error", protocol, NULL);
|
return AQH_HttpService_CreateResponseMsg(AQH_HttpUrlHandler_GetHttpService(uh), 500, "Internal Error", protocol, NULL);
|
||||||
AQH_HttpRequest_SetResponseMsg(rq, msgOut);
|
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* handle middle part (header - middle - footer) */
|
/* handle middle part (header - middle - footer) */
|
||||||
@@ -140,38 +127,35 @@ int _handleGet(AQH_HTTP_URLHANDLER *uh, AQH_HTTP_REQUEST *rq)
|
|||||||
_handleGetAdd(uh, rq, pageBuf);
|
_handleGetAdd(uh, rq, pageBuf);
|
||||||
else {
|
else {
|
||||||
DBG_ERROR(NULL, "Invalid url (2nd member is [%s])", s);
|
DBG_ERROR(NULL, "Invalid url (2nd member is [%s])", s);
|
||||||
msgOut=AQH_HttpService_CreateResponseMsg(AQH_HttpUrlHandler_GetHttpService(uh), 500, "Internal Error", protocol, NULL);
|
|
||||||
AQH_HttpRequest_SetResponseMsg(rq, msgOut);
|
|
||||||
GWEN_Buffer_free(pageBuf);
|
GWEN_Buffer_free(pageBuf);
|
||||||
return 0;
|
return AQH_HttpService_CreateResponseMsg(AQH_HttpUrlHandler_GetHttpService(uh), 404, "Not found", protocol, NULL);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
else {
|
||||||
|
DBG_ERROR(NULL, "No list of url members");
|
||||||
|
GWEN_Buffer_free(pageBuf);
|
||||||
|
return AQH_HttpService_CreateResponseMsg(AQH_HttpUrlHandler_GetHttpService(uh), 500, "Internal Error", protocol, NULL);
|
||||||
|
}
|
||||||
|
|
||||||
rv=AQH_HttpUrlHandler_AddContentFooters(uh, AQH_HTTP_CONTENT_MODE_DESKTOP, pageBuf);
|
rv=AQH_HttpUrlHandler_AddContentFooters(uh, AQH_HTTP_CONTENT_MODE_DESKTOP, pageBuf);
|
||||||
if (rv<0) {
|
if (rv<0) {
|
||||||
DBG_ERROR(AQH_LOGDOMAIN, "Error adding footers");
|
DBG_ERROR(AQH_LOGDOMAIN, "Error adding footers");
|
||||||
msgOut=AQH_HttpService_CreateResponseMsg(AQH_HttpUrlHandler_GetHttpService(uh), 500, "Internal Error", protocol, NULL);
|
|
||||||
AQH_HttpRequest_SetResponseMsg(rq, msgOut);
|
|
||||||
GWEN_Buffer_free(pageBuf);
|
GWEN_Buffer_free(pageBuf);
|
||||||
return rv;
|
return AQH_HttpService_CreateResponseMsg(AQH_HttpUrlHandler_GetHttpService(uh), 500, "Internal Error", protocol, NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
msgOut=AQH_HttpService_CreateResponseMsg(AQH_HttpUrlHandler_GetHttpService(uh), 200, "OK", protocol, GWEN_Buffer_GetStart(pageBuf));
|
msgOut=AQH_HttpService_CreateResponseMsg(AQH_HttpUrlHandler_GetHttpService(uh), 200, "OK", protocol, GWEN_Buffer_GetStart(pageBuf));
|
||||||
GWEN_Buffer_free(pageBuf);
|
GWEN_Buffer_free(pageBuf);
|
||||||
AQH_HttpRequest_SetResponseMsg(rq, msgOut);
|
return msgOut;
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
int _handlePost(AQH_HTTP_URLHANDLER *uh, AQH_HTTP_REQUEST *rq)
|
GWEN_MSG *_handlePost(AQH_HTTP_URLHANDLER *uh, AQH_HTTP_REQUEST *rq)
|
||||||
{
|
{
|
||||||
GWEN_DB_NODE *db;
|
GWEN_DB_NODE *db;
|
||||||
const GWEN_STRINGLIST *sl;
|
const GWEN_STRINGLIST *sl;
|
||||||
const char *protocol;
|
const char *protocol;
|
||||||
GWEN_MSG *msgOut=NULL;
|
|
||||||
int rv;
|
|
||||||
|
|
||||||
DBG_ERROR(NULL, "POST:");
|
DBG_ERROR(NULL, "POST:");
|
||||||
db=AQH_HttpRequest_GetDbPostBody(rq);
|
db=AQH_HttpRequest_GetDbPostBody(rq);
|
||||||
@@ -185,24 +169,21 @@ int _handlePost(AQH_HTTP_URLHANDLER *uh, AQH_HTTP_REQUEST *rq)
|
|||||||
s=GWEN_StringList_StringAt(sl, 1);
|
s=GWEN_StringList_StringAt(sl, 1);
|
||||||
if (s && *s) {
|
if (s && *s) {
|
||||||
if (strcasecmp(s, "add")==0)
|
if (strcasecmp(s, "add")==0)
|
||||||
rv=_handlePostAdd(uh, rq);
|
return _handlePostAdd(uh, rq);
|
||||||
else {
|
else {
|
||||||
DBG_ERROR(NULL, "Invalid url (2nd member is [%s])", s);
|
DBG_ERROR(NULL, "Invalid url (2nd member is [%s])", s);
|
||||||
msgOut=AQH_HttpService_CreateResponseMsg(AQH_HttpUrlHandler_GetHttpService(uh), 404, "Not found", protocol, NULL);
|
return AQH_HttpService_CreateResponseMsg(AQH_HttpUrlHandler_GetHttpService(uh), 404, "Not found", protocol, NULL);
|
||||||
AQH_HttpRequest_SetResponseMsg(rq, msgOut);
|
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
return rv;
|
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
DBG_ERROR(NULL, "Invalid url (2nd member missing)");
|
DBG_ERROR(NULL, "Invalid url (2nd member missing)");
|
||||||
msgOut=AQH_HttpService_CreateResponseMsg(AQH_HttpUrlHandler_GetHttpService(uh), 404, "Not found", protocol, NULL);
|
return AQH_HttpService_CreateResponseMsg(AQH_HttpUrlHandler_GetHttpService(uh), 404, "Not found", protocol, NULL);
|
||||||
AQH_HttpRequest_SetResponseMsg(rq, msgOut);
|
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
else {
|
||||||
return 0;
|
DBG_ERROR(NULL, "No list of url members");
|
||||||
|
return AQH_HttpService_CreateResponseMsg(AQH_HttpUrlHandler_GetHttpService(uh), 404, "Not found", protocol, NULL);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -316,65 +297,89 @@ int _writeAddPage(AQH_HTTP_URLHANDLER *uh, AQH_HTTP_REQUEST *rq, GWEN_DB_NODE *d
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
int _handlePostAdd(AQH_HTTP_URLHANDLER *uh, AQH_HTTP_REQUEST *rq)
|
GWEN_MSG *_handlePostAdd(AQH_HTTP_URLHANDLER *uh, AQH_HTTP_REQUEST *rq)
|
||||||
{
|
{
|
||||||
const char *protocol;
|
const char *protocol;
|
||||||
AQH_SERVICE *sv;
|
AQH_SERVICE *sv;
|
||||||
uint32_t perms;
|
uint32_t perms;
|
||||||
GWEN_MSG *msgOut=NULL;
|
|
||||||
|
|
||||||
protocol=AQH_HttpRequest_GetProtocol(rq);
|
protocol=AQH_HttpRequest_GetProtocol(rq);
|
||||||
sv=AQH_HttpUrlHandler_GetHttpService(uh);
|
sv=AQH_HttpUrlHandler_GetHttpService(uh);
|
||||||
perms=AQH_HttpRequest_GetModulePerms(rq);
|
perms=AQH_HttpRequest_GetModulePerms(rq);
|
||||||
if (perms & AQHOME_HTTP_PERMS_ADD_ROOM) {
|
if (perms & AQHOME_HTTP_PERMS_ADD_ROOM) {
|
||||||
GWEN_DB_NODE *db;
|
|
||||||
const char *roomName;
|
|
||||||
const char *roomDescr;
|
|
||||||
AQH_STORAGE *sto;
|
AQH_STORAGE *sto;
|
||||||
|
|
||||||
db=AQH_HttpRequest_GetDbPostBody(rq);
|
|
||||||
|
|
||||||
roomName=GWEN_DB_GetCharValue(db, "name", 0, NULL);
|
|
||||||
roomDescr=GWEN_DB_GetCharValue(db, "description", 0, NULL);
|
|
||||||
|
|
||||||
if (!(roomName && *roomName)) {
|
|
||||||
msgOut=AQH_HttpUrlHandler_CreatePageMessage(uh, rq, "red", I18N("Missing room name"), 1, db, _writeAddPage);
|
|
||||||
AQH_HttpRequest_SetResponseMsg(rq, msgOut);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
sto=AqHomeHttpService_GetStorage(sv);
|
sto=AqHomeHttpService_GetStorage(sv);
|
||||||
if (sto) {
|
if (sto) {
|
||||||
AQH_ROOM *r;
|
return _addRoomCreateResponse(uh, rq);
|
||||||
|
|
||||||
r=AQH_Room_new();
|
|
||||||
AQH_Room_SetName(r, roomName);
|
|
||||||
if (roomDescr && *roomDescr)
|
|
||||||
AQH_Room_SetDescription(r, roomDescr);
|
|
||||||
if (AQH_Storage_GetRoomByName(sto, roomName)!=NULL) {
|
|
||||||
msgOut=AQH_HttpUrlHandler_CreatePageMessage(uh, rq, "red", I18N("Room already exists"), 1, db, _writeAddPage);
|
|
||||||
AQH_HttpRequest_SetResponseMsg(rq, msgOut);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
AQH_Storage_AddRoom(sto, r);
|
|
||||||
msgOut=AQH_HttpService_CreateRedirectingResponseMsg(sv, protocol, "/rooms/list");
|
|
||||||
AQH_HttpRequest_SetResponseMsg(rq, msgOut);
|
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
DBG_ERROR(NULL, "No storage");
|
DBG_ERROR(NULL, "No storage");
|
||||||
msgOut=AQH_HttpService_CreateResponseMsg(sv, 500, "Internal error", protocol, NULL);
|
return AQH_HttpService_CreateResponseMsg(sv, 500, "Internal error", protocol, NULL);
|
||||||
AQH_HttpRequest_SetResponseMsg(rq, msgOut);
|
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
msgOut=AQH_HttpService_CreateResponseMsg(sv, 403, "Forbidden", protocol, NULL);
|
return AQH_HttpService_CreateResponseMsg(sv, 403, "Forbidden", protocol, NULL);
|
||||||
AQH_HttpRequest_SetResponseMsg(rq, msgOut);
|
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
GWEN_MSG *_addRoomCreateResponse(AQH_HTTP_URLHANDLER *uh, AQH_HTTP_REQUEST *rq)
|
||||||
|
{
|
||||||
|
AQH_SERVICE *sv;
|
||||||
|
const char *protocol;
|
||||||
|
GWEN_DB_NODE *db;
|
||||||
|
const char *roomName;
|
||||||
|
const char *roomDescr;
|
||||||
|
AQH_STORAGE *sto;
|
||||||
|
|
||||||
|
sv=AQH_HttpUrlHandler_GetHttpService(uh);
|
||||||
|
protocol=AQH_HttpRequest_GetProtocol(rq);
|
||||||
|
db=AQH_HttpRequest_GetDbPostBody(rq);
|
||||||
|
|
||||||
|
roomName=GWEN_DB_GetCharValue(db, "name", 0, NULL);
|
||||||
|
roomDescr=GWEN_DB_GetCharValue(db, "description", 0, NULL);
|
||||||
|
|
||||||
|
if (!(roomName && *roomName)) {
|
||||||
|
DBG_INFO(NULL, "Missing room name");
|
||||||
|
return AQH_HttpUrlHandler_CreatePageMessage(uh, rq, "red", I18N("Missing room name"), 1, db, _writeAddPage);
|
||||||
|
}
|
||||||
|
|
||||||
|
sto=AqHomeHttpService_GetStorage(sv);
|
||||||
|
if (sto) {
|
||||||
|
AQH_ROOM *r;
|
||||||
|
int rv;
|
||||||
|
|
||||||
|
r=AQH_Room_new();
|
||||||
|
AQH_Room_SetName(r, roomName);
|
||||||
|
if (roomDescr && *roomDescr)
|
||||||
|
AQH_Room_SetDescription(r, roomDescr);
|
||||||
|
|
||||||
|
rv=AqHomeHttpService_LockStorage(sv);
|
||||||
|
if (rv<0) {
|
||||||
|
DBG_ERROR(NULL, "Error locking storage");
|
||||||
|
return AQH_HttpService_CreateResponseMsg(sv, 500, "Internal error", protocol, NULL);
|
||||||
|
}
|
||||||
|
if (AQH_Storage_GetRoomByName(sto, roomName)!=NULL) {
|
||||||
|
DBG_INFO(NULL, "Room \"%s\" already exists", roomName);
|
||||||
|
AqHomeHttpService_UnlockStorage(sv);
|
||||||
|
return AQH_HttpUrlHandler_CreatePageMessage(uh, rq, "red", I18N("Room already exists"), 1, db, _writeAddPage);
|
||||||
|
}
|
||||||
|
AQH_Storage_AddRoom(sto, r);
|
||||||
|
AQH_Storage_AddRuntimeFlags(sto, AQH_STORAGE_RTFLAGS_MODIFIED);
|
||||||
|
|
||||||
|
rv=AqHomeHttpService_UnlockStorage(sv);
|
||||||
|
if (rv<0) {
|
||||||
|
DBG_ERROR(NULL, "Error unlocking storage");
|
||||||
|
return AQH_HttpService_CreateResponseMsg(sv, 500, "Internal error", protocol, NULL);
|
||||||
|
}
|
||||||
|
return AQH_HttpService_CreateRedirectingResponseMsg(sv, protocol, "/rooms/list");
|
||||||
|
}
|
||||||
|
else
|
||||||
|
return AQH_HttpService_CreateResponseMsg(sv, 500, "Internal error", protocol, NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -11,5 +11,5 @@ export LD_LIBRARY_PATH="0-build/aqhome/:$LD_LIBRARY_PATH"
|
|||||||
--statefile=apps/aqhome-storage/test/config/state \
|
--statefile=apps/aqhome-storage/test/config/state \
|
||||||
-ma 192.168.117.192 -mp 1883 --mqttclientid=AQHOMESTORAGETEST \
|
-ma 192.168.117.192 -mp 1883 --mqttclientid=AQHOMESTORAGETEST \
|
||||||
-ha 127.0.0.1 -hp 1884 \
|
-ha 127.0.0.1 -hp 1884 \
|
||||||
-p ./aqhome-storage.pid
|
-p ./aqhome-storage.pid \
|
||||||
|
$*
|
||||||
|
|||||||
@@ -48,7 +48,7 @@
|
|||||||
<default>0</default>
|
<default>0</default>
|
||||||
<preset>0</preset>
|
<preset>0</preset>
|
||||||
<access>public</access>
|
<access>public</access>
|
||||||
<flags>with_getbymember</flags>
|
<flags>own with_getbymember</flags>
|
||||||
</member>
|
</member>
|
||||||
|
|
||||||
<member name="mqttDataType" type="int" maxlen="8">
|
<member name="mqttDataType" type="int" maxlen="8">
|
||||||
|
|||||||
@@ -41,14 +41,14 @@
|
|||||||
<default>0</default>
|
<default>0</default>
|
||||||
<preset>0</preset>
|
<preset>0</preset>
|
||||||
<access>public</access>
|
<access>public</access>
|
||||||
<flags>with_getbymember</flags>
|
<flags>own with_getbymember</flags>
|
||||||
</member>
|
</member>
|
||||||
|
|
||||||
<member name="description" type="char_ptr" maxlen="256">
|
<member name="description" type="char_ptr" maxlen="256">
|
||||||
<default>0</default>
|
<default>0</default>
|
||||||
<preset>0</preset>
|
<preset>0</preset>
|
||||||
<access>public</access>
|
<access>public</access>
|
||||||
<flags></flags>
|
<flags>own</flags>
|
||||||
</member>
|
</member>
|
||||||
|
|
||||||
<member name="colour" type="uint32_t" maxlen="8">
|
<member name="colour" type="uint32_t" maxlen="8">
|
||||||
|
|||||||
@@ -204,6 +204,37 @@ AQH_VALUE *AQH_Storage_GetValueById(const AQH_STORAGE *sto, uint64_t id)
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
uint32_t AQH_Storage_GetRuntimeFlags(const AQH_STORAGE *sto)
|
||||||
|
{
|
||||||
|
return sto?sto->runtimeFlags:0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
void AQH_Storage_SetRuntimeFlags(AQH_STORAGE *sto, uint32_t flags)
|
||||||
|
{
|
||||||
|
if (sto)
|
||||||
|
sto->runtimeFlags=flags;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
void AQH_Storage_AddRuntimeFlags(AQH_STORAGE *sto, uint32_t flags)
|
||||||
|
{
|
||||||
|
if (sto)
|
||||||
|
sto->runtimeFlags|=flags;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
void AQH_Storage_SubRuntimeFlags(AQH_STORAGE *sto, uint32_t flags)
|
||||||
|
{
|
||||||
|
if (sto)
|
||||||
|
sto->runtimeFlags&=~flags;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
void AQH_Storage_HandleMqttPublish(AQH_STORAGE *sto, const char *topic, const char *value)
|
void AQH_Storage_HandleMqttPublish(AQH_STORAGE *sto, const char *topic, const char *value)
|
||||||
{
|
{
|
||||||
/* TODO */
|
/* TODO */
|
||||||
@@ -216,7 +247,10 @@ int AQH_Storage_Init(AQH_STORAGE *sto)
|
|||||||
int rv;
|
int rv;
|
||||||
|
|
||||||
rv=GWEN_Directory_GetPath(sto->stateFile,
|
rv=GWEN_Directory_GetPath(sto->stateFile,
|
||||||
GWEN_PATH_FLAGS_CHECKROOT | GWEN_PATH_FLAGS_PATHMUSTEXIST | GWEN_PATH_FLAGS_NAMEMUSTEXIST);
|
GWEN_PATH_FLAGS_CHECKROOT |
|
||||||
|
GWEN_PATH_FLAGS_PATHMUSTEXIST |
|
||||||
|
GWEN_PATH_FLAGS_NAMEMUSTEXIST |
|
||||||
|
GWEN_PATH_FLAGS_VARIABLE);
|
||||||
if (rv==0) {
|
if (rv==0) {
|
||||||
rv=AQH_Storage_ReadStateFile(sto, sto->stateFile);
|
rv=AQH_Storage_ReadStateFile(sto, sto->stateFile);
|
||||||
if (rv<0) {
|
if (rv<0) {
|
||||||
@@ -225,7 +259,7 @@ int AQH_Storage_Init(AQH_STORAGE *sto)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
DBG_WARN(AQH_LOGDOMAIN, "State file \"%s\" not available, will try to create it later", sto->stateFile);
|
DBG_WARN(AQH_LOGDOMAIN, "State file \"%s\" not available, will try to create it later (%d)", sto->stateFile, rv);
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
@@ -242,7 +276,7 @@ int AQH_Storage_WriteState(AQH_STORAGE *sto)
|
|||||||
DBG_INFO(AQH_LOGDOMAIN, "here (%d)", rv);
|
DBG_INFO(AQH_LOGDOMAIN, "here (%d)", rv);
|
||||||
return rv;
|
return rv;
|
||||||
}
|
}
|
||||||
|
sto->runtimeFlags&=~AQH_STORAGE_RTFLAGS_MODIFIED;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -34,6 +34,9 @@ typedef struct AQH_STORAGE AQH_STORAGE;
|
|||||||
#include "aqhome/data/datapoint.h"
|
#include "aqhome/data/datapoint.h"
|
||||||
|
|
||||||
|
|
||||||
|
#define AQH_STORAGE_RTFLAGS_MODIFIED 0x0001
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
extern "C" {
|
extern "C" {
|
||||||
@@ -67,6 +70,11 @@ AQHOME_API AQH_VALUE *AQH_Storage_GetValueById(const AQH_STORAGE *sto, uint64_t
|
|||||||
AQHOME_API const char *AQH_Storage_GetStateFile(const AQH_STORAGE *sto);
|
AQHOME_API const char *AQH_Storage_GetStateFile(const AQH_STORAGE *sto);
|
||||||
AQHOME_API void AQH_Storage_SetStateFile(AQH_STORAGE *sto, const char *s);
|
AQHOME_API void AQH_Storage_SetStateFile(AQH_STORAGE *sto, const char *s);
|
||||||
|
|
||||||
|
AQHOME_API uint32_t AQH_Storage_GetRuntimeFlags(const AQH_STORAGE *sto);
|
||||||
|
AQHOME_API void AQH_Storage_SetRuntimeFlags(AQH_STORAGE *sto, uint32_t flags);
|
||||||
|
AQHOME_API void AQH_Storage_AddRuntimeFlags(AQH_STORAGE *sto, uint32_t flags);
|
||||||
|
AQHOME_API void AQH_Storage_SubRuntimeFlags(AQH_STORAGE *sto, uint32_t flags);
|
||||||
|
|
||||||
|
|
||||||
AQHOME_API int AQH_Storage_Init(AQH_STORAGE *sto);
|
AQHOME_API int AQH_Storage_Init(AQH_STORAGE *sto);
|
||||||
AQHOME_API int AQH_Storage_WriteState(AQH_STORAGE *sto);
|
AQHOME_API int AQH_Storage_WriteState(AQH_STORAGE *sto);
|
||||||
|
|||||||
@@ -41,6 +41,8 @@ struct AQH_STORAGE {
|
|||||||
uint64_t lastValueId;
|
uint64_t lastValueId;
|
||||||
|
|
||||||
char *stateFile;
|
char *stateFile;
|
||||||
|
|
||||||
|
uint32_t runtimeFlags;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -57,6 +57,8 @@ int AQH_Storage_ReadStateFile(AQH_STORAGE *sto, const char *sFilename)
|
|||||||
_readTopicsFromXml(sto, rootNode);
|
_readTopicsFromXml(sto, rootNode);
|
||||||
_readValuesFromXml(sto, rootNode);
|
_readValuesFromXml(sto, rootNode);
|
||||||
|
|
||||||
|
GWEN_XMLNode_free(rootNode);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -125,7 +125,7 @@ void _writeDevicesToXml(const AQH_STORAGE *sto, GWEN_XMLNODE *rootNode)
|
|||||||
|
|
||||||
nElems=GWEN_XMLNode_new(GWEN_XMLNodeTypeTag, AQH_STORAGE_XML_ELEMENTNAME_DEVICES);
|
nElems=GWEN_XMLNode_new(GWEN_XMLNodeTypeTag, AQH_STORAGE_XML_ELEMENTNAME_DEVICES);
|
||||||
|
|
||||||
elem=AQH_Device_List_First(sto->roomList);
|
elem=AQH_Device_List_First(sto->deviceList);
|
||||||
while(elem) {
|
while(elem) {
|
||||||
GWEN_XMLNODE *nElem;
|
GWEN_XMLNODE *nElem;
|
||||||
|
|
||||||
|
|||||||
@@ -55,14 +55,14 @@
|
|||||||
<default>0</default>
|
<default>0</default>
|
||||||
<preset>0</preset>
|
<preset>0</preset>
|
||||||
<access>public</access>
|
<access>public</access>
|
||||||
<flags></flags>
|
<flags>own</flags>
|
||||||
</member>
|
</member>
|
||||||
|
|
||||||
<member name="dataPath" type="char_ptr" maxlen="256">
|
<member name="dataPath" type="char_ptr" maxlen="256">
|
||||||
<default>0</default>
|
<default>0</default>
|
||||||
<preset>0</preset>
|
<preset>0</preset>
|
||||||
<access>public</access>
|
<access>public</access>
|
||||||
<flags></flags>
|
<flags>own</flags>
|
||||||
</member>
|
</member>
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -45,6 +45,9 @@ void AQH_HttpContent_free(AQH_HTTP_CONTENT *cp)
|
|||||||
if (cp) {
|
if (cp) {
|
||||||
GWEN_TREE2_FINI(AQH_HTTP_CONTENT, cp, AQH_HttpContent);
|
GWEN_TREE2_FINI(AQH_HTTP_CONTENT, cp, AQH_HttpContent);
|
||||||
GWEN_INHERIT_FINI(AQH_HTTP_CONTENT, cp);
|
GWEN_INHERIT_FINI(AQH_HTTP_CONTENT, cp);
|
||||||
|
|
||||||
|
free(cp->name);
|
||||||
|
|
||||||
GWEN_FREE_OBJECT(cp);
|
GWEN_FREE_OBJECT(cp);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -119,7 +119,7 @@ void _addSockets(GWEN_MSG_ENDPOINT *ep, GWEN_SOCKETSET *readSet, GWEN_SOCKETSET
|
|||||||
} /* if socket */
|
} /* if socket */
|
||||||
}
|
}
|
||||||
else if (xep->addSocketsFn) {
|
else if (xep->addSocketsFn) {
|
||||||
DBG_INFO(AQH_LOGDOMAIN, "Endpoint %s: Not connected, calling base function", GWEN_MsgEndpoint_GetName(ep));
|
DBG_DEBUG(AQH_LOGDOMAIN, "Endpoint %s: Not connected, calling base function", GWEN_MsgEndpoint_GetName(ep));
|
||||||
xep->addSocketsFn(ep, readSet, writeSet, xSet);
|
xep->addSocketsFn(ep, readSet, writeSet, xSet);
|
||||||
}
|
}
|
||||||
} /* if (xep) */
|
} /* if (xep) */
|
||||||
@@ -172,7 +172,7 @@ void _checkSockets(GWEN_MSG_ENDPOINT *ep, GWEN_SOCKETSET *readSet, GWEN_SOCKETSE
|
|||||||
}
|
}
|
||||||
} /* if connected */
|
} /* if connected */
|
||||||
else if (xep->checkSocketsFn) {
|
else if (xep->checkSocketsFn) {
|
||||||
DBG_INFO(AQH_LOGDOMAIN, "Endpoint %s: Not connected, calling base function", GWEN_MsgEndpoint_GetName(ep));
|
DBG_DEBUG(AQH_LOGDOMAIN, "Endpoint %s: Not connected, calling base function", GWEN_MsgEndpoint_GetName(ep));
|
||||||
xep->checkSocketsFn(ep, readSet, writeSet, xSet);
|
xep->checkSocketsFn(ep, readSet, writeSet, xSet);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -208,7 +208,7 @@ int _writeCurrentMessage(GWEN_MSG_ENDPOINT *ep)
|
|||||||
}
|
}
|
||||||
GWEN_Msg_IncCurrentPos(msg, rv);
|
GWEN_Msg_IncCurrentPos(msg, rv);
|
||||||
if (rv==remaining) {
|
if (rv==remaining) {
|
||||||
DBG_INFO(AQH_LOGDOMAIN, "Message completely sent");
|
DBG_DEBUG(AQH_LOGDOMAIN, "Message completely sent");
|
||||||
/* end current message */
|
/* end current message */
|
||||||
GWEN_Msg_List_Del(msg);
|
GWEN_Msg_List_Del(msg);
|
||||||
GWEN_Msg_free(msg);
|
GWEN_Msg_free(msg);
|
||||||
@@ -216,7 +216,7 @@ int _writeCurrentMessage(GWEN_MSG_ENDPOINT *ep)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
DBG_INFO(AQH_LOGDOMAIN, "Nothing to send");
|
DBG_DEBUG(AQH_LOGDOMAIN, "Nothing to send");
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@@ -309,7 +309,7 @@ int _distributeBufferInCommandMode(GWEN_MSG_ENDPOINT *ep, const uint8_t *bufferP
|
|||||||
const char *s;
|
const char *s;
|
||||||
|
|
||||||
/* line complete */
|
/* line complete */
|
||||||
DBG_INFO(AQH_LOGDOMAIN, "Command line complete");
|
DBG_DEBUG(AQH_LOGDOMAIN, "Command line complete");
|
||||||
rv=-rv;
|
rv=-rv;
|
||||||
xep=GWEN_INHERIT_GETDATA(GWEN_MSG_ENDPOINT, AQH_ENDPOINT_HTTP, ep);
|
xep=GWEN_INHERIT_GETDATA(GWEN_MSG_ENDPOINT, AQH_ENDPOINT_HTTP, ep);
|
||||||
|
|
||||||
@@ -319,21 +319,21 @@ int _distributeBufferInCommandMode(GWEN_MSG_ENDPOINT *ep, const uint8_t *bufferP
|
|||||||
DBG_INFO(AQH_LOGDOMAIN, "Error parsing command line [%s]", GWEN_Buffer_GetStart(xep->currentReadBuffer));
|
DBG_INFO(AQH_LOGDOMAIN, "Error parsing command line [%s]", GWEN_Buffer_GetStart(xep->currentReadBuffer));
|
||||||
return GWEN_ERROR_BAD_DATA;
|
return GWEN_ERROR_BAD_DATA;
|
||||||
}
|
}
|
||||||
DBG_ERROR(AQH_LOGDOMAIN, "Command line received: %s", GWEN_Buffer_GetStart(xep->currentReadBuffer));
|
DBG_DEBUG(AQH_LOGDOMAIN, "Command line received: %s", GWEN_Buffer_GetStart(xep->currentReadBuffer));
|
||||||
s=GWEN_DB_GetCharValue(xep->dbCurrentReadCommand, "protocol", 0, "HTTP/0.9");
|
s=GWEN_DB_GetCharValue(xep->dbCurrentReadCommand, "protocol", 0, "HTTP/0.9");
|
||||||
if (s && *s && strcasecmp(s, "HTTP/0.9")==0) {
|
if (s && *s && strcasecmp(s, "HTTP/0.9")==0) {
|
||||||
DBG_INFO(AQH_LOGDOMAIN, "HTTP 0.9, no header, message finished");
|
DBG_INFO(AQH_LOGDOMAIN, "HTTP 0.9, no header, message finished");
|
||||||
_finishMessageAndStartNext(ep);
|
_finishMessageAndStartNext(ep);
|
||||||
return rv;
|
return rv;
|
||||||
}
|
}
|
||||||
DBG_INFO(AQH_LOGDOMAIN,
|
DBG_DEBUG(AQH_LOGDOMAIN,
|
||||||
"Command line complete, advancing to header read mode (start: %d)",
|
"Command line complete, advancing to header read mode (start: %d)",
|
||||||
GWEN_Buffer_GetPos(xep->currentReadBuffer));
|
GWEN_Buffer_GetPos(xep->currentReadBuffer));
|
||||||
xep->readMode=AQH_EndpointHttpd_ReadMode_Headers;
|
xep->readMode=AQH_EndpointHttpd_ReadMode_Headers;
|
||||||
xep->currentHeaderPos=GWEN_Buffer_GetPos(xep->currentReadBuffer);
|
xep->currentHeaderPos=GWEN_Buffer_GetPos(xep->currentReadBuffer);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
DBG_INFO(AQH_LOGDOMAIN, "Line not yet finished (%d)", rv);
|
DBG_DEBUG(AQH_LOGDOMAIN, "Line not yet finished (%d)", rv);
|
||||||
}
|
}
|
||||||
|
|
||||||
return rv;
|
return rv;
|
||||||
@@ -352,7 +352,7 @@ int _distributeBufferInStatusMode(GWEN_MSG_ENDPOINT *ep, const uint8_t *bufferPt
|
|||||||
/* line complete, TODO: parse status/command line */
|
/* line complete, TODO: parse status/command line */
|
||||||
rv=-rv;
|
rv=-rv;
|
||||||
xep=GWEN_INHERIT_GETDATA(GWEN_MSG_ENDPOINT, AQH_ENDPOINT_HTTP, ep);
|
xep=GWEN_INHERIT_GETDATA(GWEN_MSG_ENDPOINT, AQH_ENDPOINT_HTTP, ep);
|
||||||
DBG_INFO(AQH_LOGDOMAIN, "Line complete, advancing to header read mode");
|
DBG_DEBUG(AQH_LOGDOMAIN, "Line complete, advancing to header read mode");
|
||||||
xep->readMode=AQH_EndpointHttpd_ReadMode_Headers;
|
xep->readMode=AQH_EndpointHttpd_ReadMode_Headers;
|
||||||
xep->currentBodyPos=GWEN_Buffer_GetPos(xep->currentReadBuffer);
|
xep->currentBodyPos=GWEN_Buffer_GetPos(xep->currentReadBuffer);
|
||||||
}
|
}
|
||||||
@@ -382,7 +382,7 @@ int _distributeBufferInHeaderMode(GWEN_MSG_ENDPOINT *ep, const uint8_t *bufferPt
|
|||||||
int contentLength;
|
int contentLength;
|
||||||
|
|
||||||
/* Empty line received, TODO: parse header */
|
/* Empty line received, TODO: parse header */
|
||||||
DBG_INFO(AQH_LOGDOMAIN, "Empty header line received, end of header reached (header pos: %d).", xep->currentHeaderPos);
|
DBG_DEBUG(AQH_LOGDOMAIN, "Empty header line received, end of header reached (header pos: %d).", xep->currentHeaderPos);
|
||||||
copyOfHeader=strdup(GWEN_Buffer_GetStart(xep->currentReadBuffer)+xep->currentHeaderPos);
|
copyOfHeader=strdup(GWEN_Buffer_GetStart(xep->currentReadBuffer)+xep->currentHeaderPos);
|
||||||
xep->dbCurrentReadHeader=GWEN_DB_Group_new("header");
|
xep->dbCurrentReadHeader=GWEN_DB_Group_new("header");
|
||||||
if (_parseHeader(copyOfHeader, xep->dbCurrentReadHeader)<0) {
|
if (_parseHeader(copyOfHeader, xep->dbCurrentReadHeader)<0) {
|
||||||
@@ -393,7 +393,7 @@ int _distributeBufferInHeaderMode(GWEN_MSG_ENDPOINT *ep, const uint8_t *bufferPt
|
|||||||
free(copyOfHeader);
|
free(copyOfHeader);
|
||||||
contentLength=GWEN_DB_GetIntValue(xep->dbCurrentReadHeader, "Content-Length", 0, -1);
|
contentLength=GWEN_DB_GetIntValue(xep->dbCurrentReadHeader, "Content-Length", 0, -1);
|
||||||
if (contentLength==0 || contentLength==-1) {
|
if (contentLength==0 || contentLength==-1) {
|
||||||
DBG_INFO(AQH_LOGDOMAIN, "Message has no body, done");
|
DBG_DEBUG(AQH_LOGDOMAIN, "Message has no body, done");
|
||||||
_finishMessageAndStartNext(ep);
|
_finishMessageAndStartNext(ep);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
@@ -425,7 +425,7 @@ int _distributeBufferInBodyMode(GWEN_MSG_ENDPOINT *ep, const uint8_t *bufferPtr,
|
|||||||
GWEN_Buffer_AppendBytes(xep->currentReadBuffer, (const char*) bufferPtr, len);
|
GWEN_Buffer_AppendBytes(xep->currentReadBuffer, (const char*) bufferPtr, len);
|
||||||
xep->remainingBodySize-=len;
|
xep->remainingBodySize-=len;
|
||||||
if (xep->remainingBodySize==0) {
|
if (xep->remainingBodySize==0) {
|
||||||
DBG_INFO(AQH_LOGDOMAIN, "Body completely received");
|
DBG_DEBUG(AQH_LOGDOMAIN, "Body completely received");
|
||||||
_finishMessageAndStartNext(ep);
|
_finishMessageAndStartNext(ep);
|
||||||
}
|
}
|
||||||
return len;
|
return len;
|
||||||
@@ -475,7 +475,7 @@ void _finishMessageAndStartNext(GWEN_MSG_ENDPOINT *ep)
|
|||||||
GWEN_MSG *msg;
|
GWEN_MSG *msg;
|
||||||
GWEN_DB_NODE *dbParsedData;
|
GWEN_DB_NODE *dbParsedData;
|
||||||
|
|
||||||
DBG_INFO(AQH_LOGDOMAIN, "Message completely received.");
|
DBG_DEBUG(AQH_LOGDOMAIN, "Message completely received.");
|
||||||
xep=GWEN_INHERIT_GETDATA(GWEN_MSG_ENDPOINT, AQH_ENDPOINT_HTTP, ep);
|
xep=GWEN_INHERIT_GETDATA(GWEN_MSG_ENDPOINT, AQH_ENDPOINT_HTTP, ep);
|
||||||
|
|
||||||
msg=GWEN_Msg_fromBytes((const uint8_t*)GWEN_Buffer_GetStart(xep->currentReadBuffer), GWEN_Buffer_GetUsedBytes(xep->currentReadBuffer));
|
msg=GWEN_Msg_fromBytes((const uint8_t*)GWEN_Buffer_GetStart(xep->currentReadBuffer), GWEN_Buffer_GetUsedBytes(xep->currentReadBuffer));
|
||||||
@@ -502,11 +502,11 @@ void _finishMessageAndStartNext(GWEN_MSG_ENDPOINT *ep)
|
|||||||
xep->dbCurrentReadHeader=NULL;
|
xep->dbCurrentReadHeader=NULL;
|
||||||
|
|
||||||
if (xep->flags & AQH_ENDPOINT_HTTP_FLAGS_PASSIVE) {
|
if (xep->flags & AQH_ENDPOINT_HTTP_FLAGS_PASSIVE) {
|
||||||
DBG_INFO(AQH_LOGDOMAIN, "Passive connection");
|
DBG_DEBUG(AQH_LOGDOMAIN, "Passive connection");
|
||||||
xep->readMode=AQH_EndpointHttpd_ReadMode_Command;
|
xep->readMode=AQH_EndpointHttpd_ReadMode_Command;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
DBG_INFO(AQH_LOGDOMAIN, "Active connection");
|
DBG_DEBUG(AQH_LOGDOMAIN, "Active connection");
|
||||||
xep->readMode=AQH_EndpointHttpd_ReadMode_Status;
|
xep->readMode=AQH_EndpointHttpd_ReadMode_Status;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -517,7 +517,7 @@ void _abortMessage(GWEN_MSG_ENDPOINT *ep)
|
|||||||
{
|
{
|
||||||
AQH_ENDPOINT_HTTP *xep;
|
AQH_ENDPOINT_HTTP *xep;
|
||||||
|
|
||||||
DBG_INFO(AQH_LOGDOMAIN, "Message completely received.");
|
DBG_DEBUG(AQH_LOGDOMAIN, "Aborting message (if any).");
|
||||||
xep=GWEN_INHERIT_GETDATA(GWEN_MSG_ENDPOINT, AQH_ENDPOINT_HTTP, ep);
|
xep=GWEN_INHERIT_GETDATA(GWEN_MSG_ENDPOINT, AQH_ENDPOINT_HTTP, ep);
|
||||||
|
|
||||||
GWEN_Buffer_Reset(xep->currentReadBuffer);
|
GWEN_Buffer_Reset(xep->currentReadBuffer);
|
||||||
@@ -587,7 +587,7 @@ int _parseHeader(char *bufferPtr, GWEN_DB_NODE *db)
|
|||||||
while (*p && (*p==32 || *p==9))
|
while (*p && (*p==32 || *p==9))
|
||||||
p++;
|
p++;
|
||||||
if (*p) {
|
if (*p) {
|
||||||
DBG_ERROR(AQH_LOGDOMAIN, "Setting header variable: [%s] = [%s]", pVarBegin, p);
|
DBG_DEBUG(AQH_LOGDOMAIN, "Setting header variable: [%s] = [%s]", pVarBegin, p);
|
||||||
GWEN_DB_SetCharValue(db, GWEN_PATH_FLAGS_CREATE_VAR, pVarBegin, p);
|
GWEN_DB_SetCharValue(db, GWEN_PATH_FLAGS_CREATE_VAR, pVarBegin, p);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -18,6 +18,7 @@
|
|||||||
#include <gwenhywfar/buffer.h>
|
#include <gwenhywfar/buffer.h>
|
||||||
#include <gwenhywfar/text.h>
|
#include <gwenhywfar/text.h>
|
||||||
#include <gwenhywfar/debug.h>
|
#include <gwenhywfar/debug.h>
|
||||||
|
#include <gwenhywfar/directory.h>
|
||||||
|
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
@@ -54,11 +55,15 @@ static GWEN_BUFFER *_getConfigFilePath(const AQH_SERVICE *sv, const char *fileNa
|
|||||||
static GWEN_BUFFER *_getModuleFilePath(const AQH_SERVICE *sv, const char *modName);
|
static GWEN_BUFFER *_getModuleFilePath(const AQH_SERVICE *sv, const char *modName);
|
||||||
static GWEN_BUFFER *_getUserFilePath(const AQH_SERVICE *sv, const char *userAlias);
|
static GWEN_BUFFER *_getUserFilePath(const AQH_SERVICE *sv, const char *userAlias);
|
||||||
static GWEN_BUFFER *_getSessionFilePath(const AQH_SERVICE *sv, const char *sessionUid);
|
static GWEN_BUFFER *_getSessionFilePath(const AQH_SERVICE *sv, const char *sessionUid);
|
||||||
|
static GWEN_BUFFER *_getSessionFolder(const AQH_SERVICE *sv);
|
||||||
static int _checkUser(const AQH_USER *user, int ignoreMissingId);
|
static int _checkUser(const AQH_USER *user, int ignoreMissingId);
|
||||||
static int _checkSession(const AQH_SESSION *session);
|
static int _checkSession(const AQH_SESSION *session);
|
||||||
static int _checkModule(const AQH_MODULE *m, int ignoreMissingId);
|
static int _checkModule(const AQH_MODULE *m, int ignoreMissingId);
|
||||||
static int _checkRoleList(const AQH_ROLE_LIST *roleList, int ignoreMissingId);
|
static int _checkRoleList(const AQH_ROLE_LIST *roleList, int ignoreMissingId);
|
||||||
static int _writeDbFile(const char *fname, GWEN_DB_NODE *db);
|
static int _writeDbFile(const char *fname, GWEN_DB_NODE *db);
|
||||||
|
static GWEN_STRINGLIST *_getConfFileList(const char *folder, const char *mask);
|
||||||
|
static AQH_SESSION_LIST *_readAllSessionsIntoList(const AQH_SERVICE *sv);
|
||||||
|
static AQH_SESSION *_readSessionFromFile(const char *filename);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@@ -278,6 +283,141 @@ AQH_SESSION *AQH_HttpService_GetSession(AQH_SERVICE *sv, const char *sessionUid)
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
int AQH_HttpService_LockSessions(AQH_SERVICE *sv)
|
||||||
|
{
|
||||||
|
AQH_HTTP_SERVICE *xsv;
|
||||||
|
int rv;
|
||||||
|
|
||||||
|
xsv=GWEN_INHERIT_GETDATA(AQH_SERVICE, AQH_HTTP_SERVICE, sv);
|
||||||
|
if (xsv==NULL) {
|
||||||
|
DBG_ERROR(AQH_LOGDOMAIN, "Not a AQH_HttpService object");
|
||||||
|
return GWEN_ERROR_GENERIC;
|
||||||
|
}
|
||||||
|
|
||||||
|
rv=GWEN_Mutex_Lock(xsv->sessionMutex);
|
||||||
|
if (rv<0) {
|
||||||
|
DBG_ERROR(AQH_LOGDOMAIN, "Error obtaining lock on session mutex");
|
||||||
|
return rv;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
int AQH_HttpService_UnlockSessions(AQH_SERVICE *sv)
|
||||||
|
{
|
||||||
|
AQH_HTTP_SERVICE *xsv;
|
||||||
|
int rv;
|
||||||
|
|
||||||
|
xsv=GWEN_INHERIT_GETDATA(AQH_SERVICE, AQH_HTTP_SERVICE, sv);
|
||||||
|
if (xsv==NULL) {
|
||||||
|
DBG_ERROR(AQH_LOGDOMAIN, "Not a AQH_HttpService object");
|
||||||
|
return GWEN_ERROR_GENERIC;
|
||||||
|
}
|
||||||
|
|
||||||
|
rv=GWEN_Mutex_Unlock(xsv->sessionMutex);
|
||||||
|
if (rv<0) {
|
||||||
|
DBG_ERROR(AQH_LOGDOMAIN, "Error releasing lock on session mutex");
|
||||||
|
return rv;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
int AQH_HttpService_CleanupSessions(AQH_SERVICE *sv, int maxAgeInSecs)
|
||||||
|
{
|
||||||
|
time_t tNow;
|
||||||
|
AQH_SESSION_LIST *sessionList;
|
||||||
|
int rv;
|
||||||
|
|
||||||
|
rv=AQH_HttpService_LockSessions(sv);
|
||||||
|
if (rv<0) {
|
||||||
|
DBG_INFO(AQH_LOGDOMAIN, "Error locking sessions (%d)", rv);
|
||||||
|
return rv;
|
||||||
|
}
|
||||||
|
|
||||||
|
tNow=time(NULL);
|
||||||
|
|
||||||
|
sessionList=AQH_Service_GetSessionList(sv);
|
||||||
|
if (sessionList) {
|
||||||
|
AQH_SESSION *session;
|
||||||
|
|
||||||
|
session=AQH_Session_List_First(sessionList);
|
||||||
|
while(session) {
|
||||||
|
AQH_SESSION *next;
|
||||||
|
const GWEN_TIMESTAMP *ts;
|
||||||
|
|
||||||
|
next=AQH_Session_List_Next(session);
|
||||||
|
|
||||||
|
ts=AQH_Session_GetTimestampLastAccess(session);
|
||||||
|
if (ts==NULL)
|
||||||
|
ts=AQH_Session_GetTimestampCreation(session);
|
||||||
|
if (ts) {
|
||||||
|
time_t diff;
|
||||||
|
|
||||||
|
diff=tNow-GWEN_Timestamp_toTimeT(ts);
|
||||||
|
if (((int)diff)>maxAgeInSecs) {
|
||||||
|
DBG_INFO(AQH_LOGDOMAIN, "Session \"%s\" expired (%d secs)", AQH_Session_GetUid(session), (int) diff);
|
||||||
|
rv=AQH_HttpService_DelSession(sv, session); /* frees session!! */
|
||||||
|
if (rv<0) {
|
||||||
|
DBG_INFO(AQH_LOGDOMAIN, "here (%d)", rv);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
session=next;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
rv=AQH_HttpService_UnlockSessions(sv);
|
||||||
|
if (rv<0) {
|
||||||
|
DBG_INFO(AQH_LOGDOMAIN, "Error unlocking sessions (%d)", rv);
|
||||||
|
return rv;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void AQH_HttpService_LoadAllSessions(AQH_SERVICE *sv)
|
||||||
|
{
|
||||||
|
AQH_SESSION_LIST *sessionList;
|
||||||
|
|
||||||
|
sessionList=_readAllSessionsIntoList(sv);
|
||||||
|
if (sessionList) {
|
||||||
|
AQH_SESSION *session;
|
||||||
|
|
||||||
|
while( (session=AQH_Session_List_First(sessionList)) ) {
|
||||||
|
const char *sessionUid;
|
||||||
|
const char *userAlias;
|
||||||
|
|
||||||
|
AQH_Session_List_Del(session);
|
||||||
|
sessionUid=AQH_Session_GetUid(session);
|
||||||
|
userAlias=AQH_Session_GetUserAlias(session);
|
||||||
|
if (userAlias && *userAlias) {
|
||||||
|
AQH_USER *user;
|
||||||
|
|
||||||
|
user=AQH_HttpService_GetUser(sv, userAlias);
|
||||||
|
if (user==NULL) {
|
||||||
|
DBG_ERROR(AQH_LOGDOMAIN, "User \"%s\" for session \"%s\" not available", userAlias, sessionUid);
|
||||||
|
AQH_Session_free(session);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
DBG_INFO(AQH_LOGDOMAIN, "Adding session \"%s\" (user=%s)", sessionUid, userAlias);
|
||||||
|
AQH_Session_SetUser(session, user);
|
||||||
|
AQH_Service_AddSession(sv, session);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
DBG_ERROR(AQH_LOGDOMAIN, "Session has no user, not adding");
|
||||||
|
AQH_Session_free(session);
|
||||||
|
}
|
||||||
|
} /* while */
|
||||||
|
AQH_Session_List_free(sessionList);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@@ -518,29 +658,21 @@ AQH_SESSION *AQH_HttpService_LoadSession(const AQH_SERVICE *sv, const char *sess
|
|||||||
{
|
{
|
||||||
GWEN_BUFFER *nameBuf;
|
GWEN_BUFFER *nameBuf;
|
||||||
int rv;
|
int rv;
|
||||||
GWEN_DB_NODE *db;
|
|
||||||
AQH_SESSION *session;
|
AQH_SESSION *session;
|
||||||
|
|
||||||
db=GWEN_DB_Group_new("user");
|
|
||||||
|
|
||||||
nameBuf=_getSessionFilePath(sv, sessionUid);
|
nameBuf=_getSessionFilePath(sv, sessionUid);
|
||||||
rv=GWEN_DB_ReadFile(db, GWEN_Buffer_GetStart(nameBuf), GWEN_DB_FLAGS_DEFAULT);
|
if (nameBuf==NULL) {
|
||||||
if (rv<0) {
|
DBG_INFO(AQH_LOGDOMAIN, "here");
|
||||||
DBG_INFO(AQH_LOGDOMAIN, "here (%d)", rv);
|
return NULL;
|
||||||
|
}
|
||||||
|
session=_readSessionFromFile(GWEN_Buffer_GetStart(nameBuf));
|
||||||
|
if (session==NULL) {
|
||||||
|
DBG_ERROR(AQH_LOGDOMAIN, "Error loading session \"%s\" from config group", sessionUid);
|
||||||
GWEN_Buffer_free(nameBuf);
|
GWEN_Buffer_free(nameBuf);
|
||||||
GWEN_DB_Group_free(db);
|
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
GWEN_Buffer_free(nameBuf);
|
GWEN_Buffer_free(nameBuf);
|
||||||
|
|
||||||
session=AQH_Session_fromDb(db);
|
|
||||||
if (session==NULL) {
|
|
||||||
DBG_ERROR(AQH_LOGDOMAIN, "Error loading session \"%s\" from config group", sessionUid);
|
|
||||||
GWEN_DB_Group_free(db);
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
GWEN_DB_Group_free(db);
|
|
||||||
|
|
||||||
rv=_checkSession(session);
|
rv=_checkSession(session);
|
||||||
if (rv<0) {
|
if (rv<0) {
|
||||||
DBG_INFO(AQH_LOGDOMAIN, "Invalid data for session \"%s\"", sessionUid);
|
DBG_INFO(AQH_LOGDOMAIN, "Invalid data for session \"%s\"", sessionUid);
|
||||||
@@ -686,7 +818,6 @@ AQH_SESSION *_ensureSession(AQH_SERVICE *sv, const char *sessionUid)
|
|||||||
AQH_Session_free(session);
|
AQH_Session_free(session);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
AQH_User_Attach(user);
|
|
||||||
AQH_Session_SetUser(session, user);
|
AQH_Session_SetUser(session, user);
|
||||||
AQH_Service_AddSession(sv, session);
|
AQH_Service_AddSession(sv, session);
|
||||||
}
|
}
|
||||||
@@ -773,23 +904,16 @@ GWEN_BUFFER *_getUserFilePath(const AQH_SERVICE *sv, const char *userAlias)
|
|||||||
|
|
||||||
GWEN_BUFFER *_getSessionFilePath(const AQH_SERVICE *sv, const char *sessionUid)
|
GWEN_BUFFER *_getSessionFilePath(const AQH_SERVICE *sv, const char *sessionUid)
|
||||||
{
|
{
|
||||||
const char *configFolder;
|
GWEN_BUFFER *nameBuf;
|
||||||
|
|
||||||
configFolder=AQH_HttpService_GetConfigFolder(sv);
|
nameBuf=_getSessionFolder(sv);
|
||||||
if (!(configFolder && *configFolder)) {
|
if (nameBuf) {
|
||||||
DBG_ERROR(AQH_LOGDOMAIN, "No config folder given");
|
GWEN_Buffer_AppendString(nameBuf, GWEN_DIR_SEPARATOR_S);
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
GWEN_BUFFER *nameBuf;
|
|
||||||
|
|
||||||
nameBuf=GWEN_Buffer_new(0, 256, 0, 1);
|
|
||||||
GWEN_Buffer_AppendString(nameBuf, configFolder);
|
|
||||||
GWEN_Buffer_AppendString(nameBuf, GWEN_DIR_SEPARATOR_S AQH_HTTP_SERVICE_DIR_SESSIONS GWEN_DIR_SEPARATOR_S);
|
|
||||||
GWEN_Text_EscapeToBuffer(sessionUid, nameBuf);
|
GWEN_Text_EscapeToBuffer(sessionUid, nameBuf);
|
||||||
GWEN_Buffer_AppendString(nameBuf, ".conf");
|
GWEN_Buffer_AppendString(nameBuf, ".conf");
|
||||||
return nameBuf;
|
return nameBuf;
|
||||||
}
|
}
|
||||||
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -1012,6 +1136,132 @@ int _writeDbFile(const char *fname, GWEN_DB_NODE *db)
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
GWEN_BUFFER *_getSessionFolder(const AQH_SERVICE *sv)
|
||||||
|
{
|
||||||
|
const char *configFolder;
|
||||||
|
|
||||||
|
configFolder=AQH_HttpService_GetConfigFolder(sv);
|
||||||
|
if (!(configFolder && *configFolder)) {
|
||||||
|
DBG_ERROR(AQH_LOGDOMAIN, "No config folder given");
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
GWEN_BUFFER *nameBuf;
|
||||||
|
|
||||||
|
nameBuf=GWEN_Buffer_new(0, 256, 0, 1);
|
||||||
|
GWEN_Buffer_AppendString(nameBuf, configFolder);
|
||||||
|
GWEN_Buffer_AppendString(nameBuf, GWEN_DIR_SEPARATOR_S AQH_HTTP_SERVICE_DIR_SESSIONS);
|
||||||
|
return nameBuf;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
GWEN_STRINGLIST *_getConfFileList(const char *folder, const char *mask)
|
||||||
|
{
|
||||||
|
GWEN_STRINGLIST *sl;
|
||||||
|
int rv;
|
||||||
|
|
||||||
|
sl=GWEN_StringList_new();
|
||||||
|
rv=GWEN_Directory_GetFileEntries(folder, sl, mask);
|
||||||
|
if (rv<0) {
|
||||||
|
DBG_INFO(AQH_LOGDOMAIN, "here (%d)", rv);
|
||||||
|
GWEN_StringList_free(sl);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
if (GWEN_StringList_Count(sl)<1) {
|
||||||
|
DBG_INFO(AQH_LOGDOMAIN, "Empty string list");
|
||||||
|
GWEN_StringList_free(sl);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
return sl;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
AQH_SESSION_LIST *_readAllSessionsIntoList(const AQH_SERVICE *sv)
|
||||||
|
{
|
||||||
|
GWEN_BUFFER *folderBuf;
|
||||||
|
|
||||||
|
folderBuf=_getSessionFolder(sv);
|
||||||
|
if (folderBuf) {
|
||||||
|
GWEN_STRINGLIST *fileList;
|
||||||
|
|
||||||
|
fileList=_getConfFileList(GWEN_Buffer_GetStart(folderBuf), "*.conf");
|
||||||
|
if (fileList) {
|
||||||
|
AQH_SESSION_LIST *sessionList;
|
||||||
|
uint32_t pos;
|
||||||
|
GWEN_STRINGLISTENTRY *se;
|
||||||
|
|
||||||
|
sessionList=AQH_Session_List_new();
|
||||||
|
GWEN_Buffer_AppendString(folderBuf, GWEN_DIR_SEPARATOR_S);
|
||||||
|
pos=GWEN_Buffer_GetPos(folderBuf);
|
||||||
|
se=GWEN_StringList_FirstEntry(fileList);
|
||||||
|
while(se) {
|
||||||
|
const char *s;
|
||||||
|
|
||||||
|
s=GWEN_StringListEntry_Data(se);
|
||||||
|
if (s && *s) {
|
||||||
|
AQH_SESSION *session;
|
||||||
|
|
||||||
|
GWEN_Buffer_AppendString(folderBuf, s);
|
||||||
|
session=_readSessionFromFile(GWEN_Buffer_GetStart(folderBuf));
|
||||||
|
if (session==NULL) {
|
||||||
|
DBG_INFO(AQH_LOGDOMAIN, "here");
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
AQH_Session_List_Add(session, sessionList);
|
||||||
|
}
|
||||||
|
GWEN_Buffer_Crop(folderBuf, 0, pos);
|
||||||
|
}
|
||||||
|
se=GWEN_StringListEntry_Next(se);
|
||||||
|
}
|
||||||
|
if (AQH_Session_List_GetCount(sessionList)<1) {
|
||||||
|
DBG_INFO(NULL, "Empty session list");
|
||||||
|
AQH_Session_List_free(sessionList);
|
||||||
|
GWEN_StringList_free(fileList);
|
||||||
|
GWEN_Buffer_free(folderBuf);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
GWEN_StringList_free(fileList);
|
||||||
|
GWEN_Buffer_free(folderBuf);
|
||||||
|
return sessionList;
|
||||||
|
}
|
||||||
|
GWEN_Buffer_free(folderBuf);
|
||||||
|
}
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
AQH_SESSION *_readSessionFromFile(const char *filename)
|
||||||
|
{
|
||||||
|
int rv;
|
||||||
|
GWEN_DB_NODE *db;
|
||||||
|
AQH_SESSION *session;
|
||||||
|
|
||||||
|
db=GWEN_DB_Group_new("session");
|
||||||
|
|
||||||
|
rv=GWEN_DB_ReadFile(db, filename, GWEN_DB_FLAGS_DEFAULT);
|
||||||
|
if (rv<0) {
|
||||||
|
DBG_INFO(AQH_LOGDOMAIN, "here (%d)", rv);
|
||||||
|
GWEN_DB_Group_free(db);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
session=AQH_Session_fromDb(db);
|
||||||
|
if (session==NULL) {
|
||||||
|
DBG_ERROR(AQH_LOGDOMAIN, "Error loading session from file \"%s\"", filename);
|
||||||
|
GWEN_DB_Group_free(db);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
GWEN_DB_Group_free(db);
|
||||||
|
return session;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -32,7 +32,9 @@ AQHOME_API AQH_USER *AQH_HttpService_GetUser(AQH_SERVICE *sv, const char *alias)
|
|||||||
AQHOME_API int AQH_HttpService_WriteUser(const AQH_SERVICE *sv, const AQH_USER *user);
|
AQHOME_API int AQH_HttpService_WriteUser(const AQH_SERVICE *sv, const AQH_USER *user);
|
||||||
|
|
||||||
AQHOME_API AQH_SESSION *AQH_HttpService_GetSession(AQH_SERVICE *sv, const char *sessionUid);
|
AQHOME_API AQH_SESSION *AQH_HttpService_GetSession(AQH_SERVICE *sv, const char *sessionUid);
|
||||||
|
AQHOME_API int AQH_HttpService_LockSessions(AQH_SERVICE *sv);
|
||||||
|
AQHOME_API int AQH_HttpService_UnlockSessions(AQH_SERVICE *sv);
|
||||||
|
AQHOME_API int AQH_HttpService_CleanupSessions(AQH_SERVICE *sv, int maxAgeInSecs);
|
||||||
|
|
||||||
AQHOME_API AQH_MODULE *AQH_HttpService_LoadModule(const AQH_SERVICE *sv, const char *modName);
|
AQHOME_API AQH_MODULE *AQH_HttpService_LoadModule(const AQH_SERVICE *sv, const char *modName);
|
||||||
AQHOME_API int AQH_HttpService_SaveModule(const AQH_SERVICE *sv, const AQH_MODULE *m);
|
AQHOME_API int AQH_HttpService_SaveModule(const AQH_SERVICE *sv, const AQH_MODULE *m);
|
||||||
@@ -47,6 +49,7 @@ AQHOME_API AQH_SESSION *AQH_HttpService_LoadSession(const AQH_SERVICE *sv, const
|
|||||||
AQHOME_API int AQH_HttpService_SaveSession(const AQH_SERVICE *sv, const AQH_SESSION *session);
|
AQHOME_API int AQH_HttpService_SaveSession(const AQH_SERVICE *sv, const AQH_SESSION *session);
|
||||||
AQHOME_API int AQH_HttpService_AddSession(AQH_SERVICE *sv, AQH_SESSION *session);
|
AQHOME_API int AQH_HttpService_AddSession(AQH_SERVICE *sv, AQH_SESSION *session);
|
||||||
AQHOME_API int AQH_HttpService_DelSession(AQH_SERVICE *sv, AQH_SESSION *session);
|
AQHOME_API int AQH_HttpService_DelSession(AQH_SERVICE *sv, AQH_SESSION *session);
|
||||||
|
AQHOME_API void AQH_HttpService_LoadAllSessions(AQH_SERVICE *sv);
|
||||||
|
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -94,7 +94,13 @@ GWEN_MSG *AQH_HttpService_HandleHttpRequest(AQH_SERVICE *sv, GWEN_MSG_ENDPOINT *
|
|||||||
DBG_INFO(AQH_LOGDOMAIN, "Session \"%s\" not found", s);
|
DBG_INFO(AQH_LOGDOMAIN, "Session \"%s\" not found", s);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
|
GWEN_TIMESTAMP *ts;
|
||||||
|
|
||||||
DBG_INFO(AQH_LOGDOMAIN, "Found session \"%s\"", s);
|
DBG_INFO(AQH_LOGDOMAIN, "Found session \"%s\"", s);
|
||||||
|
ts=GWEN_Timestamp_NowInLocalTime();
|
||||||
|
AQH_Session_SetTimestampLastAccess(session, ts);
|
||||||
|
GWEN_Timestamp_free(ts);
|
||||||
|
AQH_Session_AddRuntimeFlags(session, AQH_SESSION_RTFLAGS_MODIFIED);
|
||||||
AQH_HttpRequest_SetSession(rq, session);
|
AQH_HttpRequest_SetSession(rq, session);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -31,6 +31,7 @@
|
|||||||
role.t2d
|
role.t2d
|
||||||
user.t2d
|
user.t2d
|
||||||
session.t2d
|
session.t2d
|
||||||
|
permdef.t2d
|
||||||
</setVar>
|
</setVar>
|
||||||
|
|
||||||
<setVar name="local/built_sources" >
|
<setVar name="local/built_sources" >
|
||||||
|
|||||||
@@ -15,12 +15,15 @@
|
|||||||
with_db
|
with_db
|
||||||
with_list1
|
with_list1
|
||||||
with_list2
|
with_list2
|
||||||
|
nodup
|
||||||
|
nocopy
|
||||||
</flags>
|
</flags>
|
||||||
|
|
||||||
<headers>
|
<headers>
|
||||||
<header type="sys" loc="pre">aqhome/api.h</header>
|
<header type="sys" loc="pre">aqhome/api.h</header>
|
||||||
<header type="sys" loc="pre">gwenhywfar/error.h</header>
|
<header type="sys" loc="pre">gwenhywfar/error.h</header>
|
||||||
<header type="sys" loc="post">aqhome/service/role.h</header>
|
<header type="sys" loc="post">aqhome/service/role.h</header>
|
||||||
|
<header type="sys" loc="post">aqhome/service/permdef.h</header>
|
||||||
</headers>
|
</headers>
|
||||||
|
|
||||||
<inlines>
|
<inlines>
|
||||||
@@ -42,14 +45,14 @@
|
|||||||
<default>0</default>
|
<default>0</default>
|
||||||
<preset>0</preset>
|
<preset>0</preset>
|
||||||
<access>public</access>
|
<access>public</access>
|
||||||
<flags>with_getbymember</flags>
|
<flags>own with_getbymember</flags>
|
||||||
</member>
|
</member>
|
||||||
|
|
||||||
<member name="descr" type="char_ptr" maxlen="256">
|
<member name="descr" type="char_ptr" maxlen="256">
|
||||||
<default>0</default>
|
<default>0</default>
|
||||||
<preset>0</preset>
|
<preset>0</preset>
|
||||||
<access>public</access>
|
<access>public</access>
|
||||||
<flags></flags>
|
<flags>own</flags>
|
||||||
</member>
|
</member>
|
||||||
|
|
||||||
<member name="guestPerms" type="uint32_t" maxlen="4">
|
<member name="guestPerms" type="uint32_t" maxlen="4">
|
||||||
@@ -68,6 +71,15 @@
|
|||||||
<setflags>none</setflags>
|
<setflags>none</setflags>
|
||||||
</member>
|
</member>
|
||||||
|
|
||||||
|
<member name="permDefList" type="AQH_PERMDEF_LIST" elementName="permdef" >
|
||||||
|
<default>NULL</default>
|
||||||
|
<preset>NULL</preset>
|
||||||
|
<access>public</access>
|
||||||
|
<flags>own</flags>
|
||||||
|
<getflags>none</getflags>
|
||||||
|
<setflags>none</setflags>
|
||||||
|
</member>
|
||||||
|
|
||||||
</members>
|
</members>
|
||||||
|
|
||||||
</type>
|
</type>
|
||||||
|
|||||||
65
aqhome/service/permdef.t2d
Normal file
65
aqhome/service/permdef.t2d
Normal file
@@ -0,0 +1,65 @@
|
|||||||
|
<?xml?>
|
||||||
|
|
||||||
|
<tm2>
|
||||||
|
<type id="AQH_PERMDEF" type="pointer">
|
||||||
|
<descr>
|
||||||
|
</descr>
|
||||||
|
<lang id="c">
|
||||||
|
<identifier>AQH_PERMDEF</identifier>
|
||||||
|
<prefix>AQH_PermDef</prefix>
|
||||||
|
<baseFileName>permdef</baseFileName>
|
||||||
|
|
||||||
|
<flags>
|
||||||
|
with_xml
|
||||||
|
with_db
|
||||||
|
with_list1
|
||||||
|
nodup
|
||||||
|
nocopy
|
||||||
|
</flags>
|
||||||
|
|
||||||
|
<headers>
|
||||||
|
<header type="sys" loc="pre">aqhome/api.h</header>
|
||||||
|
</headers>
|
||||||
|
|
||||||
|
<inlines>
|
||||||
|
</inlines>
|
||||||
|
|
||||||
|
</lang>
|
||||||
|
|
||||||
|
|
||||||
|
<members>
|
||||||
|
|
||||||
|
<member name="id" type="char_ptr" maxlen="32">
|
||||||
|
<default>NULL</default>
|
||||||
|
<preset>NULL</preset>
|
||||||
|
<access>public</access>
|
||||||
|
<flags>own with_getbymember</flags>
|
||||||
|
</member>
|
||||||
|
|
||||||
|
<member name="name" type="char_ptr" maxlen="32">
|
||||||
|
<default>NULL</default>
|
||||||
|
<preset>NULL</preset>
|
||||||
|
<access>public</access>
|
||||||
|
<flags>own with_getbymember</flags>
|
||||||
|
</member>
|
||||||
|
|
||||||
|
<member name="mask" type="uint32_t" maxlen="4">
|
||||||
|
<default>0</default>
|
||||||
|
<preset>0</preset>
|
||||||
|
<access>public</access>
|
||||||
|
<flags>own with_getbymember</flags>
|
||||||
|
</member>
|
||||||
|
|
||||||
|
<member name="descr" type="char_ptr" maxlen="256">
|
||||||
|
<default>NULL</default>
|
||||||
|
<preset>NULL</preset>
|
||||||
|
<access>public</access>
|
||||||
|
<flags>own</flags>
|
||||||
|
</member>
|
||||||
|
|
||||||
|
</members>
|
||||||
|
|
||||||
|
</type>
|
||||||
|
|
||||||
|
</tm2>
|
||||||
|
|
||||||
@@ -40,7 +40,7 @@
|
|||||||
<default>0</default>
|
<default>0</default>
|
||||||
<preset>0</preset>
|
<preset>0</preset>
|
||||||
<access>public</access>
|
<access>public</access>
|
||||||
<flags></flags>
|
<flags>own</flags>
|
||||||
</member>
|
</member>
|
||||||
|
|
||||||
<member name="perms" type="uint32_t" maxlen="4">
|
<member name="perms" type="uint32_t" maxlen="4">
|
||||||
|
|||||||
@@ -44,10 +44,12 @@ void AQH_Service_free(AQH_SERVICE *sv)
|
|||||||
{
|
{
|
||||||
if (sv) {
|
if (sv) {
|
||||||
GWEN_LIST_FINI(AQH_SERVICE, sv);
|
GWEN_LIST_FINI(AQH_SERVICE, sv);
|
||||||
|
GWEN_INHERIT_FINI(AQH_SERVICE, sv);
|
||||||
|
|
||||||
AQH_User_List_free(sv->userList);
|
AQH_User_List_free(sv->userList);
|
||||||
AQH_Module_List_free(sv->moduleList);
|
AQH_Module_List_free(sv->moduleList);
|
||||||
AQH_Session_List_free(sv->sessionList);
|
AQH_Session_List_free(sv->sessionList);
|
||||||
GWEN_INHERIT_FINI(AQH_SERVICE, sv);
|
|
||||||
GWEN_FREE_OBJECT(sv);
|
GWEN_FREE_OBJECT(sv);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -31,13 +31,21 @@
|
|||||||
</lang>
|
</lang>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
<defines>
|
||||||
|
<define id="AQH_SESSION_RTFLAGS" prefix="AQH_SESSION_RTFLAGS_">
|
||||||
|
<item name="MODIFIED" value="0x00000001" />
|
||||||
|
</define>
|
||||||
|
</defines>
|
||||||
|
|
||||||
|
|
||||||
<members>
|
<members>
|
||||||
|
|
||||||
<member name="uid" type="char_ptr" maxlen="64">
|
<member name="uid" type="char_ptr" maxlen="64">
|
||||||
<default>0</default>
|
<default>0</default>
|
||||||
<preset>0</preset>
|
<preset>0</preset>
|
||||||
<access>public</access>
|
<access>public</access>
|
||||||
<flags>with_getbymember</flags>
|
<flags>own with_getbymember</flags>
|
||||||
</member>
|
</member>
|
||||||
|
|
||||||
<member name="flags" type="uint32_t" maxlen="4">
|
<member name="flags" type="uint32_t" maxlen="4">
|
||||||
@@ -51,7 +59,7 @@
|
|||||||
<default>NULL</default>
|
<default>NULL</default>
|
||||||
<preset>NULL</preset>
|
<preset>NULL</preset>
|
||||||
<access>public</access>
|
<access>public</access>
|
||||||
<flags></flags>
|
<flags>own</flags>
|
||||||
</member>
|
</member>
|
||||||
|
|
||||||
<member name="state" type="int" maxlen="4">
|
<member name="state" type="int" maxlen="4">
|
||||||
@@ -65,7 +73,7 @@
|
|||||||
<default>0</default>
|
<default>0</default>
|
||||||
<preset>0</preset>
|
<preset>0</preset>
|
||||||
<access>public</access>
|
<access>public</access>
|
||||||
<flags></flags>
|
<flags>own</flags>
|
||||||
</member>
|
</member>
|
||||||
|
|
||||||
<member name="timestampCreation" type="gwen_timestamp" maxlen="8">
|
<member name="timestampCreation" type="gwen_timestamp" maxlen="8">
|
||||||
@@ -75,6 +83,13 @@
|
|||||||
<flags>own</flags>
|
<flags>own</flags>
|
||||||
</member>
|
</member>
|
||||||
|
|
||||||
|
<member name="timestampLastAccess" type="gwen_timestamp" maxlen="8">
|
||||||
|
<default>NULL</default>
|
||||||
|
<preset>NULL</preset>
|
||||||
|
<access>public</access>
|
||||||
|
<flags>own</flags>
|
||||||
|
</member>
|
||||||
|
|
||||||
|
|
||||||
<member name="user" type="AQH_USER">
|
<member name="user" type="AQH_USER">
|
||||||
<default>NULL</default>
|
<default>NULL</default>
|
||||||
@@ -85,6 +100,15 @@
|
|||||||
<flags>volatile nodup nocopy</flags>
|
<flags>volatile nodup nocopy</flags>
|
||||||
</member>
|
</member>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
<member name="runtimeFlags" type="uint32_t" maxlen="4">
|
||||||
|
<default>0</default>
|
||||||
|
<preset>0</preset>
|
||||||
|
<access>public</access>
|
||||||
|
<flags>with_flags volatile</flags>
|
||||||
|
</member>
|
||||||
|
|
||||||
</members>
|
</members>
|
||||||
|
|
||||||
</type>
|
</type>
|
||||||
|
|||||||
@@ -86,35 +86,35 @@
|
|||||||
<default>0</default>
|
<default>0</default>
|
||||||
<preset>0</preset>
|
<preset>0</preset>
|
||||||
<access>public</access>
|
<access>public</access>
|
||||||
<flags></flags>
|
<flags>own</flags>
|
||||||
</member>
|
</member>
|
||||||
|
|
||||||
<member name="alias" type="char_ptr" maxlen="16">
|
<member name="alias" type="char_ptr" maxlen="16">
|
||||||
<default>0</default>
|
<default>0</default>
|
||||||
<preset>0</preset>
|
<preset>0</preset>
|
||||||
<access>public</access>
|
<access>public</access>
|
||||||
<flags>with_getbymember</flags>
|
<flags>own with_getbymember</flags>
|
||||||
</member>
|
</member>
|
||||||
|
|
||||||
<member name="hashedPassword" type="char_ptr" maxlen="128">
|
<member name="hashedPassword" type="char_ptr" maxlen="128">
|
||||||
<default>0</default>
|
<default>0</default>
|
||||||
<preset>0</preset>
|
<preset>0</preset>
|
||||||
<access>public</access>
|
<access>public</access>
|
||||||
<flags></flags>
|
<flags>own</flags>
|
||||||
</member>
|
</member>
|
||||||
|
|
||||||
<member name="email" type="char_ptr" maxlen="128">
|
<member name="email" type="char_ptr" maxlen="128">
|
||||||
<default>0</default>
|
<default>0</default>
|
||||||
<preset>0</preset>
|
<preset>0</preset>
|
||||||
<access>public</access>
|
<access>public</access>
|
||||||
<flags></flags>
|
<flags>own</flags>
|
||||||
</member>
|
</member>
|
||||||
|
|
||||||
<member name="notes" type="char_ptr" maxlen="256">
|
<member name="notes" type="char_ptr" maxlen="256">
|
||||||
<default>0</default>
|
<default>0</default>
|
||||||
<preset>0</preset>
|
<preset>0</preset>
|
||||||
<access>public</access>
|
<access>public</access>
|
||||||
<flags></flags>
|
<flags>own</flags>
|
||||||
</member>
|
</member>
|
||||||
|
|
||||||
<member name="timestampCreation" type="gwen_timestamp" maxlen="8">
|
<member name="timestampCreation" type="gwen_timestamp" maxlen="8">
|
||||||
|
|||||||
16
vg_aqhomed.sh
Executable file
16
vg_aqhomed.sh
Executable file
@@ -0,0 +1,16 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
|
||||||
|
export AQHOME_LOGLEVEL=info
|
||||||
|
export LD_LIBRARY_PATH="0-build/aqhome/:$LD_LIBRARY_PATH"
|
||||||
|
|
||||||
|
valgrind \
|
||||||
|
--tool=memcheck --trace-children=yes -v --log-file=aqhomed.vg --leak-check=full --show-reachable=yes \
|
||||||
|
--track-origins=yes --num-callers=50 --keep-stacktraces=alloc-and-free \
|
||||||
|
0-build/apps/aqhomed/aqhomed \
|
||||||
|
-l aqhome.log \
|
||||||
|
-db aqhome.db \
|
||||||
|
-ma 192.168.117.192 -mp 1883 --mqttclientid=AQHOMELOGTEST \
|
||||||
|
-t 127.0.0.1 \
|
||||||
|
--pidfile=./aqhomed.pid \
|
||||||
|
-T 300
|
||||||
|
|
||||||
18
vg_mqttlog.sh
Executable file
18
vg_mqttlog.sh
Executable file
@@ -0,0 +1,18 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
|
||||||
|
export AQHOME_LOGLEVEL=info
|
||||||
|
export LD_LIBRARY_PATH="0-build/aqhome/:$LD_LIBRARY_PATH"
|
||||||
|
|
||||||
|
# valgrind --tool=memcheck --trace-children=yes -v --log-file=aqf15 --leak-check=full --show-reachable=yes --track-origins=yes --num-callers=50 --keep-stacktraces=alloc-and-free --suppressions=../../../../debug/valgrind.supp /usr/local/bin/aqfinance
|
||||||
|
|
||||||
|
# valgrind --tool=memcheck --trace-children=yes -v --log-file=aqhomed.vg --leak-check=full --show-reachable=yes --track-origins=yes --num-callers=50 --keep-stacktraces=alloc-and-free 0-build/apps/aqhomed/aqhomed -l aqhome.log -db aqhome.db -ma 192.168.117.192 -mp 1883 -t 127.0.0.1 -T 300
|
||||||
|
|
||||||
|
valgrind \
|
||||||
|
--tool=memcheck --trace-children=yes -v --log-file=aqhome-mqttlog.vg --leak-check=full --show-reachable=yes \
|
||||||
|
--track-origins=yes --num-callers=50 --keep-stacktraces=alloc-and-free \
|
||||||
|
0-build/apps/aqhome-mqttlog/aqhome-mqttlog \
|
||||||
|
-ma 192.168.117.192 -mp 1883 --mqttclientid=AQHOMEMQTTLOGTEST \
|
||||||
|
-W /tmp/aqhome/mqttlog \
|
||||||
|
-i apps/aqhome-mqttlog/mqttlog.conf \
|
||||||
|
-T 30
|
||||||
|
|
||||||
21
vg_storage.sh
Executable file
21
vg_storage.sh
Executable file
@@ -0,0 +1,21 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
|
||||||
|
export AQHOME_LOGLEVEL=info
|
||||||
|
export LD_LIBRARY_PATH="0-build/aqhome/:$LD_LIBRARY_PATH"
|
||||||
|
|
||||||
|
# valgrind --tool=memcheck --trace-children=yes -v --log-file=aqf15 --leak-check=full --show-reachable=yes --track-origins=yes --num-callers=50 --keep-stacktraces=alloc-and-free --suppressions=../../../../debug/valgrind.supp /usr/local/bin/aqfinance
|
||||||
|
|
||||||
|
# valgrind --tool=memcheck --trace-children=yes -v --log-file=aqhomed.vg --leak-check=full --show-reachable=yes --track-origins=yes --num-callers=50 --keep-stacktraces=alloc-and-free 0-build/apps/aqhomed/aqhomed -l aqhome.log -db aqhome.db -ma 192.168.117.192 -mp 1883 -t 127.0.0.1 -T 300
|
||||||
|
|
||||||
|
valgrind \
|
||||||
|
--tool=memcheck --trace-children=yes -v --log-file=aqhome-storage.vg --leak-check=full --show-reachable=yes \
|
||||||
|
--track-origins=yes --num-callers=50 --keep-stacktraces=alloc-and-free \
|
||||||
|
0-build/apps/aqhome-storage/aqhome-storage \
|
||||||
|
--sourcefolder=apps/aqhome-storage/test/html \
|
||||||
|
-D apps/aqhome-storage/test/config \
|
||||||
|
--statefile=apps/aqhome-storage/test/config/state \
|
||||||
|
-ma 192.168.117.192 -mp 1883 --mqttclientid=AQHOMESTORAGEVG \
|
||||||
|
-ha 127.0.0.1 -hp 1884 \
|
||||||
|
-p ./aqhome-storage.pid \
|
||||||
|
-T 90
|
||||||
|
|
||||||
Reference in New Issue
Block a user