diff --git a/src/common/lua/LuaXML_lib.c b/src/common/lua/LuaXML_lib.c
index 435dd57d1..ca4bea397 100644
--- a/src/common/lua/LuaXML_lib.c
+++ b/src/common/lua/LuaXML_lib.c
@@ -1,6 +1,8 @@
/**
LuaXML License
+https://github.com/LuaDist/luaxml
+
LuaXml is licensed under the terms of the MIT license reproduced below,
the same as Lua itself. This means that LuaXml is free software and can be
used for both academic and commercial purposes at absolutely no cost.
diff --git a/src/common/mongoose.c b/src/common/mongoose.c
index f80b4daf3..957623529 100644
--- a/src/common/mongoose.c
+++ b/src/common/mongoose.c
@@ -13,7 +13,7 @@
/* Amalgamated: #include "common/mg_mem.h" */
#ifndef MBUF_REALLOC
-#define MBUF_REALLOC MG_REALLOC
+#define MBUF_REALLOC MG_REALLOC
#endif
#ifndef MBUF_FREE
@@ -2834,7 +2834,6 @@ void mg_if_recv_udp_cb(struct mg_connection *nc, void *buf, int len,
} else {
/* Drop on the floor. */
MG_FREE(buf);
- nc->iface->vtable->recved(nc, len);
}
}
@@ -3451,8 +3450,11 @@ void mg_socket_if_connect_udp(struct mg_connection *nc) {
}
if (nc->flags & MG_F_ENABLE_BROADCAST) {
int optval = 1;
- setsockopt(nc->sock, SOL_SOCKET, SO_BROADCAST, (const char *) &optval,
- sizeof(optval));
+ if (setsockopt(nc->sock, SOL_SOCKET, SO_BROADCAST, (const char *) &optval,
+ sizeof(optval)) < 0) {
+ nc->err = mg_get_errno() ? mg_get_errno() : 1;
+ return;
+ }
}
nc->err = 0;
}
@@ -3914,10 +3916,16 @@ time_t mg_socket_if_poll(struct mg_iface *iface, int timeout_ms) {
/* A hack to make sure all our file descriptos fit into FD_SETSIZE. */
if (nc->sock >= (sock_t) FD_SETSIZE && try_dup) {
int new_sock = dup(nc->sock);
- if (new_sock >= 0 && new_sock < (sock_t) FD_SETSIZE) {
- closesocket(nc->sock);
- DBG(("new sock %d -> %d", nc->sock, new_sock));
- nc->sock = new_sock;
+ if (new_sock >= 0) {
+ if (new_sock < (sock_t) FD_SETSIZE) {
+ closesocket(nc->sock);
+ DBG(("new sock %d -> %d", nc->sock, new_sock));
+ nc->sock = new_sock;
+ } else {
+ closesocket(new_sock);
+ DBG(("new sock is still larger than FD_SETSIZE, disregard"));
+ try_dup = 0;
+ }
} else {
try_dup = 0;
}
@@ -8459,9 +8467,11 @@ size_t mg_parse_multipart(const char *buf, size_t buf_len, char *var_name,
size_t *data_len) {
static const char cd[] = "Content-Disposition: ";
size_t hl, bl, n, ll, pos, cdl = sizeof(cd) - 1;
+ int shl;
if (buf == NULL || buf_len <= 0) return 0;
- if ((hl = mg_http_get_request_len(buf, buf_len)) <= 0) return 0;
+ if ((shl = mg_http_get_request_len(buf, buf_len)) <= 0) return 0;
+ hl = shl;
if (buf[0] != '-' || buf[1] != '-' || buf[2] == '\n') return 0;
/* Get boundary length */
@@ -8835,6 +8845,7 @@ static void mg_prepare_cgi_environment(struct mg_connection *nc,
char *p;
size_t i;
char buf[100];
+ size_t path_info_len = path_info != NULL ? path_info->len : 0;
blk->len = blk->nvars = 0;
blk->nc = nc;
@@ -8866,7 +8877,7 @@ static void mg_prepare_cgi_environment(struct mg_connection *nc,
mg_conn_addr_to_str(nc, buf, sizeof(buf), MG_SOCK_STRINGIFY_PORT);
mg_addenv(blk, "SERVER_PORT=%s", buf);
- s = hm->uri.p + hm->uri.len - path_info->len - 1;
+ s = hm->uri.p + hm->uri.len - path_info_len - 1;
if (*s == '/') {
const char *base_name = strrchr(prog, DIRSEP);
mg_addenv(blk, "SCRIPT_NAME=%.*s/%s", (int) (s - hm->uri.p), hm->uri.p,
@@ -10849,8 +10860,7 @@ static void mg_mqtt_broker_handle_connect(struct mg_mqtt_broker *brk,
/* TODO(mkm): check header (magic and version) */
mg_mqtt_session_init(brk, s, nc);
- s->user_data = nc->user_data;
- nc->user_data = s;
+ nc->priv_2 = s;
mg_mqtt_add_session(s);
mg_mqtt_connack(nc, MG_EV_MQTT_CONNACK_ACCEPTED);
@@ -10858,7 +10868,7 @@ static void mg_mqtt_broker_handle_connect(struct mg_mqtt_broker *brk,
static void mg_mqtt_broker_handle_subscribe(struct mg_connection *nc,
struct mg_mqtt_message *msg) {
- struct mg_mqtt_session *ss = (struct mg_mqtt_session *) nc->user_data;
+ struct mg_mqtt_session *ss = (struct mg_mqtt_session *) nc->priv_2;
uint8_t qoss[MG_MQTT_MAX_SESSION_SUBSCRIPTIONS];
size_t num_subs = 0;
struct mg_str topic;
@@ -10936,18 +10946,18 @@ void mg_mqtt_broker(struct mg_connection *nc, int ev, void *data) {
struct mg_mqtt_broker *brk;
if (nc->listener) {
- brk = (struct mg_mqtt_broker *) nc->listener->user_data;
+ brk = (struct mg_mqtt_broker *) nc->listener->priv_2;
} else {
- brk = (struct mg_mqtt_broker *) nc->user_data;
+ brk = (struct mg_mqtt_broker *) nc->priv_2;
}
switch (ev) {
case MG_EV_ACCEPT:
if (nc->proto_data == NULL) mg_set_protocol_mqtt(nc);
- nc->user_data = NULL; /* Clear up the inherited pointer to broker */
+ nc->priv_2 = NULL; /* Clear up the inherited pointer to broker */
break;
case MG_EV_MQTT_CONNECT:
- if (nc->user_data == NULL) {
+ if (nc->priv_2 == NULL) {
mg_mqtt_broker_handle_connect(brk, nc);
} else {
/* Repeated CONNECT */
@@ -10955,7 +10965,7 @@ void mg_mqtt_broker(struct mg_connection *nc, int ev, void *data) {
}
break;
case MG_EV_MQTT_SUBSCRIBE:
- if (nc->user_data != NULL) {
+ if (nc->priv_2 != NULL) {
mg_mqtt_broker_handle_subscribe(nc, msg);
} else {
/* Subscribe before CONNECT */
@@ -10963,7 +10973,7 @@ void mg_mqtt_broker(struct mg_connection *nc, int ev, void *data) {
}
break;
case MG_EV_MQTT_PUBLISH:
- if (nc->user_data != NULL) {
+ if (nc->priv_2 != NULL) {
mg_mqtt_broker_handle_publish(brk, msg);
} else {
/* Publish before CONNECT */
@@ -10971,8 +10981,8 @@ void mg_mqtt_broker(struct mg_connection *nc, int ev, void *data) {
}
break;
case MG_EV_CLOSE:
- if (nc->listener && nc->user_data != NULL) {
- mg_mqtt_close_session((struct mg_mqtt_session *) nc->user_data);
+ if (nc->listener && nc->priv_2 != NULL) {
+ mg_mqtt_close_session((struct mg_mqtt_session *) nc->priv_2);
}
break;
}
@@ -11690,6 +11700,8 @@ int mg_resolve_async_opt(struct mg_mgr *mgr, const char *name, int query,
}
strncpy(req->name, name, sizeof(req->name));
+ req->name[sizeof(req->name) - 1] = '\0';
+
req->query = query;
req->callback = cb;
req->data = data;
diff --git a/src/vscp/common/devicethread.cpp b/src/vscp/common/devicethread.cpp
index f10e95ae6..d894b403b 100644
--- a/src/vscp/common/devicethread.cpp
+++ b/src/vscp/common/devicethread.cpp
@@ -353,7 +353,7 @@ void *deviceThread::Entry()
// * * * * Blocking version * * * *
if ( m_pCtrlObject->m_debugFlags1 & VSCP_DEBUG1_DRIVER ) {
- m_pCtrlObject->logMsg(_("[Device tread] Level I Blocking version."));
+ m_pCtrlObject->logMsg(_("[Device tread] Level I blocking version."));
}
/////////////////////////////////////////////////////////////////////////////
@@ -379,7 +379,7 @@ void *deviceThread::Entry()
}
if ( m_pCtrlObject->m_debugFlags1 & VSCP_DEBUG1_DRIVER ) {
- m_pCtrlObject->logMsg(_("[Device tread] Level I Write thread started."));
+ m_pCtrlObject->logMsg(_("[Device tread] Level I write thread started."));
}
/////////////////////////////////////////////////////////////////////////////
@@ -405,7 +405,7 @@ void *deviceThread::Entry()
}
if ( m_pCtrlObject->m_debugFlags1 & VSCP_DEBUG1_DRIVER ) {
- m_pCtrlObject->logMsg(_("[Device tread] Level I Receive thread started."));
+ m_pCtrlObject->logMsg(_("[Device tread] Level I receive thread started."));
}
// Just sit and wait until the end of the world as we know it...
@@ -414,7 +414,7 @@ void *deviceThread::Entry()
}
if ( m_pCtrlObject->m_debugFlags1 & VSCP_DEBUG1_DRIVER ) {
- m_pCtrlObject->logMsg(_("[Device tread] Level I Work loop ended."));
+ m_pCtrlObject->logMsg(_("[Device tread] Level I work loop ended."));
}
m_preceiveThread->m_bQuit = true;
diff --git a/src/vscp/common/duktape_vscp_func.cpp b/src/vscp/common/duktape_vscp_func.cpp
index 35e08143d..7a82a9403 100644
--- a/src/vscp/common/duktape_vscp_func.cpp
+++ b/src/vscp/common/duktape_vscp_func.cpp
@@ -653,6 +653,7 @@ duk_ret_t js_vscp_sendEvent( duk_context *ctx )
duk_push_boolean(ctx,0); // return code false
return JAVASCRIPT_OK;
}
+
duk_pop_n(ctx, 1);
// Send the event
@@ -662,6 +663,7 @@ duk_ret_t js_vscp_sendEvent( duk_context *ctx )
return JAVASCRIPT_OK;
}
+ pEvent->pdata = NULL;
vscp_convertVSCPfromEx( pEvent, &ex );
duk_push_global_object(ctx); /* -> stack: [ global ] */
diff --git a/src/vscp/common/lua_vscp_func.cpp b/src/vscp/common/lua_vscp_func.cpp
index 224586c25..50b51f881 100644
--- a/src/vscp/common/lua_vscp_func.cpp
+++ b/src/vscp/common/lua_vscp_func.cpp
@@ -315,6 +315,42 @@ int lua_vscp_base64_decode( struct lua_State *L )
}
+///////////////////////////////////////////////////////////////////////////////
+// lua_vscp_escapexml
+//
+// result = escapexml(string)
+//
+// TODO TODO TODO TODO TODO TODO TODO TODO TODO TODO TODO TODO TODO TODO TODO
+
+int lua_vscp_escapexml( struct lua_State *L )
+{
+ int nArgs = lua_gettop( L );
+
+ if ( 0 == nArgs ) {
+ return luaL_error( L, "vscp.escapexml: Wrong number of arguments: "
+ "vscp.escapexml( string-to-escape ) ");
+ }
+
+ // String to escape
+ if ( !lua_isstring( L, 1 ) ) {
+ return luaL_error( L, "vscp.readvariable: Argument error, string expected: "
+ "vscp.readvariable( \"name\"[,format] ) ");
+ }
+
+ size_t len;
+ const char *pstr = lua_tolstring ( L, 1, &len );
+
+ if ( !len ) {
+ lua_pushnil( L );
+ return 1;
+ }
+
+ // TODO
+
+ return 1;
+}
+
+
///////////////////////////////////////////////////////////////////////////////
// lua_vscp_readVariable
//
@@ -404,19 +440,46 @@ int lua_vscp_readVariable( struct lua_State *L )
}
// Get only value
else if ( 3 == format ) {
- // Get the variable value un encoded
- wxString strVal;
- strVal = variable.getValue();
- lua_pushlstring( L, (const char *)strVal.mbc_str(),
- strVal.Length() );
+ // Get the variable value
+ wxString strval = variable.getValue();
+ if ( variable.isNumerical() ) {
+ if ( VSCP_DAEMON_VARIABLE_CODE_INTEGER == variable.getType() ) {
+ int val = atoi( strval );
+ lua_pushinteger( L, val );
+ }
+ else if ( VSCP_DAEMON_VARIABLE_CODE_LONG == variable.getType() ) {
+ long val = atol( strval );
+ lua_pushnumber( L, val );
+ }
+ else if ( VSCP_DAEMON_VARIABLE_CODE_DOUBLE == variable.getType() ) {
+ double val;
+ strval.ToDouble( &val );
+ lua_pushnumber( L, val );
+ }
+ }
+ else {
+ if ( VSCP_DAEMON_VARIABLE_CODE_BOOLEAN == variable.getType() ) {
+ lua_pushboolean( L, variable.isTrue() );
+ }
+ else {
+
+ // Decode if needed
+ if ( variable.isValueBase64Encoded() ) {
+ vscp_base64_wxdecode( strval );
+ }
+
+ lua_pushlstring( L, (const char *)strval.mbc_str(),
+ strval.Length() );
+ }
+ }
}
// Get only note
else if ( 4 == format ) {
// Get the variable value un encoded
- wxString strVal;
- strVal = variable.getValue();
- lua_pushlstring( L, (const char *)strVal.mbc_str(),
- strVal.Length() );
+ wxString strval = variable.getValue();
+ vscp_base64_wxdecode( strval );
+ lua_pushlstring( L, (const char *)strval.mbc_str(),
+ strval.Length() );
}
else {
return luaL_error( L, "vscp.readvariable: Format must be 0=string, "
@@ -428,15 +491,13 @@ int lua_vscp_readVariable( struct lua_State *L )
///////////////////////////////////////////////////////////////////////////////
-// js_vscp_writeVariable
+// lua_vscp_writeVariable
//
-// writeVariable( value[, format])
+// writeVariable( value[,format])
//
// format = 0 - string
// format = 1 - XML
// format = 2 - JSON
-// format = 3 - Value
-// format = 4 . Note
//
int lua_vscp_writeVariable( struct lua_State *L )
@@ -477,14 +538,7 @@ int lua_vscp_writeVariable( struct lua_State *L )
format = (int)lua_tointeger( L, 2 );
}
-
- // Get Base64 flags
- if ( nArgs >= 3 ) {
- if ( lua_isboolean( L, 3 ) ) {
- bBase64 = lua_toboolean( L, 3 ) ? true : false;
- }
- }
-
+
if ( 0 == format ) {
// Set variable from string
if ( !variable.setVariableFromString( varValue ) ) {
@@ -506,19 +560,12 @@ int lua_vscp_writeVariable( struct lua_State *L )
" from JSON object.");
}
}
- else if ( 3 == format ) {
- // Set variable value
- variable.setValue( varValue, bBase64 );
- }
- else if ( 4 == format ) {
- // Set variable note
- variable.setNote( varValue, bBase64 );
- }
else {
return luaL_error( L, "vscp.writevariable: Format must be 0=string, "
- "1=XML, 2=JSON, 0=value, 3=note");
+ "1=XML, 2=JSON");
}
+ // Update or add variable if not defined
if ( !gpobj->m_variables.add( variable ) ) {
return luaL_error( L, "vscp.writevariable: Failed to update/add variable!");
}
@@ -530,21 +577,24 @@ int lua_vscp_writeVariable( struct lua_State *L )
///////////////////////////////////////////////////////////////////////////////
// lua_vscp_writeVariableValue
//
-// writeVariableValue( varname, value, bBase64)
+// writeVariableValue( varname, value[, bBase64])
//
//
int lua_vscp_writeVariableValue( struct lua_State *L )
{
+ size_t len;
+ const char *pstr;
+ bool bBase64 = false;
wxString varName;
wxString varValue;
CVSCPVariable variable;
int nArgs = lua_gettop( L );
- if ( nArgs < 3 ) {
+ if ( nArgs < 2 ) {
return luaL_error( L, "vscp.writeVariableValue: Wrong number of arguments: "
- "vscp.writeVariableValue( varname, varvalue, bBase64 ) ");
+ "vscp.writeVariableValue( varname, varvalue[, bBase64] ) ");
}
// variable name
@@ -553,36 +603,101 @@ int lua_vscp_writeVariableValue( struct lua_State *L )
"vscp.writeVariableValue( varname, varvalue, bBase64 ) ");
}
- size_t len;
- const char *pstr = lua_tolstring ( L, 1, &len );
+ pstr = lua_tolstring ( L, 1, &len );
varName = wxString::FromUTF8( pstr, len );
-
- // variable value
- if ( !lua_isstring( L, 2 ) ) {
- return luaL_error( L, "vscp.writeVariableValue: Argument error, string expected: "
- "vscp.writeVariableValue( varname, varvalue, bBase64 ) ");
- }
-
- pstr = lua_tolstring ( L, 2, &len );
- varValue = wxString::FromUTF8( pstr, len );
-
-
- // variable base64 flag
- bool bBase64 = false;
- if ( !lua_isboolean( L, 3 ) ) {
- return luaL_error( L, "vscp.writeVariableValue: Argument error, boolean expected: "
- "vscp.writeVariableValue( varname, varvalue, bBase64 ) ");
- }
-
- bBase64 = lua_toboolean ( L, 3 );
-
if ( !gpobj->m_variables.find( varName, variable ) ) {
return luaL_error( L, "vscp.writeVariableValue: No variable with that "
"name found!");
}
-
- variable.setValue( varValue, bBase64 );
+
+ // variable value
+ if ( variable.isNumerical() ) {
+
+ if ( VSCP_DAEMON_VARIABLE_CODE_INTEGER == variable.getType() ) {
+
+ int val;
+ if ( lua_isnumber( L, 2 ) ) {
+ val = lua_tointeger( L, 2 );
+ variable.setValue( val );
+ }
+ else if ( lua_isstring( L, 2 ) ) {
+ pstr = lua_tolstring ( L, 2, &len );
+ val = atoi( pstr );
+ variable.setValue( val );
+ }
+ else {
+ return luaL_error( L, "vscp.writeVariableValue: Value has "
+ "wrong format !");
+ }
+
+ }
+ else if ( VSCP_DAEMON_VARIABLE_CODE_LONG == variable.getType() ) {
+
+ long val;
+ if ( lua_isnumber( L, 2 ) ) {
+ val = lua_tonumber( L, 2 );
+ variable.setValue( val );
+ }
+ else if ( lua_isstring( L, 2 ) ) {
+ pstr = lua_tolstring ( L, 2, &len );
+ val = atol( pstr );
+ variable.setValue( val );
+ }
+
+ else {
+ return luaL_error( L, "vscp.writeVariableValue: Value has "
+ "wrong format !");
+ }
+
+ }
+ else if ( VSCP_DAEMON_VARIABLE_CODE_DOUBLE == variable.getType() ) {
+
+ double val;
+ if ( lua_isnumber( L, 2 ) ) {
+ val = lua_tonumber( L, 2 );
+ variable.setValue( val );
+ }
+ else if ( lua_isstring( L, 2 ) ) {
+ val = lua_tonumber( L, 2 );
+ variable.setValue( val );
+ }
+
+ else {
+ return luaL_error( L, "vscp.writeVariableValue: Value has "
+ "wrong format !");
+ }
+
+ }
+
+ }
+ else {
+
+ if ( VSCP_DAEMON_VARIABLE_CODE_BOOLEAN == variable.getType() ) {
+ bool bVal;
+ if ( lua_isboolean( L, 2 ) ) {
+ variable.setValue( lua_toboolean( L, 2 ) ? true : false );
+ }
+ else {
+ return luaL_error( L, "vscp.writeVariableValue: Value has "
+ "wrong format !");
+ }
+ variable.setValue( bVal );
+ }
+ else {
+ // This is a string type value
+
+ // variable base64 flag
+ if ( nArgs < 3 ) {
+ bBase64 = lua_toboolean ( L, 3 );
+ }
+
+ pstr = lua_tolstring ( L, 1, &len );
+ wxString str = wxString::FromUTF8( pstr, len );
+ variable.setValue( str, bBase64 );
+ }
+
+ }
if ( !gpobj->m_variables.update( variable ) ) {
return luaL_error( L, "vscp.writeVariableValue: Failed to update variable value!");
@@ -691,6 +806,185 @@ int lua_vscp_deleteVariable( struct lua_State *L )
}
+///////////////////////////////////////////////////////////////////////////////
+// lua_vscp_isVariableBase64Encoded
+//
+// isVariableBase64(name)
+//
+//
+
+int lua_vscp_isVariableBase64Encoded( struct lua_State *L )
+{
+ size_t len;
+ bool bBase64 = false;
+ wxString varName;
+ CVSCPVariable variable;
+
+ int nArgs = lua_gettop( L );
+
+ if ( 0 == nArgs ) {
+ return luaL_error( L, "vscp.isVariableBase64: Wrong number of arguments: "
+ "vscp.isVariableBase64( name ) ");
+ }
+
+ if ( nArgs >= 1 ) {
+
+ // variable name
+ if ( !lua_isstring( L, 1 ) ) {
+ return luaL_error( L, "vscp.isVariableBase64: Argument error, string expected: "
+ "vscp.isVariableBase64( name ) ");
+ }
+
+ const char *pstr = lua_tolstring ( L, 1, &len );
+ varName = wxString::FromUTF8( pstr, len );
+
+ }
+
+ if ( !gpobj->m_variables.find( varName, variable ) ) {
+ return luaL_error( L, "vscp.isVariableBase64: No variable with that "
+ "name found!");
+ }
+
+ lua_pushboolean( L, variable.isValueBase64Encoded() );
+
+ return 1;
+}
+
+
+///////////////////////////////////////////////////////////////////////////////
+// lua_vscp_isVariablePersistent
+//
+// isVariablePersistent(name)
+//
+//
+
+int lua_vscp_isVariablePersistent( struct lua_State *L )
+{
+ size_t len;
+ bool bBase64 = false;
+ wxString varName;
+ CVSCPVariable variable;
+
+ int nArgs = lua_gettop( L );
+
+ if ( 0 == nArgs ) {
+ return luaL_error( L, "vscp.isVariablePersistent: Wrong number of arguments: "
+ "vscp.isVariablePersistent( name ) ");
+ }
+
+ if ( nArgs >= 1 ) {
+
+ // variable name
+ if ( !lua_isstring( L, 1 ) ) {
+ return luaL_error( L, "vscp.isVariablePersistent: Argument error, string expected: "
+ "vscp.isVariablePersistent( name ) ");
+ }
+
+ const char *pstr = lua_tolstring ( L, 1, &len );
+ varName = wxString::FromUTF8( pstr, len );
+
+ }
+
+ if ( !gpobj->m_variables.find( varName, variable ) ) {
+ return luaL_error( L, "vscp.isVariablePersistent: No variable with that "
+ "name found!");
+ }
+
+ lua_pushboolean( L, variable.isPersistent() );
+
+ return 1;
+}
+
+
+///////////////////////////////////////////////////////////////////////////////
+// lua_vscp_isVariableNumerical
+//
+// isVariableNumerical(name)
+//
+//
+
+int lua_vscp_isVariableNumerical( struct lua_State *L )
+{
+ size_t len;
+ bool bBase64 = false;
+ wxString varName;
+ CVSCPVariable variable;
+
+ int nArgs = lua_gettop( L );
+
+ if ( 0 == nArgs ) {
+ return luaL_error( L, "vscp.isVariableNumerical: Wrong number of arguments: "
+ "vscp.isVariableNumerical( name ) ");
+ }
+
+ if ( nArgs >= 1 ) {
+
+ // variable name
+ if ( !lua_isstring( L, 1 ) ) {
+ return luaL_error( L, "vscp.isVariableNumerical: Argument error, string expected: "
+ "vscp.isVariableNumerical( name ) ");
+ }
+
+ const char *pstr = lua_tolstring ( L, 1, &len );
+ varName = wxString::FromUTF8( pstr, len );
+
+ }
+
+ if ( !gpobj->m_variables.find( varName, variable ) ) {
+ return luaL_error( L, "vscp.isVariableNumerical: No variable with that "
+ "name found!");
+ }
+
+ lua_pushboolean( L, variable.isNumerical() );
+
+ return 1;
+}
+
+
+///////////////////////////////////////////////////////////////////////////////
+// lua_vscp_isStockVariable
+//
+// isStockVariable(name)
+//
+//
+
+int lua_vscp_isStockVariable( struct lua_State *L )
+{
+ size_t len;
+ bool bBase64 = false;
+ wxString varName;
+ CVSCPVariable variable;
+
+ int nArgs = lua_gettop( L );
+
+ if ( 0 == nArgs ) {
+ return luaL_error( L, "vscp.isStockVariable: Wrong number of arguments: "
+ "vscp.isStockVariable( name ) ");
+ }
+
+ if ( nArgs >= 1 ) {
+
+ // variable name
+ if ( !lua_isstring( L, 1 ) ) {
+ return luaL_error( L, "vscp.isStockVariable: Argument error, string expected: "
+ "vscp.isStockVariable( name ) ");
+ }
+
+ const char *pstr = lua_tolstring ( L, 1, &len );
+ varName = wxString::FromUTF8( pstr, len );
+
+ }
+
+ if ( !gpobj->m_variables.find( varName, variable ) ) {
+ return luaL_error( L, "vscp.isStockVariable: No variable with that "
+ "name found!");
+ }
+
+ lua_pushboolean( L, variable.isStockVariable() );
+
+ return 1;
+}
+
///////////////////////////////////////////////////////////////////////////////
// lua_vscp_sendEvent
//
@@ -700,17 +994,6 @@ int lua_vscp_deleteVariable( struct lua_State *L )
// format = 1 - XML format.
// format = 2 - JSON format.
//
-// {
-// "time": "2017-01-13T10:16:02",
-// "head": 2,
-// "timestamp":50817,
-// "obid"; 123,
-// "class": 10,
-// "type": 8,
-// "guid": "00:00:00:00:00:00:00:00:00:00:00:00:00:01:00:02",
-// "data": [1,2,3,4,5,6,7],
-// }
-//
int lua_vscp_sendEvent( struct lua_State *L )
{
@@ -726,6 +1009,13 @@ int lua_vscp_sendEvent( struct lua_State *L )
lua_gettable (L, LUA_REGISTRYINDEX );
pClientItem = (CClientItem *)lua_touserdata( L, -1 );
+ nArgs = lua_gettop( L );
+
+ // Remove client item from stack
+ lua_pop( L, 1 );
+
+ nArgs = lua_gettop( L );
+
if ( NULL == pClientItem ) {
return luaL_error( L, "vscp.sendEvent: VSCP server client not found.");
}
@@ -756,17 +1046,20 @@ int lua_vscp_sendEvent( struct lua_State *L )
format = (int)lua_tointeger( L, 2 );
}
+ // String
if ( 0 == format ) {
if ( !vscp_setVscpEventExFromString( &ex, strEvent ) ) {
return luaL_error( L, "vscp.sendEvent: Failed to get VSCP event from string!");
}
}
+ // XML
else if ( 1 == format ) {
if ( !vscp_convertXMLToEventEx( strEvent, &ex ) ) {
return luaL_error( L, "vscp.sendEvent: Failed to get "
"VSCP event from XML!");
}
}
+ // JSON
else if ( 2 == format ) {
if ( !vscp_convertJSONToEventEx( strEvent, &ex ) ) {
return luaL_error( L, "vscp.sendEvent: Failed to get "
@@ -774,17 +1067,20 @@ int lua_vscp_sendEvent( struct lua_State *L )
}
}
- vscpEvent *pEvent;
+ vscpEvent *pEvent = new vscpEvent;
+ if ( NULL == pEvent ) {
+ return luaL_error( L, "vscp.sendEvent: Failed to "
+ "allocate VSCP event!");
+ }
+ pEvent->pdata = NULL;
vscp_convertVSCPfromEx( pEvent, &ex );
if ( !gpobj->sendEvent( pClientItem, pEvent ) ) {
// Failed to send event
- vscp_deleteVSCPevent( pEvent );
+ vscp_deleteVSCPevent_v2( &pEvent );
return luaL_error( L, "vscp.sendEvent: Failed to send event!");
}
- vscp_deleteVSCPevent( pEvent );
-
return 1;
}
@@ -792,6 +1088,8 @@ int lua_vscp_sendEvent( struct lua_State *L )
///////////////////////////////////////////////////////////////////////////////
// lua_vscp_getEvent
//
+// receiveevent([format])
+//
int lua_vscp_getEvent( struct lua_State *L )
{
@@ -802,6 +1100,14 @@ int lua_vscp_getEvent( struct lua_State *L )
int nArgs = lua_gettop( L );
+ // Get format - if given
+ if ( 0 != nArgs ) {
+
+ if ( !lua_isnumber( L, 1 ) ) {
+ format = (int)lua_tointeger( L, 1 );
+ }
+ }
+
// Get the client item
lua_pushlstring( L, "vscp_clientitem", 15 );
lua_gettable (L, LUA_REGISTRYINDEX );
@@ -811,10 +1117,7 @@ int lua_vscp_getEvent( struct lua_State *L )
return luaL_error( L, "vscp.getEvent: VSCP server client not found.");
}
- if ( 0 == nArgs ) {
- return luaL_error( L, "vscp.getEvent: Wrong number of arguments: "
- "vscp.getEvent( format ) ");
- }
+
try_again:
@@ -834,69 +1137,58 @@ int lua_vscp_getEvent( struct lua_State *L )
pClientItem->m_clientInputQueue.DeleteNode( nodeClient );
pClientItem->m_mutexClientInputQueue.Unlock();
- if ( NULL != pEvent ) {
-
- if ( vscp_doLevel2Filter( pEvent, &pClientItem->m_filterVSCP ) ) {
+ if ( NULL == pEvent ) {
+ return luaL_error( L, "vscp.getEvent: Allocation error when "
+ "getting event from client!");
+ }
- // Write it out
- wxString strResult;
- switch ( format ) {
- case 0: // String
- if ( !vscp_writeVscpEventToString( pEvent, strResult ) ) {
- return luaL_error( L,
- "vscp.getEvent: Failed to "
- "convert event to string form.");
- }
- break;
+ if ( vscp_doLevel2Filter( pEvent, &pClientItem->m_filterVSCP ) ) {
+
+ // Write it out
+ wxString strResult;
+ switch ( format ) {
+ case 0: // String
+ if ( !vscp_writeVscpEventToString( pEvent, strResult ) ) {
+ return luaL_error( L,
+ "vscp.getEvent: Failed to "
+ "convert event to string form.");
+ }
+ break;
- case 1: // XML
- if ( !vscp_convertEventToXML( pEvent, strResult ) ) {
- return luaL_error( L,
- "vscp.getEvent: Failed to "
- "convert event to XML form.");
- }
- break;
+ case 1: // XML
+ if ( !vscp_convertEventToXML( pEvent, strResult ) ) {
+ return luaL_error( L,
+ "vscp.getEvent: Failed to "
+ "convert event to XML form.");
+ }
+ break;
- case 2: // JSON
- if ( !vscp_convertEventToJSON( pEvent, strResult ) ) {
- return luaL_error( L,
- "vscp.getEvent: Failed to "
- "convert event to JSON form.");
- }
- break;
- }
-
- // Event is not needed anymore
- vscp_deleteVSCPevent( pEvent );
-
- lua_pushlstring( L,
- (const char *)strResult.mbc_str(),
- strResult.Length() );
-
- // All OK return event
- return 1;
-
+ case 2: // JSON
+ if ( !vscp_convertEventToJSON( pEvent, strResult ) ) {
+ return luaL_error( L,
+ "vscp.getEvent: Failed to "
+ "convert event to JSON form.");
+ }
+ break;
}
- else {
-
- // Filtered out
- vscp_deleteVSCPevent( pEvent );
- goto try_again;
- }
-
- // Remove the event
+ // Event is not needed anymore
vscp_deleteVSCPevent( pEvent );
+
+ lua_pushlstring( L,
+ (const char *)strResult.mbc_str(),
+ strResult.Length() );
+
+ // All OK return event
+ return 1;
} // Valid pEvent pointer
- else {
- // NULL event
- lua_pushnil( L ); // return code failure
- return 1;
- }
+
} // events available
+ // No events available
+ lua_pushnil( L );
return 1;
}
@@ -904,6 +1196,7 @@ int lua_vscp_getEvent( struct lua_State *L )
///////////////////////////////////////////////////////////////////////////////
// lua_vscp_getCountEvent
//
+// cnt = vscp.countevents()
//
int lua_vscp_getCountEvent( struct lua_State *L )
@@ -999,7 +1292,7 @@ int lua_vscp_setFilter( struct lua_State *L )
switch ( format ) {
case 0:
- if ( !vscp_readFilterFromString( &filter, strFilter ) ) {
+ if ( !vscp_readFilterMaskFromString( &filter, strFilter ) ) {
luaL_error( L, "vscp.setFilter: Failed to read filter!");
}
break;
@@ -1295,7 +1588,7 @@ int lua_send_Measurement( struct lua_State *L )
///////////////////////////////////////////////////////////////////////////////
// lua_is_Measurement
//
-// event,format
+// result = ismeasurement(event,format)
//
// format = 0 - String format.
// format = 1 - XML format.
diff --git a/src/vscp/common/lua_vscp_func.h b/src/vscp/common/lua_vscp_func.h
index fdec69346..f73347b8e 100644
--- a/src/vscp/common/lua_vscp_func.h
+++ b/src/vscp/common/lua_vscp_func.h
@@ -102,30 +102,43 @@ int lua_vscp_readVariable( struct lua_State *L );
*
* vscp.readvariable( "name"[, format ] )
*
- * Lua Parameter 1: Variable name
+ * Lua Parameter 1: variable
* Lua Parameter 2: Optional format
- * Lua: Return: True if variable got updated/added.
+ * Lua: Return: 1 on success.
*
- * @param v7 Pointer to v7 object.
- * @param res Pointer to JSON object or NULL if variable was not found.
- * @return v7 error code.
*/
int lua_vscp_writeVariable( struct lua_State *L );
+/*!
+ * Write remote variable value
+ *
+ * Lua Parameter 1: variable name
+ * Lua Parameter 2: variable value
+ * Lua Parameter 3: OPTIONAL Flag for BASE64 coding of value.
+ * Lua: Return: 1 on success.
+ *
+ */
+int lua_vscp_writeVariableValue( struct lua_State *L );
+
/*!
* Delete VSCP variable
*
* Lua Parameter 0: ClientItem
* Lua Parameter 1: Name of variable
- * Lua: Return: True if variable got deleted.
+ * Lua: Return: 1 on success.
*
- * @param v7 Pointer to v7 object.
- * @param res Pointer to JSON object or NULL if variable was not found.
- * @return v7 error code.
*/
int lua_vscp_deleteVariable( struct lua_State *L );
+int lua_vscp_isVariableBase64Encoded( struct lua_State *L ) ;
+
+int lua_vscp_isVariablePersistent( struct lua_State *L );
+
+int lua_vscp_isVariableNumerical( struct lua_State *L );
+
+int lua_vscp_isStockVariable( struct lua_State *L );
+
/*!
* Send VSCP event on the local client queue
*
diff --git a/src/vscp/common/lua_vscp_wrkthread.cpp b/src/vscp/common/lua_vscp_wrkthread.cpp
index dc73de0fc..f3b562a0d 100644
--- a/src/vscp/common/lua_vscp_wrkthread.cpp
+++ b/src/vscp/common/lua_vscp_wrkthread.cpp
@@ -200,11 +200,17 @@ void *actionThread_Lua::Entry()
web_reg_function( L, "readvariable", lua_vscp_readVariable );
web_reg_function( L, "writevariable", lua_vscp_writeVariable );
+ web_reg_function( L, "writevariablevalue", lua_vscp_writeVariableValue );
web_reg_function( L, "deletevariable", lua_vscp_deleteVariable );
+
+ web_reg_function( L, "isVariableBase64Encoded", lua_vscp_isVariableBase64Encoded );
+ web_reg_function( L, "isVariablePersistent", lua_vscp_isVariablePersistent );
+ web_reg_function( L, "isVariableNumerical", lua_vscp_isVariableNumerical );
+ web_reg_function( L, "isStockVariable", lua_vscp_isStockVariable );
web_reg_function( L, "sendevent", lua_vscp_sendEvent );
- web_reg_function( L, "getevent", lua_vscp_getEvent );
- web_reg_function( L, "getcountevent", lua_vscp_getCountEvent );
+ web_reg_function( L, "receiveevent", lua_vscp_getEvent );
+ web_reg_function( L, "countevent", lua_vscp_getCountEvent );
web_reg_function( L, "setfilter", lua_vscp_setFilter );
web_reg_function( L, "ismeasurement", lua_is_Measurement );
@@ -302,7 +308,7 @@ void *actionThread_Lua::Entry()
(const char *)m_wxstrScript.mbc_str() );
gpobj->logMsg( strError, DAEMON_LOGMSG_NORMAL, DAEMON_LOGTYPE_DM );
- return NULL;
+ return NULL;
}
// The script file is loaded, now call it
diff --git a/src/vscp/common/remotevariable.cpp b/src/vscp/common/remotevariable.cpp
index a6acc7545..374e58e55 100644
--- a/src/vscp/common/remotevariable.cpp
+++ b/src/vscp/common/remotevariable.cpp
@@ -196,9 +196,10 @@ uint16_t CVSCPVariable::getVariableTypeFromString( const wxString& strVariableTy
wxString str = strVariableType;
long val;
- if ( str.IsNumber() ) {
- str.ToLong( &val, 10 );
- type = val;
+ if ( str.IsNumber() ||
+ str.StartsWith(_("0x")) ||
+ str.StartsWith(_("0X")) ) {
+ type = vscp_readStringValue( str );
}
else {
str.Trim();
@@ -585,7 +586,7 @@ bool CVSCPVariable::setFromJSON( wxString &strVariable )
}
if (j.find("user") != j.end()) {
- m_userid = j.at("userid").get
"
+// The JSON text CLASS1.MEASUREMENTL, Type= Temperature,6 sensorindex=0, unit=1 (Celsius)
+// 45.464 degrees Celsius
+var eventTxt = "{ 'class': 10, 'type': 6, 'data': [0x48,0x34,0x35,0x2E,0x34,0x36,0x34] }";
+
+// Make the JSON object
+var event = JSON.parse( eventTxt );
+
+if ( null != ( value = vscp_getMeasurementValue( event ) ) ) {
+ vscp_log("Measurement event sent successfully! value = " + value.toString() + "\n");
+}
+else {
+ vscp_log("This is not a measurement event!\n");
+}
+
+
+-----------------------------------------
+
+
+==== Example ====
+
+Will output Unit = 1.
+
+
+// The JSON text CLASS1.MEASUREMENTL, Type= Temperature,6 sensorindex=1, unit=1 (Celsius)
+// 45.464 degrees Celsius
+var eventTxt = "{ 'class': 10, 'type': 6, 'data': [0x49,0x34,0x35,0x2E,0x34,0x36,0x34] }";
+
+// Make the JSON object
+var event = JSON.parse( eventTxt );
+
+vscp_log("Unit = " + vscp_getMeasurementUnit( event ).toString() + "\n");
+
+
+
+------------------------------------------
+
+==== Example ====
+
+Will output sensorindex = 1.
+
+
+// The JSON text CLASS1.MEASUREMENTL, Type= Temperature,6 sensorindex=1, unit=1 (Celsius)
+// 45.464 degrees Celsius
+var eventTxt = "{ \"class\": 10, \"type\": 6, \"data\": [0x49,0x34,0x35,0x2E,0x34,0x36,0x34] }";
+
+// Make the JSON object
+var event = JSON.parse( eventTxt );
+
+vscp_log("Sensor index = " + vscp_getMeasurementSensorIndex( event ).toString() + "\n");
+
+
+
+--------------------------------------------
+
+
+==== Example ====
+
+Will output Zone = 0.
+
+
+// The JSON text CLASS1.MEASUREMENTL, Type= Temperature,6 sensorindex=1, unit=1 (Celsius)
+// 45.464 degrees Celsius
+var eventTxt = "{ \"class\": 10, \"type\": 6, \"data\": [0x49,0x34,0x35,0x2E,0x34,0x36,0x34] }";
+
+// Make the JSON object
+var event = JSON.parse( eventTxt );
+
+vscp_log("Zone = " + vscp.getmeasurementzone( event ).toString() + "\n");
+
+
+
+---------------------------------------------
+
+
+==== Example ====
+
+Will output Subzone = 0.
+
+
+// The JSON text CLASS1.MEASUREMENTL, Type= Temperature,6 sensorindex=1, unit=1 (Celsius)
+// 45.464 degrees Celsius
+var eventTxt = "{ \"class\": 10, \"type\": 6, \"data\": [0x49,0x34,0x35,0x2E,0x34,0x36,0x34] }";
+
+// Make the JSON object
+var event = JSON.parse( eventTxt );
+
+vscp_log("Subzone = " + vscp_getMeasurementSubZone( event ).toString() + "\n");
+
+
+
+
+
+
+