changed debug to libUDPTCPNetwork and trying to fix some stuff.

master
Steffen Pohle 2 months ago
parent 519b59e215
commit bf6df35874

@ -16,23 +16,20 @@ LDFLAGS_CGI= -lm -lc -lpthread -L/usr/local/lib -g -ggdb
DEPENDFILE=.depend
TARGET=modelbahn-server
SERVEROBJ=server.o network.o session.o server-loadsave.o debug.o \
json.o main.o sensor.o turnout.o railway.o interfaces.o locomotive.o \
SERVEROBJ=server.o network.o session.o server-loadsave.o \
main.o sensor.o turnout.o railway.o interfaces.o locomotive.o \
block.o interface.o interface-z21.o
CURDIR=`pwd`
all: dep $(TARGET) test-json modelbahn-cgi
all: dep $(TARGET) modelbahn-cgi
modelbahn-server: $(SERVEROBJ)
$(CXX) -o $@ $^ $(LDFLAGS) -lUDPTCPNetwork -L./ -I./ -lpthread
modelbahn-cgi: modelbahn-cgi.o debug.o
modelbahn-cgi: modelbahn-cgi.o
$(CXX) -o $@ $^ $(LDFLAGS_CGI) -lUDPTCPNetwork -L./ -I./ -lpthread
test-json: json.o test-json.o debug.o
$(CXX) -o $@ $^ $(LDFLAGS) -L./ -I./ -lpthread
install: $(TARGET)
cp -f $(TARGET) $(PREFIX)/lib/

@ -218,7 +218,7 @@ int Blocks::SetOff(string blname) {
if ((bl = FindBlock(blname)) != NULL) {
changed = 1;
bl->flags |= BLOCK_F_OFF;
debug (0, "Blocks::SetOff block %s", bl->name);
debug ("block %s", bl->name);
jp.AddObject("block",_GetJSON(bl));
if(network) network->ChangeListPushToAll(jp.ToString());
@ -255,7 +255,7 @@ int Blocks::SetLockedby (string blname, string lockedby, int lock_onoff) {
int res = -1;
int x, y, cnt;
debug (0, "Blocks::SetLockedby block:'%s' locked for '%s' locked:%d", blname.c_str(), lockedby.c_str(), lock_onoff);
debug ("block:'%s' locked for '%s' locked:%d", blname.c_str(), lockedby.c_str(), lock_onoff);
Lock();
if ((bl = FindBlock(blname)) != NULL) {
@ -274,12 +274,12 @@ int Blocks::SetLockedby (string blname, string lockedby, int lock_onoff) {
res = 1;
}
else {
debug (0, "Blocks::SetLockedby could not set block '%s' for '%s'. Is used by '%s'.", blname.c_str(),lockedby.c_str(), bl->lockedby);
debug ("could not set block '%s' for '%s'. Is used by '%s'.", blname.c_str(),lockedby.c_str(), bl->lockedby);
res = 0;
}
}
else {
debug (0, "Blocks::SetLockedby could not find block '%s'.", blname.c_str());
debug ("could not find block '%s'.", blname.c_str());
}
UnLock();
@ -342,7 +342,7 @@ int Blocks::Clear(string name) {
if ((bl = FindBlock(name)) != NULL) {
changed = 1;
bl->flags &= ~BLOCK_F_OFF;
printf ("%s:%d clear block %s off", __FILE__, __LINE__, bl->name);
debug ("clear block %s off", bl->name);
UnLock();
return 1;
}
@ -398,7 +398,7 @@ int Blocks::GetBlocksPtr (string blname, Block **b1, Block **b2) {
}
if ((*b1) == NULL) {
debug (0, "Blocks::%s Could not find block: %s", __FUNCTION__, blname.c_str());
debug ("Could not find block: %s", blname.c_str());
return 0;
}
@ -407,7 +407,7 @@ int Blocks::GetBlocksPtr (string blname, Block **b1, Block **b2) {
(*b2) = &blocks[i];
}
if ((*b2) == NULL) {
debug (0, "Blocks::%s Could not find second block: %s", __FUNCTION__, (*b1)->secondblock);
debug ("Could not find second block: %s", (*b1)->secondblock);
return 0;
}
}

@ -1,73 +0,0 @@
// #define _GNU_SOURCE /* See feature_test_macros(7) */
#include <stdarg.h>
#include <stdio.h>
#include <stdlib.h>
#include <execinfo.h>
#include <unistd.h>
#include <time.h>
#include <sys/syscall.h>
#include <sys/types.h>
#include <sys/time.h>
#include "modelbahn.h"
#define DEBUG_FILE "/tmp/modelbahn-server.log"
#define LEN_TEXT 256
int _debuglevel = 0xff;
pid_t gettid();
void debug (int type, char *fmt,...) {
va_list args;
char texttime[LEN_TEXT];
char text1[DEBUG_TEXT1LEN];
char text2[DEBUG_TEXT2LEN];
pid_t pid = gettid();
int tms;
struct timeval tv;
struct tm tmp;
struct tm *tmptr = NULL;
va_start (args, fmt);
vsnprintf (text1, (DEBUG_TEXT1LEN-1), fmt, args);
va_end (args);
texttime[0] = 0;
text1[DEBUG_TEXT1LEN-1] = 0;
text2[DEBUG_TEXT2LEN-1] = 0;
gettimeofday (&tv, NULL);
tmptr = localtime_r(&tv.tv_sec, &tmp);
if (tmptr != NULL)
strftime(texttime, LEN_TEXT, "%H:%M:%S", &tmp);
if (type > 0) snprintf (text2, DEBUG_TEXT2LEN-1, "(%d, %s.%03d) %d : %s", pid, texttime, tv.tv_usec/1000, type, text1);
else snprintf (text2, DEBUG_TEXT2LEN-1, "(%d, %s.%03d) : %s", pid, texttime, tv.tv_usec/1000, text1);
if (type == 0 || (type & _debuglevel) != 0) {
FILE *f;
printf ("%s\n", text2);
f= fopen(DEBUG_FILE, "a");
if (f) {
fprintf (f, "%s\n", text2);
fclose (f);
}
}
};
/*******************************************************************************************
* helper stuff
*******************************************************************************************/
//
// return the current thread process id
//
pid_t gettid() {
pid_t tid = 0;
tid = syscall(SYS_gettid);
return tid;
};

@ -1,22 +0,0 @@
#ifndef _DEBUG_H_
#define _DEBUG_H_
#define DEBUG_INFO 0x0001
#define DEBUG_ERROR 0x0002
#define DEBUG_IFACE 0x0004
#define DEBUG_NET 0x0008
#define DEBUG_SESSION 0x0010
#define DEBUG_SERVER 0x0020
#define DEBUG_RAILWAY 0x0040
#define DEBUG_LOCO 0x0080
#define DEBUG_TEXT1LEN 64000
#define DEBUG_TEXT2LEN 65000
void debug(int type, char *fmt,...);
#endif // _DEBUG_H_

@ -33,8 +33,6 @@ static unsigned char RX_RMBUS_DATACHANGED[] { 0x0F, 0x00, 0x80, 0x00 };
#define Z21_IDX_SETTURNOUT_CHK 8
InterfaceZ21::InterfaceZ21 () {
debug (DEBUG_INFO | DEBUG_IFACE, "InterfaceZ21:%s", __FUNCTION__);
status_connected = false;
status_poweron = false;
status_programmingmode = false;
@ -59,13 +57,12 @@ InterfaceZ21::~InterfaceZ21() {
void InterfaceZ21::Connect () {
debug (DEBUG_INFO | DEBUG_IFACE, "InterfaceZ21: Connect %s to: %s", name, host);
debug ("Connect %s to: %s", name, host);
if (status_connected) Disconnect();
if (udp.Listen(0) == 0) {
debug (DEBUG_ERROR | DEBUG_IFACE, "%s:%d Error could not bind UDP socket (%s)",
__FILE__, __LINE__, strerror(errno));
debug ("Error could not bind UDP socket (%s)", strerror(errno));
return;
}
udp.SetBlocked(1);
@ -116,7 +113,7 @@ int InterfaceZ21::Loop() {
//
// Z21 timed out? close all connection
if ((timeout + 2 * INTF_Z21_TIMEOUT) < curtime) {
debug (DEBUG_ERROR | DEBUG_IFACE, "%s:%d connection timed out (%d)", __FILE__, __LINE__, curtime-(timeout + 2 * INTF_Z21_TIMEOUT));
debug ("connection timed out (%d)", curtime-(timeout + 2 * INTF_Z21_TIMEOUT));
Disconnect();
needs_update = true;
}
@ -144,7 +141,7 @@ int InterfaceZ21::Loop() {
if ((inlen = udp.ReadTimeout(&source, inbuffer, INTF_Z21_INBUFFER, 10)) > 0) {
//
// got some data
debug (DEBUG_INFO | DEBUG_IFACE, "%s:%d [%s] got some data.", __FILE__, __LINE__, name);
debug ("Name:%s got some data.", name);
//
// check for LAN_SYSTEMSTATE_DATACHANGED
if (memcmp (inbuffer, RX_GET_SERIAL_NUMBER, sizeof(RX_GET_SERIAL_NUMBER)) == 0) {
@ -158,7 +155,7 @@ int InterfaceZ21::Loop() {
// got turnout information
int addr = 0;
addr = ((unsigned char)inbuffer[Z21_IDX_SETTURNOUT_ADRH] << 8) + (unsigned char)inbuffer[Z21_IDX_SETTURNOUT_ADRL];
debug (0, "%s:%d Interface-Z21: TurnoutInformation Addr:%d", __FILE__, __LINE__, addr);
debug ("TurnoutInformation Addr:%d", addr);
if (inbuffer[Z21_IDX_SETTURNOUT_MODE] == 2)
server->TurnoutAddrMode(name, addr, 1);
@ -179,7 +176,7 @@ int InterfaceZ21::Loop() {
status_shortcircuit = (cs & INTF_Z21_CS_ShortCircuit);
status_programmingmode = (cs & INTF_Z21_CS_ProgModeActive);
debug (0, "%s:%d Name:%s cs:%d csex:%d", __FILE__, __LINE__, name, cs, csex);
debug ("Name:%s cs:%d csex:%d", name, cs, csex);
needs_update = true;
//if ( old_poweron != status_poweron ||
@ -194,12 +191,7 @@ int InterfaceZ21::Loop() {
//Got some Data:08:00:a1:00:a0:02:55:08:
else if (memcmp (inbuffer+1, RX_LOCONET_Z21_TX, sizeof (RX_LOCONET_Z21_TX)) == 0) {
int loconetopc = (unsigned char)inbuffer[4];
printf ("%s:%d Got some LOCONET (%x) Data:", __FILE__, __LINE__, loconetopc);
for (i = 0; i < inlen; i++) {
int z = (unsigned char) inbuffer[i];
printf ("i:%d %02x:", i, z);
}
printf ("\n");
debug ("Got some LOCONET (%d) data", loconetopc);
//
//
@ -211,11 +203,11 @@ int InterfaceZ21::Loop() {
if (inloc >= 0 && inloc <= INTF_Z21_LOCONET_MAXADDR) {
if (loconet_last.addr) {
debug (0, "%s:%d loconet_lastaddr:%d", __FILE__, __LINE__, loconet_last.addr);
debug ("loconet_lastaddr:%d", loconet_last.addr);
loconet_map[inloc].addr = loconet_last.addr;
}
debug (0, "%s:%d Loc:%d Speed:%d", __FILE__, __LINE__, loconet_map[inloc].addr, inspeed);
debug ("Loc:%d Speed:%d", loconet_map[inloc].addr, inspeed);
if (loconet_map[inloc].addr > 0) {
int speed = inspeed;
server->LocomotiveAddrSpeed(name, loconet_map[inloc].addr, speed);
@ -232,10 +224,10 @@ int InterfaceZ21::Loop() {
if (inloc >= 0 && inloc <= INTF_Z21_LOCONET_MAXADDR) {
if (loconet_last.addr) loconet_map[inloc] = loconet_last;
debug (0, "%s:%d Loc:%d Function:%d", __FILE__, __LINE__, loconet_map[inloc].addr, infunc);
debug ("Loc:%d Function:%d", loconet_map[inloc].addr, infunc);
}
debug (0, "%s:%d Loc:%d Function:%d", __FILE__, __LINE__, loconet_map[inloc].addr, infunc);
debug ("Loc:%d Function:%d", loconet_map[inloc].addr, infunc);
if (loconet_map[inloc].addr > 0) {
server->LocomotiveAddrFunction(name, loconet_map[inloc].addr, infunc);
}
@ -250,11 +242,7 @@ int InterfaceZ21::Loop() {
int group = (unsigned char)inbuffer[4];
int idx;
printf ("LAN_RMBUS_DATA_CHANGE[%s] ", name);
for (idx = 0; idx < INTF_Z21_RMSENSOR_BYTES * INTF_Z21_RMSENSOR_GROUPS; idx++) {
printf ("%x ", (unsigned char) inbuffer[4+idx]);
}
printf ("\n");
debug ("LAN_RMBUS_DATA_CHANGE[%s] ", name);
// groupindex (first or last 10 bytes)
unsigned char rmsold[INTF_Z21_RMSENSOR_BYTES * INTF_Z21_RMSENSOR_GROUPS];
@ -267,7 +255,7 @@ int InterfaceZ21::Loop() {
for (idx = 0; idx < INTF_Z21_RMSENSOR_GROUPS*INTF_Z21_RMSENSOR_BYTES; idx++) {
if (rmsold[idx]^rmsensors[idx]) {
for (i = 0; i < 8; i++) if (rmsensorinit || (rmsold[idx] & 1 << i) != (rmsensors[idx] & 1 << i)) {
debug (0, "Sendor Data Changed: %s[%d]", name, idx*8+i);
debug ("Sendor Data Changed: %s[%d]", name, idx*8+i);
if (rmsensors[idx] & 1 << i) server->SensorAddrChange(name, idx*8+i, 1);
else server->SensorAddrChange(name, idx*8+i, 0);
}
@ -278,18 +266,12 @@ int InterfaceZ21::Loop() {
}
else {
printf ("InterfaceZ21(%s) Got some Data:", name);
for (i = 0; i < inlen; i++) {
int z = (unsigned char) inbuffer[i];
printf ("%02x:", z);
}
printf ("\n");
debug ("InterfaceZ21(%s) Got some Data", name);
}
}
else if (inlen < 0) {
if (errno != EAGAIN && errno != EWOULDBLOCK) {
debug (DEBUG_ERROR | DEBUG_IFACE, "%s:%d error on reading (%s)",
__FILE__, __LINE__, strerror(errno));
debug ("error on reading (%s)", strerror(errno));
}
}
}
@ -344,7 +326,7 @@ void InterfaceZ21::send_LOGOFF() {
void InterfaceZ21::SetLocoSpeed(Locomotive *l, int step) {
unsigned char buffer[] = { 0x0A, 0x00, 0x40, 0x00, 0xE4, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00 };
debug (0, "%s:%d InterfaceZ21::SetLocoSpeed step:%d", __FILE__, __LINE__, step);
debug ("loco_addr:%d step:%d", l->addr, step);
//
// reverse?
@ -390,12 +372,6 @@ void InterfaceZ21::SetLocoSpeed(Locomotive *l, int step) {
for (int i = 4; i < (int) sizeof (buffer)-1; i++)
buffer[Z21_IDX_SETLOCO_DRIVE_CHK] = (unsigned char)buffer[Z21_IDX_SETLOCO_DRIVE_CHK] xor (unsigned char)buffer[i];
printf ("Send Data:");
for (int i = 0; i < (int)sizeof (buffer); i++) {
int z = (unsigned char) buffer[i];
printf ("%02x:", z);
}
printf ("\n");
udp.Write(host, (char*)buffer, sizeof (buffer));
loconet_last.addr = l->addr;
loconet_last.dir = l->flags & LOCO_F_REVERSE;
@ -408,7 +384,7 @@ void InterfaceZ21::SetLocoSpeed(Locomotive *l, int step) {
//
// Set Locomotive Function
void InterfaceZ21::SetLocoFunction(Locomotive *l, int func, int value) {
debug (0, "%s:%d InterfaceZ21::SetLocoFunction", __FILE__, __LINE__);
debug ("InterfaceZ21::SetLocoFunction **** NOT IMPLEMENTED YET ****");
};
@ -417,12 +393,11 @@ void InterfaceZ21::SetLocoFunction(Locomotive *l, int func, int value) {
void InterfaceZ21::SetTurnout(Turnout *t, int activate, int outputactive) {
unsigned char buffer[] = { 0x09, 0x00, 0x40, 0x00, 0x53, 0x00, 0x00, 0x00, 0x00 };
debug (DEBUG_INFO | DEBUG_IFACE, "InterfaceZ21 (%s) SetTurnout Addr:%d Acitve:%d Output:%d", name,
t->addr, activate, outputactive);
debug ("InterfaceZ21 (%s) SetTurnout Addr:%d Acitve:%d Output:%d", name, t->addr, activate, outputactive);
//
//
if (outputactive == 1 && timer_get(&turnouttimeout) < 100) {
debug (0, "%s:%d Interface need to wait between two turnout commands", __FILE__, __LINE__);
debug ("Interface need to wait between two turnout commands");
return;
}
timer_start(&turnouttimeout);
@ -459,7 +434,7 @@ void InterfaceZ21::SetTurnout(Turnout *t, int activate, int outputactive) {
// send_X_SET_TRACK_POWER_ON(); send_X_SET_TRACK_POWER_ON();
void InterfaceZ21::PowerOnOff(int onoff) {
if (status_connected == false) return;
debug (DEBUG_INFO | DEBUG_IFACE, "InterfaceZ21::PowerOnOff onoff:%d", onoff);
debug ("onoff:%d", onoff);
if (onoff) {
udp.Write(host, (char*)TX_X_SET_TRACK_POWER_ON, sizeof (TX_X_SET_TRACK_POWER_ON));
}

@ -10,8 +10,6 @@
// **************************************************************************
Interface::Interface() {
debug (DEBUG_INFO | DEBUG_IFACE, "Interface:%s", __FUNCTION__);
name[0] = 0;
host[0] = 0;
flags = 0;
@ -24,17 +22,17 @@ Interface::~Interface() {
void Interface::Connect () {
debug (DEBUG_INFO | DEBUG_IFACE, "* Interface (%s) Connect to %s", name, host);
debug ("Interface (%s) Connect to %s **** VIRTUAL NOT IMPLEMENTED ****", name, host);
};
void Interface::Disconnect() {
debug (DEBUG_INFO | DEBUG_IFACE, "* Interface (%s) Disconnect", name);
debug ("Interface (%s) Disconnect **** VIRTUAL NOT IMPLEMENTED ****", name);
};
void Interface::PowerOnOff(int onoff) {
debug (DEBUG_INFO | DEBUG_IFACE, "* Interface (%s) PowerOnOff %d", name, onoff);
debug ("Interface (%s) PowerOnOff %d **** VIRTUAL NOT IMPLEMENTED ****", name, onoff);
};
/*
@ -43,22 +41,19 @@ void Interface::PowerOnOff(int onoff) {
* will save the current time in the value turnouttime.
*/
void Interface::SetTurnout(Turnout *t, int active, int outputactive) {
JSONParse jp;
debug (DEBUG_INFO | DEBUG_IFACE, "%s:%d Interface (%s) SetTurnout Addr:%d Acitve:%d Output:%d", __FILE__, __LINE__, name,
t->addr, active, outputactive);
debug ("Interface (%s) SetTurnout Addr:%d Acitve:%d Output:%d **** VIRTUAL NOT IMPLEMENTED ****", name, t->addr, active, outputactive);
};
//
// Locomotive
//
void Interface::SetLocoSpeed(Locomotive *l, int step) {
debug (DEBUG_INFO | DEBUG_IFACE, "* Interface (%s) SetLocoSpeed Addr:%d Speed:%d ", name, l->addr, step);
debug ("Interface (%s) SetLocoSpeed Addr:%d Speed:%d **** VIRTUAL NOT IMPLEMENTED ****", name, l->addr, step);
};
void Interface::SetLocoFunction(Locomotive *l, int func, int value) {
debug (DEBUG_INFO | DEBUG_IFACE, "* Interface (%s) SetLocoFunction Addr:%d Func:%d:%d", name, l->addr, func, value);
debug ("Interface (%s) SetLocoFunction Addr:%d Func:%d:%d **** VIRTUAL NOT IMPLEMENTED ****", name, l->addr, func, value);
};
@ -68,8 +63,6 @@ void Interface::SetLocoFunction(Locomotive *l, int func, int value) {
int Interface::Loop() {
int ret = 0;
// debug (DEBUG_INFO | DEBUG_IFACE, "* Interface (%s) Loop", name);
flags &= ~(INTF_F_CONNECTED | INTF_F_POWER | INTF_F_STOP | INTF_F_SHORT_CIRCUIT | INTF_F_PROGRAMMING);
if (needs_update) {
ret = 1;
@ -81,35 +74,30 @@ int Interface::Loop() {
bool Interface::IsConnected() {
bool ret = false;
debug (DEBUG_INFO | DEBUG_IFACE, "* Interface (%s) IsConnected", name);
return ret;
debug ("Interface (%s) IsConnected **** VIRTUAL NOT IMPLEMENTED ****", name);
return false;
}
bool Interface::IsPoweron() {
bool ret = false;
debug (DEBUG_INFO | DEBUG_IFACE, "* Interface (%s) IsPoweron", name);
return ret;
debug ("Interface (%s) IsPoweron **** VIRTUAL NOT IMPLEMENTED ****", name);
return false;
}
bool Interface::IsSortCircuit() {
bool ret = false;
debug (DEBUG_INFO | DEBUG_IFACE, "* Interface (%s) IsSortCircuit", name);
return ret;
debug ("Interface (%s) IsSortCircuit **** VIRTUAL NOT IMPLEMENTED ****", name);
return false;
}
bool Interface::IsProgramminnMode() {
bool ret = false;
debug (DEBUG_INFO | DEBUG_IFACE, "* Interface (%s) IsProgramminnMode", name);
return ret;
debug ("Interface (%s) IsProgramminnMode **** VIRTUAL NOT IMPLEMENTED ****", name);
return false;
}
bool Interface::IsEmergencyStop() {
bool ret = false;
debug (DEBUG_INFO | DEBUG_IFACE, "* Interface (%s) IsEmergencyStop", name);
return ret;
debug ("Interface (%s) IsEmergencyStop **** VIRTUAL NOT IMPLEMENTED ****", name);
return false;
}

@ -4,8 +4,6 @@
#include "modelbahn.h"
#include "server.h"
#include "UDPTCPNetwork.h"
#include "json.h"
#define INTF_F_CONNECTED 0x0001
#define INTF_F_POWER 0x0002

@ -201,7 +201,7 @@ void Interfaces::SetTurnout(Turnout *t, int active, int motoractive) {
if (t == NULL) return;
LockThread();
debug (0, "%s:%d Interfaces::SetTurnout Name:%s active:%d Output%d", __FILE__, __LINE__, t->name, active, motoractive);
debug ("Name:%s active:%d Output%d", t->name, active, motoractive);
//
// if the interfacename is debug ... simulate a change in the turnout
@ -231,7 +231,7 @@ void Interfaces::SetLocoSpeed(Locomotive *l, int speed) {
int i;
int step = 0, maxstep = 0;
debug (0, "Interfaces::SetLocoSpeed Loco:'%s' Speed:%d", l->name, speed);
debug ("Loco:'%s' Speed:%d", l->name, speed);
switch(l->stepcode) {
case LOCO_INT_DCC14: maxstep = 14; break;
@ -261,7 +261,7 @@ void Interfaces::SetLocoSpeed(Locomotive *l, int speed) {
void Interfaces::SetLocoFunction(Locomotive *l, int func, int value) {
int i;
debug (0, "Interfaces::SetLocoFunction Loco:'%s' Function:%d Value:%d", l->name, func, value);
debug ("Loco:'%s' Function:%d Value:%d", l->name, func, value);
LockThread();

@ -4,8 +4,6 @@
#include "modelbahn.h"
#include "server.h"
#include "UDPTCPNetwork.h"
#include "json.h"
#include "interface.h"
#include "interfaces.h"

@ -1,493 +0,0 @@
#include <list>
#include <string>
#include <string.h>
using namespace std;
#include "debug.h"
#include "json.h"
/***********************************************************************
***********************************************************************
*
* JSONParse
*
***********************************************************************
***********************************************************************
*/
enum {
STEP_NONE = 0,
STEP_STARTNAME,
STEP_NAME,
STEP_STARTVALUE,
STEP_VALUE,
STEP_END
};
/////////////////////////////////////////////////////////
//
// clear out all data
//
void JSONParse::Clear() {
jsondata = "";
names.clear();
}
/////////////////////////////////////////////////////////
//
// read every element and keep only this in memory.
//
int JSONParse::Set(string json) {
int i;
int step;
int level;
bool ignorenext;
JSONElement jelement;
Clear();
// find start and read until end
for (step = STEP_NONE, i = 0, ignorenext = false; i < (int) json.length(); i++) {
// need to copy next character
// debug (0, "JSONParse: step:%d i:%d name:'%s' value:'%s'", step, i, jelement.name.c_str(), jelement.value.c_str());
if (ignorenext) {
ignorenext = false;
if (step == STEP_NAME) jelement.name += json[i];
if (step == STEP_VALUE) jelement.value += json[i];
}
// searching for startname
else if (step == STEP_NONE) {
if (json[i] == '{') {
step = STEP_STARTNAME;
continue;
}
}
// searching for startname
else if (step == STEP_STARTNAME) {
if (json[i] == '"') {
step = STEP_NAME;
continue;
}
}
// copy name
else if (step == STEP_NAME) {
if (json[i] == '"') {
step = STEP_STARTVALUE;
continue;
}
else {
jelement.name += json[i];
continue;
}
}
// searching for startvalue
else if (step == STEP_STARTVALUE) {
if (json[i] == '"') {
step = STEP_VALUE;
jelement.type = JSON_T_STRING;
continue;
}
if (json[i] == '{') {
step = STEP_VALUE;
level = 0;
jelement.type = JSON_T_OBJECT;
jelement.value = "{";
continue;
}
if (json[i] == '[') {
step = STEP_VALUE;
level = 0;
jelement.type = JSON_T_ARRAY;
jelement.value = "[";
continue;
}
if ((json[i] >= '0' && json[i] <= '9') ||
(json[i] == '+' || json[i] == '-')) {
step = STEP_VALUE;
level = 0;
jelement.type = JSON_T_NUMBER;
jelement.value = json[i];
continue;
}
}
// copy value
else if (step == STEP_VALUE) {
if (jelement.type == JSON_T_STRING) {
if (json[i] == '"') step = STEP_END;
else jelement.value += json[i];
continue;
}
else if (jelement.type == JSON_T_OBJECT) {
if (json[i] == '}' && level == 0) {
jelement.value += json[i];
step = STEP_END;
}
else {
if (json[i] == '{') level++; // increase level
if (json[i] == '}') level--; // decrease level
jelement.value += json[i];
}
continue;
}
else if (jelement.type == JSON_T_ARRAY) {
if (json[i] == ']' && level == 0) {
jelement.value += json[i];
step = STEP_END;
}
else {
if (json[i] == '[') level++; // increase level
if (json[i] == ']') level--; // decrease level
jelement.value += json[i];
}
continue;
}
else if (jelement.type == JSON_T_NUMBER) {
if ((json[i] < '0' || json[i] > '9') && json[i] != '.' &&
json[i] != '+' && json[i] != 'e' && json[i] != 'E') step = STEP_END;
else {
jelement.value += json[i];
continue;
}
}
}
// another element?
if (step == STEP_END) {
if (json[i] == ',') {
// debug (0, "* JSON.Set Add name:%s", jelement.name.c_str());
if (jelement.type != JSON_T_NONE) {
// debug (0, "%s:%d json add element type:%d", __FILE__, __LINE__, jelement.type);
names.push_back (jelement);
}
jelement.Clear();
step = STEP_STARTNAME;
}
continue;
}
}
// debug (0, "* JSON.Set Add name:%s", jelement.name.c_str());
if (jelement.type != JSON_T_NONE) {
// debug (0, "%s:%d json add element type:%d", __FILE__, __LINE__, jelement.type);
names.push_back (jelement);
}
return 0;
};
int JSONParse::GetValue(string varname, string *dest) {
list<JSONElement>::iterator iter;
if (dest == NULL) return 0;
*dest = "";
for (iter = names.begin(); iter != names.end(); iter++) {
if (varname.compare(iter->name) == 0) {
*dest = iter->value;
return 1;
}
}
return 0;
};
int JSONParse::GetValueInt(string varname, int *dest) {
string s;
int res = GetValue(varname, &s);
if (res) {
*dest = atoi (s.c_str());
return 1;
}
return 0;
};
int JSONParse::GetValueInt64(string varname, int64_t *dest) {
string s;
int res = GetValue(varname, &s);
if (res) {
*dest = atol (s.c_str());
return 1;
}
return 0;
};
int JSONParse::GetObject(string varname, JSONParse *dest) {
list<JSONElement>::iterator iter;
if (dest == NULL) return 0;
for (iter = names.begin(); iter != names.end(); iter++) {
if (varname.compare(iter->name) == 0) {
dest->Set(iter->value);
return 1;
}
}
return 0;
};
#define MAXRECURSIVE 255
int JSONParse::GetIdx(string src, int idx, string *dest) {
char recursive[MAXRECURSIVE];
int i = 0, rcnt = 0, cnt = 0;
(*dest) = "";
// printf("\n***************************************idx:%d\n", idx);
for (i = 0; i < MAXRECURSIVE; i++) recursive[i] = 0;
for (i = 0; i < (int) src.length() && rcnt < MAXRECURSIVE && cnt <= idx; i++) {
// printf ("i:%d rcnt:%d['%c'] cnt:%d char:'%c' ous:'%s'\n",
// i, rcnt, recursive[rcnt], cnt, src[i], dest->c_str());
if (src[i] == '[') {
recursive[rcnt++] = src[i];
continue;
}
else if (src[i] == '{' && recursive[rcnt] != '"') recursive[++rcnt] = src[i];
else if (src[i] == '}' && recursive[rcnt] == '{') rcnt--;
else if (src[i] == '"' && recursive[rcnt] == '"') rcnt--;
else if (src[i] == '"') recursive[++rcnt] = src[i];
else if (src[i] == ',' && rcnt == 1) {
cnt++;
continue;
}
else if (src[i] == ']' && rcnt == 1) {
continue;
}
if (rcnt > 0 && cnt == idx) {
(*dest) += src[i];
if (src[i] == '\\') (*dest) += src[i];
}
else {
if (src[i] == '\\')i++;
}
}
// printf("\n***************************************idx:%d cnt:%d\n", idx, cnt);
// printf("in:'%s'\n***\nout:'%s'\n\n*****\n", src.c_str(), dest->c_str());
//
// final checks
if (cnt == 0 && idx == 0 && // empty source/array?
dest->size() == 0) return 0; //
if (cnt >= idx) return 1; // found the right element
return 0; // element not found
}
#undef MAXRECURSIVE
int JSONParse::GetValueIdx(string varname, int idx, string *dest) {
list<JSONElement>::iterator iter;
if (dest == NULL) return 0;
for (iter = names.begin(); iter != names.end(); iter++) {
if (varname.compare(iter->name) == 0) {
return GetIdx(iter->value, idx, dest);
}
}
return 0;
};
int JSONParse::GetObjectIdx(string varname, int idx, JSONParse *dest) {
list<JSONElement>::iterator iter;
string deststr;
int ret = 0;
if (dest == NULL) return 0;
for (iter = names.begin(); iter != names.end(); iter++) {
if (varname.compare(iter->name) == 0) {
ret = GetIdx(iter->value, idx, &deststr);
if (ret == 1) dest->Set(deststr);
return ret;
}
}
return 0;
};
list<JSONElement> JSONParse::GetElements() {
list<JSONElement> l;
list<JSONElement>::iterator iter;
l.clear();
for (iter = names.begin(); iter != names.end(); iter++) {
l.push_back(*iter);
}
return l;
};
void JSONParse::AddObject (JSONElement element) {
names.push_back (element);
};
void JSONParse::AddObject (string name, JSONParse jp) {
JSONElement je;
je.SetObject(name, jp.ToString());
names.push_back(je);
};
void JSONParse::AddObject (string name, int val) {
JSONElement je;
je.Set(name, val);
names.push_back(je);
};
void JSONParse::AddObject (string name, int64_t val) {
JSONElement je;
je.Set(name, val);
names.push_back(je);
};
void JSONParse::AddObject (string name, string val) {
JSONElement je;
je.Set(name, val);
names.push_back(je);
};
void JSONParse::AddObject (string name, double val) {
JSONElement je;
je.Set(name, val);
names.push_back(je);
};
string JSONParse::ToString() {
list<JSONElement>::iterator iter;
string output;
int level, i;
output = "{";
for (level = 1, iter = names.begin(); iter != names.end(); iter++) {
if (iter != names.begin()) output += ",";
output += "\n";
for (i = 0; i < 4*level; i++) output += " ";
output += iter->GetString();
}
output += "\n}\n";
return output;
};
/***********************************************************************
***********************************************************************
*
* JSONElement
*
***********************************************************************
***********************************************************************
*/
void JSONElement::Set (string n, double v) {
name = n;
value = to_string(v);
type = JSON_T_NUMBER;
};
void JSONElement::Set (string n, int v) {
name = n;
value = to_string(v);
type = JSON_T_NUMBER;
};
void JSONElement::Set (string n, int64_t v) {
name = n;
value = to_string(v);
type = JSON_T_NUMBER;
};
void JSONElement::Set (string n, string v) {
name = n;
value = v;
type = JSON_T_STRING;
};
void JSONElement::SetArray (string n, list<JSONElement> *l) {
list<JSONElement>::iterator iter;
name = n;
value = "[";
type = JSON_T_STRING;
for (iter = l->begin(); iter != l->end(); iter++) {
if (iter != l->begin()) value += ",";
value += iter->GetString();
}
value += "]";
};
void JSONElement::SetObject (string n, string s) {
name = n;
value = s;
type = JSON_T_OBJECT;
};
string JSONElement::GetString () {
string output = "";
string filename = __FILE__;
switch (type) {
case(JSON_T_NUMBER):
output += "\"" + name + "\" : " + value;
break;
case(JSON_T_STRING):
if (value.length()==0) {
output += "\"" + name + "\" : \"\"";
}
else if (value[0] != '"') {
output += "\"" + name + "\" : \"" + value + "\"";
}
else output += "\"" + name + "\" : " + value;
break;
case(JSON_T_OBJECT):
output += "\"" + name + "\" : " + value;
break;
case(JSON_T_ARRAY):
if (value.length()==0) {
output += "\"" + name + "\" : []";
}
else if (value[0] != '[') {
output += "\"" + name + "\" : [" + value + "]";
}
else output += "\"" + name + "\" : " + value;
break;
default:
output += "\"error\" : \""+ filename + ":" + to_string(__LINE__) + " JSONElement unknown type error\"("+to_string(type)+")";
break;
}
return output;
};

@ -1,72 +0,0 @@
#ifndef _JSON_H_
#define _JSON_H_
#include <list>
#include <string>
#include <string.h>
using namespace std;
enum {
JSON_T_NONE,
JSON_T_STRING,
JSON_T_NUMBER,
JSON_T_OBJECT,
JSON_T_ARRAY
};
class JSONElement {
public:
int type;
string name;
string value;
JSONElement() { Clear(); };
~JSONElement() {};
void Clear() { type = JSON_T_NONE; name = ""; value = ""; };
void Set (string n, double v);
void Set (string n, int v);
void Set (string n, int64_t v);
void Set (string n, string v);
void SetArray (string n, list<JSONElement> *l);
void SetObject (string n, string s);
string GetString();
};
class JSONParse {
private:
string jsondata;
list<JSONElement> names;
public:
JSONParse() { Set("{}"); };
JSONParse(string json) { Set(json); };
~JSONParse() {};
void Clear();
int Set(string json);
int GetValue(string varname, string *dest);
int GetValueInt(string varname, int *dest);
int GetValueInt64(string varname, int64_t *dest);
int GetObject(string varname, JSONParse *dest);
int GetIdx(string src, int idx, string *dest);
int GetValueIdx(string varname, int idx, string *dest);
int GetObjectIdx(string varname, int idx, JSONParse *dest);
list<JSONElement> GetElements();
void AddObject (JSONElement element);
void AddObject (string name, int val);
void AddObject (string name, int64_t val);
void AddObject (string name, string val);
void AddObject (string name, double val);
void AddObject (string name, JSONParse jp);
string ToString();
};
#endif // _JSON_H_

@ -1,5 +1,4 @@
#include "modelbahn.h"
#include "locomotive.h"
@ -324,7 +323,7 @@ int Locomotives::SetDestination (string name, string block, int direction) {
}
}
debug (0, "Locomotives::SetDestination (Name:%s Block:%s Direction:%d) -> Final:%s"
debug ("Name:%s Block:%s Direction:%d -> Final:%s"
, name.c_str(), block.c_str(), direction, locomotives[i].blockdest);
break;
@ -342,10 +341,10 @@ int Locomotives::SetAssign (string name, string block, int direction) {
Lock();
for (i = 0; i < max; i++) if (locomotives[i].name[0] != 0)
if (name.compare(locomotives[i].name) == 0) {
debug (0, "Locomotives::SetAssign (Name:%s Block:%s Direction:%d)", name.c_str(), block.c_str(), direction);
debug ("Name:%s Block:%s Direction:%d", name.c_str(), block.c_str(), direction);
if (locomotives[i].flags & LOCO_F_AUTO) {
debug (0, "Locomotives::SetAssign not possible Loco is stil in AUTO mode.");
debug ("not possible Loco is stil in AUTO mode.");
i = max;
continue;
}
@ -402,7 +401,7 @@ int Locomotives::Reset(string name) {
Lock();
for (i = 0; i < max; i++) if (locomotives[i].name[0] != 0)
if (name.compare(locomotives[i].name) == 0) {
debug (0, "Locomotives::Reset (Name:%s)", name.c_str());
debug ("Name:%s", name.c_str());
locomotives[i].flags &= ~(LOCO_F_AUTO | LOCO_F_AUTOSTOP | LOCO_F_AUTORANDOM | LOCO_F_AUTOSHED);
locomotives[i].blockassign[0] = 0;
locomotives[i].blockdest[0] = 0;
@ -436,7 +435,7 @@ int Locomotives::SetModeMan(string name) {
Lock();
for (i = 0; i < max; i++) if (locomotives[i].name[0] != 0)
if (name.compare(locomotives[i].name) == 0) {
debug (0, "Locomotives::SetMan (Name:%s)\n", name.c_str());
debug ("Name:%s", name.c_str());
locomotives[i].flags &= ~(LOCO_F_AUTO | LOCO_F_AUTOSTOP | LOCO_F_AUTORANDOM | LOCO_F_AUTOSHED);
locomotives[i].auto_onroute = 0;
locomotives[i].auto_way[0] = 0;
@ -462,7 +461,7 @@ int Locomotives::SetModeAutoMan(string name) {
Lock();
for (i = 0; i < max; i++) if (locomotives[i].name[0] != 0)
if (name.compare(locomotives[i].name) == 0 && (locomotives[i].flags & LOCO_F_AUTO)) {
debug (0, "Locomotives::SetAutoMan (Name:%s)\n", name.c_str());
debug ("Name:%s", name.c_str());
locomotives[i].flags |= LOCO_F_AUTOSTOP;
locomotives[i].flags &= ~LOCO_F_AUTORANDOM;
locomotives[i].flags &= ~LOCO_F_AUTOSHED;
@ -485,7 +484,7 @@ int Locomotives::SetModeAuto(string name) {
Lock();
for (i = 0; i < max; i++) if (locomotives[i].name[0] != 0)
if (name.compare(locomotives[i].name) == 0) {
debug (0, "Locomotives::SetAuto (Name:%s)\n", name.c_str());
debug ("Name:%s", name.c_str());
locomotives[i].flags |= LOCO_F_AUTO;
locomotives[i].flags &= ~LOCO_F_AUTORANDOM;
locomotives[i].flags &= ~LOCO_F_AUTOSHED;
@ -508,7 +507,7 @@ int Locomotives::SetModeAutoRand(string name) {
Lock();
for (i = 0; i < max; i++) if (locomotives[i].name[0] != 0)
if (name.compare(locomotives[i].name) == 0 && (locomotives[i].flags & LOCO_F_AUTO)) {
debug (0, "Locomotives::SetAutoRandom (Name:%s)\n", name.c_str());
debug ("Name:%s", name.c_str());
locomotives[i].flags |= LOCO_F_AUTORANDOM;
locomotives[i].flags &= ~LOCO_F_AUTOSHED;
locomotives[i].flags &= ~LOCO_F_AUTOSTOP;
@ -532,7 +531,7 @@ int Locomotives::SetModeAutoShed(string name) {
Lock();
for (i = 0; i < max; i++) if (locomotives[i].name[0] != 0)
if (name.compare(locomotives[i].name) == 0 && (locomotives[i].flags & LOCO_F_AUTO)) {
debug (0, "Locomotives::SetAutoShed (Name:%s)\n", name.c_str());
debug ("Name:%s", name.c_str());
locomotives[i].flags |= LOCO_F_AUTOSHED;
locomotives[i].flags &= ~LOCO_F_AUTORANDOM;
locomotives[i].flags &= ~LOCO_F_AUTOSTOP;
@ -557,7 +556,7 @@ int Locomotives::SetSpeedFromBus(string ifname, int addr, int speed) {
JSONParse jp;
debug (0, "Locomotives::SetSpeedFromBus IfName:%s Addr:%d Speed:%d", __FILE__, __LINE__, ifname.c_str(), addr, speed);
debug ("IfName:%s Addr:%d Speed:%d", __FILE__, __LINE__, ifname.c_str(), addr, speed);
for (i = 0; i < max; i++) if (locomotives[i].name[0] != 0) {
if (ifname.compare(locomotives[i].ifname) == 0 && locomotives[i].addr == addr) {
@ -590,7 +589,7 @@ int Locomotives::SetFunctionFromBus(string ifname, int addr, int func) {
int i;
JSONParse jp;
debug (0, "Locomotives::SetDirectionFromBus IfName:%s Addr:%d function:%d", __FILE__, __LINE__, ifname.c_str(), addr, func);
debug ("IfName:%s Addr:%d function:%d", __FILE__, __LINE__, ifname.c_str(), addr, func);
for (i = 0; i < max; i++) if (locomotives[i].name[0] != 0) {
if (ifname.compare(locomotives[i].ifname) == 0 && locomotives[i].addr == addr) {
if (func & 32) locomotives[i].flags |= LOCO_F_REVERSE;
@ -632,7 +631,7 @@ int Locomotives::SchedulerNextStep(Locomotive *loc) {
if (loc == NULL) return 0;
debug (0, "Locomotives::SchedulerNextStep loc:%s Step:%d", loc->name, loc->sched_step);
debug ("loc:%s Step:%d", loc->name, loc->sched_step);
name = loc->name;
//
@ -659,7 +658,7 @@ int Locomotives::SchedulerNextStep(Locomotive *loc) {
for (next = "", i = stepnextpos; i < WAYDATA_LEN && loc->schedway[i] != ',' && loc->schedway[i] != 0; i++) {
if (i > stepnextpos+1) next += loc->schedway[i];
}
debug (0, "Locomotives::SchedulerNextStep loc:%s Next Pos: '%s'", loc->name, loc->schedway+stepnextpos);
debug ("loc:%s Next Pos: '%s'", loc->name, loc->schedway+stepnextpos);
if (loc->schedway[stepnextpos] && stepnextpos < schedwaylen-2) {
@ -689,8 +688,7 @@ int Locomotives::SchedulerNextStep(Locomotive *loc) {
break;
default:
debug (0, "Locomotives::SchedulerNextStep Unknown Command: '%c' loc:%s way:'%s'", loc->name,
loc->schedway[stepnextpos], loc->schedway);
debug ("Unknown Command: '%c' loc:%s way:'%s'", loc->name, loc->schedway[stepnextpos], loc->schedway);
break;
}
}
@ -708,7 +706,7 @@ int Locomotives::SchedulerNextStep(Locomotive *loc) {
// if everything is set up till the destination (next) block return 1
// to speed things up: we only prepare ways which we have locked already
//
int Locomotives::AutoCheckWaySingleStep(string way, Locomotive *loc, int *data) {
int Locomotives::AutoCheckWaySingleStep(string way, Locomotive *loc, int *data, int mark_error) {
size_t pos1;
size_t curpos;
int cnt;
@ -722,7 +720,7 @@ int Locomotives::AutoCheckWaySingleStep(string way, Locomotive *loc, int *data)
Railway r;
if (*data < 0) *data = 0;
debug (0, "Locomotives::AutoCheckWaySingleStep Prepare for Loco: %s Way:%s data:%d blocknext:%s", loc->name, way.c_str(), *data, loc->blocknext);
debug ("Prepare for Loco: %s Way:%s data:%d blocknext:%s mark_error:%d", loc->name, way.c_str(), *data, loc->blocknext, mark_error);
//
// find final next block
@ -736,7 +734,7 @@ int Locomotives::AutoCheckWaySingleStep(string way, Locomotive *loc, int *data)
}
}
nextblockpos = way.find(nextblock);
debug (0, "Locomotives::AutoCheckWaySingleStep nextblock:%s", nextblock.c_str());
debug ("nextblock:%s", nextblock.c_str());
curpos = 0;
do {
@ -749,7 +747,7 @@ int Locomotives::AutoCheckWaySingleStep(string way, Locomotive *loc, int *data)
if (curpos != string::npos) {
pos1 = way.find(":", curpos+3);
if (pos1 == string::npos) {
debug (0, "%s:%d turnout without value? '%s'", __FILE__, __LINE__, way.c_str());
debug ("turnout without value? '%s'", way.c_str());
server->PowerOnOff(0);
server->SetModeManual();
return 0;
@ -758,7 +756,7 @@ int Locomotives::AutoCheckWaySingleStep(string way, Locomotive *loc, int *data)
state = server->turnouts.Get(turnout);
if (state == -1) {
debug (0, "%s:%d turnout not found '%s'", __FILE__, __LINE__, turnout.c_str());
debug ("turnout not found '%s'", turnout.c_str());
server->PowerOnOff(0);
server->SetModeManual();
return 0;
@ -768,32 +766,44 @@ int Locomotives::AutoCheckWaySingleStep(string way, Locomotive *loc, int *data)
while (server->railways.FindReference(&x, &y, turnout, cnt++)) {
cnt++;
r = server->railways.RailwayGet(x, y);
debug (0, "Locomotives::AutoCheckWaySingleStep Loco:%s Turnout:%s LockedBy:%s", loc->name, turnout.c_str(), r.lockedby);
debug ("Loco:%s Turnout:%s LockedBy:%s", loc->name, turnout.c_str(), r.lockedby);
//
//
if (strncmp(loc->name, r.lockedby, REFERENCENAME_LEN) == 0 || r.lockedby[0] == 0) {
if (way[pos1+1] == '0' && state != 0) {
debug (0, "Locomotives::AutoCheckWaySingleStep Loco:%s Turnout:%s Not Equal -> Set:0", loc->name, turnout.c_str());
debug ("Loco:%s Turnout:%s Not Equal -> Set:0", loc->name, turnout.c_str());
server->turnouts.Set(way.substr(curpos+3, pos1-curpos-3), 0);
if (mark_error) {
debug ("MARK ERROR for %s", turnout.c_str());
server->turnouts.SetFlags(turnout, server->turnouts.GetFlags(turnout) | TURNOUT_F_ERROR);
}
return 0;
}
else if (way[pos1+1] == '1' && state != 1) {
debug (0, "Locomotives::AutoCheckWaySingleStep Loco:%s Turnout:%s Not Equal -> Set:1", loc->name, turnout.c_str());
debug ("Loco:%s Turnout:%s Not Equal -> Set:1", loc->name, turnout.c_str());
server->turnouts.Set(way.substr(curpos+3, pos1-curpos-3), 1);
if (mark_error) {
debug ("MARK ERROR for %s", turnout.c_str());
server->turnouts.SetFlags(turnout, server->turnouts.GetFlags(turnout) | TURNOUT_F_ERROR);
}
return 0;
}
else if (newdata > *data) {
debug (0, "Locomotives::AutoCheckWaySingleStep Loco:%s Turnout:%s Equal Reset:%c", loc->name, turnout.c_str(), way[pos1+1]);
debug ("Loco:%s Turnout:%s Equal Reset:%c", loc->name, turnout.c_str(), way[pos1+1]);
if (way[pos1+1] == '0') server->turnouts.Set(way.substr(curpos+3, pos1-curpos-3), 0);
if (way[pos1+1] == '1') server->turnouts.Set(way.substr(curpos+3, pos1-curpos-3), 1);
(*data) = newdata;
if (mark_error) {
debug ("MARK ERROR for %s", turnout.c_str());
server->turnouts.SetFlags(turnout, server->turnouts.GetFlags(turnout) | TURNOUT_F_ERROR);
}
return 0;
}
}
}
if (cnt == 0) {
debug (0, "Locomotives::AutoCheckWaySingleStep Loco:%s Turnout:%s Reference not found", loc->name, turnout.c_str());
debug ("Loco:%s Turnout:%s Reference not found", loc->name, turnout.c_str());
return 0;
}
}
@ -837,7 +847,7 @@ int Locomotives::Loco_SearchAndLock(Locomotive *loco) {
//
// destination empty? true -> random
// false -> find way to destination
debug (0, "Locomotives::Loop Search '%s' Reverse:%d", loco->name, (loco->flags & LOCO_F_REVERSE) ? 1 : 0);
debug ("Search '%s' Reverse:%d", loco->name, (loco->flags & LOCO_F_REVERSE) ? 1 : 0);
//
// destination set? - need to find a random block?
@ -869,7 +879,7 @@ int Locomotives::Loco_SearchAndLock(Locomotive *loco) {
else if (server->railways.FindWay(loco->blockassign, loco->blockdest, loco->name, &way)) {
// try to lock way.
size_t pos, pos1;
debug (0, "Locomotives::Loop %s:%d Found Way:%s", __FILE__, __LINE__, way.c_str());
debug ("Found Way:%s", way.c_str());
if ((pos = way.find(",b:", 1)) != string::npos) {
if ((pos1 = way.find(",", pos+3)) != string::npos) {
strncpy (loco->blocknext, way.substr(pos+3, pos1-(pos+3)).c_str(), REFERENCENAME_LEN);
@ -886,8 +896,7 @@ int Locomotives::Loco_SearchAndLock(Locomotive *loco) {
server->LocomotiveSetMan(loco->name);
server->LocomotiveSetSpeed(loco->name, 0);
debug (DEBUG_ERROR, "*** ERROR *** %s:%d locomotive %s error occured. Could not undo the locking of the way.",
__FILE__, __LINE__, loco->name);
debug ("*** ERROR *** locomotive %s error occured. Could not undo the locking of the way.", loco->name);
return 0;
}
}
@ -909,7 +918,7 @@ int Locomotives::Loco_PrepareWay(Locomotive *loco) {
block = ((string)(loco->blocknext+2)).substr(0, ((string)(loco->blocknext+2)).find(","));
if (loco->auto_timenext.tv_sec == 0 || timer_get(&loco->auto_timenext) > LOCO_TO_TURNOUT) {
if (AutoCheckWaySingleStep(loco->auto_way, loco, &loco->auto_data) == 1) {
if (AutoCheckWaySingleStep(loco->auto_way, loco, &loco->auto_data, ERROR_SET_NONE) == 1) {
if ((loco->flags & LOCO_F_CARGO) ||
(server->blocks.GetFlags(block) & BLOCK_F_SPEEDLIMIT)) return 1;
else return 2;
@ -953,10 +962,10 @@ int Locomotives::Loco_OnRoute(Locomotive *loco) {
if ( server->sensors.GetActive(s_enter) == 1 || server->sensors.GetActive(s_stop) == 1 ||
server->sensors.GetActive(s_slow) == 1) { // entering block?
debug (0, "* Locomotive '%s' EnterBlock '%s'", loco->name, loco->blocknext);
debug (0, "* %s,%d Sensor Enter '%s' = %d", __FILE__, __LINE__, s_enter.c_str(), server->sensors.GetActive(s_enter));
debug (0, "* %s,%d Sensor Slow '%s' = %d", __FILE__, __LINE__, s_slow.c_str(), server->sensors.GetActive(s_slow));
debug (0, "* %s,%d Sensor Stop '%s' = %d", __FILE__, __LINE__, s_stop.c_str(), server->sensors.GetActive(s_stop));
debug ("Locomotive '%s' EnterBlock '%s'", loco->name, loco->blocknext);
debug (" Sensor Enter '%s' = %d", __FILE__, __LINE__, s_enter.c_str(), server->sensors.GetActive(s_enter));
debug (" Sensor Slow '%s' = %d", __FILE__, __LINE__, s_slow.c_str(), server->sensors.GetActive(s_slow));
debug (" Sensor Stop '%s' = %d", __FILE__, __LINE__, s_stop.c_str(), server->sensors.GetActive(s_stop));
// assignment <-- next, the assignment has to be checked
// against long trains and split blocks
@ -983,23 +992,23 @@ int Locomotives::Loco_OnRoute(Locomotive *loco) {
loco->auto_way[0] = 0;
loco->blocknext[0] = 0;
debug (0, "Locomotive::Loco_OnRoute Loco:'%s' Prev:'%s' Assign:'%s' Next:'%s'",
debug ("Loco:'%s' Prev:'%s' Assign:'%s' Next:'%s'",
loco->name, loco->blockprev, loco->blockassign, loco->blocknext);
//
if (Loco_SearchAndLock(loco) == 1) {
loco->auto_onroute = LOCO_OR_ENTERBLOCKNEXT;
debug (0, "Locomotives::Loco_OnRoute Found Way Prepare '%s'", loco->name);
debug ("Found Way Prepare '%s'", loco->name);
SetSpeed(loco->name, loco->flags & LOCO_F_REVERSE ? -loco->vslow : loco->vslow);
timer_start(&loco->auto_timenext);
}
else if (loco->flags && LOCO_F_AUTO) {
loco->auto_onroute = LOCO_OR_ENTERBLOCKSTOP;
debug (0, "Locomotives::Loco_OnRoute Slow Down '%s'", loco->name);
debug ("Slow Down '%s'", loco->name);
SetSpeed(loco->name, loco->flags & LOCO_F_REVERSE ? -loco->vslow : loco->vslow);
}
else {
debug (0, "Locomotives::Loco_OnRoute '%s' some error occured.", loco->name);
debug ("'%s' some error occured.", loco->name);
SetSpeed(loco->name, 0);
}
return 1;
@ -1033,10 +1042,10 @@ int Locomotives::Loco_BlockEnterStop(Locomotive *loco) {
s_slow = server->blocks.GetSensorSlow(dir_reverse, block, loco->flags);
s_enter = server->blocks.GetSensorEnter(dir_reverse, block, loco->flags);
if (server->sensors.GetActive(s_stop) == 1) {
debug (0, "Locomotives::Loop BlockEnterStop '%s' UnLockWay\n", loco->name);
debug (0, "* %s,%d Sensor Enter '%s' = %d", __FILE__, __LINE__, s_enter.c_str(), server->sensors.GetActive(s_enter));
debug (0, "* %s,%d Sensor Slow '%s' = %d", __FILE__, __LINE__, s_slow.c_str(), server->sensors.GetActive(s_slow));
debug (0, "* %s,%d Sensor Stop '%s' = %d", __FILE__, __LINE__, s_stop.c_str(), server->sensors.GetActive(s_stop));
debug ("Locomotives::Loop BlockEnterStop '%s' UnLockWay\n", loco->name);
debug (" Sensor Enter '%s' = %d", s_enter.c_str(), server->sensors.GetActive(s_enter));
debug (" Sensor Slow '%s' = %d", s_slow.c_str(), server->sensors.GetActive(s_slow));
debug (" Sensor Stop '%s' = %d", s_stop.c_str(), server->sensors.GetActive(s_stop));
SetSpeed(loco->name, 0);
loco->auto_onroute = LOCO_OR_STOPWAIT;
@ -1075,11 +1084,11 @@ int Locomotives::Loco_BlockEnterNext(Locomotive *loco) {
s_enter = server->blocks.GetSensorEnter(dir_reverse, block, loco->flags);
if (server->sensors.GetActive(s_stop) == 1) {
if (!AutoCheckWaySingleStep(loco->auto_way, loco, &loco->auto_data)) {
if (!AutoCheckWaySingleStep(loco->auto_way, loco, &loco->auto_data, ERROR_SET_1)) {
//
// end of block and not finished preparing the way.
// stop everything
debug (0, "Locomotives::Loco_BlockEnterNext could not prepare way in time '%s'\n", loco->name);
debug ("could not prepare way in time '%s'\n", loco->name);
SetSpeed(loco->name, 0);
loco->auto_onroute = LOCO_OR_STOPWAIT;
server->railways.LockWay(loco->auto_wayold, loco->name, 0, 0);
@ -1090,7 +1099,7 @@ int Locomotives::Loco_BlockEnterNext(Locomotive *loco) {
return 0;
}
else {
debug (0, "* Locomotives::Loco_BlockEnterNext endblock reached %s", loco->name);
debug ("endblock reached %s", loco->name);
server->railways.LockWay(loco->auto_wayold, loco->name, 0, 0);
server->blocks.SetLockedby(loco->blockprev+2, loco->name, 0);
@ -1103,11 +1112,11 @@ int Locomotives::Loco_BlockEnterNext(Locomotive *loco) {
}
if (loco->auto_timenext.tv_sec > 0 && timer_get(&loco->auto_timenext) > LOCO_TO_TURNOUT) {
debug (0, "* Locomotives::Loco_BlockEnterNext prepare way for loco: %s", loco->name);
if (AutoCheckWaySingleStep(loco->auto_way, loco, &loco->auto_data) == 1) {
debug ("prepare way for loco: %s", loco->name);
if (AutoCheckWaySingleStep(loco->auto_way, loco, &loco->auto_data, ERROR_SET_NONE) == 1) {
//
// finished preparing new way, need to stay in ENTERBLOCKNEXT to unlock old way
debug (0, "* Locomotives::Loco_BlockEnterNext finished preparing way for loco: %s", loco->name);
debug ("finished preparing way for loco: %s", loco->name);
loco->auto_timenext.tv_sec = 0;
}
else timer_start(&loco->auto_timenext);
@ -1143,12 +1152,12 @@ int Locomotives::Loop() {
//
// only in automate do anything alone
//
// debug (0, "* Locomotives::Loop (%s:%d) Loco:%s auto_onroute:%d assign:'%s' next:'%s' prev:'%s' dest:'%s' way:'%s' wayold:'%s'"
// , __FILE__, __LINE__, loco->name, loco->auto_onroute, loco->blockassign
// debug ("Loco:%s auto_onroute:%d assign:'%s' next:'%s' prev:'%s' dest:'%s' way:'%s' wayold:'%s'"
// , loco->name, loco->auto_onroute, loco->blockassign
// , loco->blocknext, loco->blockprev, loco->blockdest, loco->auto_way, loco->auto_wayold);
if (loco->blockassign[0] == 0) {
debug (0, "%s:%d Locomotive [%s] not assigned to any block. Set Mode to Man", __FILE__, __LINE__, loco->name);
debug ("Locomotive [%s] not assigned to any block. Set Mode to Man", loco->name);
SetModeMan(loco->name);
continue;
}
@ -1160,7 +1169,7 @@ int Locomotives::Loop() {
continue;
}
else {
debug (0, "%s:%d Locomotive [%s] is doing NOTHING", __FILE__, __LINE__, loco->name);
debug ("Locomotive [%s] is doing NOTHING", loco->name);
timer_start(&loco->auto_timenext);
loco->auto_onroute = LOCO_OR_SEARCH;
}
@ -1180,7 +1189,7 @@ int Locomotives::Loop() {
if (strcmp(loco->blockassign, loco->blockdest) == 0) {
loco->blockdest[0] = 0;
debug (0, "* Locomotive '%s' DEST == ASSING", loco->name);
debug ("Locomotive '%s' DEST == ASSING", loco->name);
jp.Clear();
jp.AddObject("locomotive",_GetJSON(lnum));
if(network) network->ChangeListPushToAll(jp.ToString());
@ -1193,7 +1202,7 @@ int Locomotives::Loop() {
else {
// nothing found -> try reverse
if (loco->blockassign[0] != 0 && loco->blockdest[0] != 0 && (loco->flags & LOCO_F_CANREVERSE)) {
debug (0, "* Loco_SearchAndLock Reverse Loco %s", loco->name);
debug ("Reverse Loco %s", loco->name);
if (loco->blockassign[0] == '-') loco->blockassign[0] = '+';
else if (loco->blockassign[0] == '+') loco->blockassign[0] = '-';
@ -1215,7 +1224,7 @@ int Locomotives::Loop() {
case 1:
SetSpeed(loco->name, loco->flags & LOCO_F_REVERSE ? -loco->vmid : loco->vmid);
loco->auto_onroute = LOCO_OR_ONTHEWAY;
debug (0, "* %s:%d Locomotive '%s' Way Prepared -> Speed: VMID", __FILE__, __LINE__, loco->name);
debug ("Locomotive '%s' Way Prepared -> Speed: VMID", loco->name);
jp.Clear();
jp.AddObject("locomotive",_GetJSON(lnum));
if(network) network->ChangeListPushToAll(jp.ToString());
@ -1223,7 +1232,7 @@ int Locomotives::Loop() {
case 2:
SetSpeed(loco->name, loco->flags & LOCO_F_REVERSE ? -loco->vfast : loco->vfast);
loco->auto_onroute = LOCO_OR_ONTHEWAY;
debug (0, "* %s:%d Locomotive '%s' Way Prepared -> Speed: VFAST", __FILE__, __LINE__, loco->name);
debug ("Locomotive '%s' Way Prepared -> Speed: VFAST", loco->name);
jp.Clear();
jp.AddObject("locomotive",_GetJSON(lnum));
if(network) network->ChangeListPushToAll(jp.ToString());
@ -1255,7 +1264,7 @@ int Locomotives::Loop() {
case 1:
SetSpeed(loco->name, loco->flags & LOCO_F_REVERSE ? -loco->vmid : loco->vmid);
loco->auto_onroute = LOCO_OR_ONTHEWAY;
debug (0, "* %s:%d Locomotive LOCO_OR_ENTERBLOCKNEXT '%s' Way Prepared -> Speed: VMID", __FILE__, __LINE__, loco->name);
debug ("Locomotive LOCO_OR_ENTERBLOCKNEXT '%s' Way Prepared -> Speed: VMID", loco->name);
jp.Clear();
jp.AddObject("locomotive",_GetJSON(lnum));
if(network) network->ChangeListPushToAll(jp.ToString());
@ -1263,7 +1272,7 @@ int Locomotives::Loop() {
case 2:
SetSpeed(loco->name, loco->flags & LOCO_F_REVERSE ? -loco->vfast : loco->vfast);
loco->auto_onroute = LOCO_OR_ONTHEWAY;
debug (0, "* Locomotive LOCO_OR_ENTERBLOCKNEXT '%s' Way Prepared -> Speed: VFAST", loco->name);
debug ("Locomotive LOCO_OR_ENTERBLOCKNEXT '%s' Way Prepared -> Speed: VFAST", loco->name);
jp.Clear();
jp.AddObject("locomotive",_GetJSON(lnum));
if(network) network->ChangeListPushToAll(jp.ToString());

@ -115,7 +115,7 @@ class Locomotives {
int SetAssign (string name, string block, int direction);
int GetFlags(string name);
int AutoCheckWaySingleStep(string way, Locomotive *loc, int *data);
int AutoCheckWaySingleStep(string way, Locomotive *loc, int *data, int mark_error);
int Loop();
string GetName(int idx);

@ -8,8 +8,6 @@
#include <stdarg.h>
#include <signal.h>
#include <UDPTCPNetwork.h>
#include "modelbahn.h"
void uprintf (UNIX *u, char *fmt,...);
@ -45,18 +43,23 @@ int main (int argc, char **argv) {
return 0;
}
debug (0, "***************************************************");
debug (0, "* *");
debug (0, "* Modelbahn Server *");
debug (0, "* *");
debug (0, "***************************************************");
debug (0, "");
debug ("***************************************************");
debug ("* *");
debug ("* Modelbahn Server *");
debug ("* *");
debug ("***************************************************");
debug ("");
for (i = 1; i < argc; i++) {
if (strcmp (argv[i], "-help") == 0) {
debug ("possible parameters:");
debug (" -simulation simulate all IO commands");
exit (1);
}
if (strcmp (argv[i], "-simulation") == 0) {
simulation = 1;
debug (0, "WARINING SIMULATION MODE ACTIVE. ALL COMMANDS WILL BE SEND");
debug (0, "TO THE INTERFACES. TURNOUT AND SENSORDATA WILL BE FORCED.");
debug ("WARINING SIMULATION MODE ACTIVE. ALL COMMANDS WILL BE SEND");
debug ("TO THE INTERFACES. TURNOUT AND SENSORDATA WILL BE FORCED.");
sleep (5);
}
}
@ -65,7 +68,7 @@ int main (int argc, char **argv) {
//
// application startup
//
debug (0, "* application startup");
debug ("application startup");
server = new Server();
network = new Network();
@ -74,11 +77,11 @@ int main (int argc, char **argv) {
//
// application loop
//
debug (0, "* application loop");
debug ("application loop");
server->Start();
debug (0, "* server thread started");
debug ("server thread started");
network->Start();
debug (0, "* network thread started");
debug ("network thread started");
while (running) {
usleep (1000000);
}
@ -88,12 +91,12 @@ int main (int argc, char **argv) {
// application shutdown
//
while (server->isRunning() || network->isRunning());
debug (0, "* application shutdown");
debug ("application shutdown");
delete network;
debug (0, "* deleted network");
debug ("deleted network");
delete server;
debug (0, "* deleted server");
debug (0, "* application exited");
debug ("deleted server");
debug ("application exited");
return 0;
};
@ -110,7 +113,7 @@ void uprintf (UNIX *u, char *fmt,...) {
};
static void sig_int(int sig) {
debug (0, "* signal:%d received", sig);
debug ("signal:%d received", sig);
if (signal (SIGINT, sig_int) == SIG_ERR) {
fprintf (stderr, "%s:%d could not set up signal SIGINT\n", __FILE__, __LINE__);

@ -16,12 +16,17 @@
#define SENSORS_MAX 255
#define BLOCKS_MAX 128
#include <string>
using namespace std;
#define DEBUG_FILE "/tmp/modelbahn-server.log"
#include "UDPTCPNetwork.h"
#include "server.h"
#include "turnout.h"
#include "sensor.h"
#include "network.h"
#include "block.h"
#include "debug.h"
extern int running;

@ -23,7 +23,6 @@
#include "modelbahn.h"
#include "network.h"
#include "json.h"
Network::Network() {
thread = 0;
@ -92,7 +91,7 @@ void Network::ThreadProcess() {
if (tv_loop.tv_sec > timeout10s) {
timeout10s = tv.tv_sec + 10;
debug (DEBUG_INFO, "Network::ThreadProcess max Cycletime: %dms Cyclelooptime:%dms", cycletime_max, cyclelooptime_max);
debug ("max Cycletime: %dms Cyclelooptime:%dms", cycletime_max, cyclelooptime_max);
cycletime_max = 0;
cyclelooptime_max = 0;
}
@ -121,7 +120,7 @@ int Network::Start() {
pthread_attr_setdetachstate (&attr, PTHREAD_CREATE_JOINABLE);
err = pthread_create (&thread, &attr, ThreadEntry, this);
if (err != 0) {
debug (DEBUG_ERROR, (char*)"%s(%s:%d) pthread_create errror: %s", __FUNCTION__, __FILE__, __LINE__, strerror (errno));
debug ("pthread_create errror: %s", strerror (errno));
running = 0;
return 0;
}
@ -194,18 +193,17 @@ int Network::ClientLoop(UNIX *client) {
JSONParse json;
JSONParse jsonout;
JSONParse jelement;
long int l;
bufferin[len] = 0; // prevent reading behind the data
json.Set(bufferin);
if (!json.GetValue("sid", &ssid)) {
debug (0, "json.GetValue error --> sid");
debug ("json.GetValue error --> sid");
return 0;
}
if (!json.GetValue("rid", &srid)) {
debug (0, "json.GetValue error --> rid");
debug ("json.GetValue error --> rid");
return 0;
}
@ -215,7 +213,7 @@ int Network::ClientLoop(UNIX *client) {
}
catch (...) {
rid = 0;
debug (0, "* rid error");
debug ("rid error");
}
try {
@ -223,11 +221,11 @@ int Network::ClientLoop(UNIX *client) {
}
catch (...) {
sid = 0;
debug (0, "* sid error");
debug ("sid error");
}
if (sid <= 0) {
debug (0, "* sid not set, gettin new SID");
debug ("sid not set, gettin new SID");
session = new Session(rid);
sid = session->GetSessionID();
LockSessions();
@ -262,6 +260,9 @@ int Network::ClientLoop(UNIX *client) {
je.Clear();
je.Set("serverstatus", server->GetStatus());
jsonout.AddObject(je);
je.Clear();
je.Set("simulation", simulation);
jsonout.AddObject(je);
}
else {
je.Clear();
@ -272,9 +273,7 @@ int Network::ClientLoop(UNIX *client) {
jsonout.AddObject(je);
}
s = jsonout.ToString();
// printf ("***************************** %s:%d ---> send:\n\n\n%s\n\n\n", __FILE__, __LINE__, s.c_str());
l = client->Write((char*)s.c_str(), strlen(s.c_str()));
// printf ("\n\n Network::ClientLoop %s:%d strlen:%ld result:%ld \n\n\n", __FILE__, __LINE__, strlen(s.c_str()), l);
client->Write((char*)s.c_str(), strlen(s.c_str()));
result = 1;
}
else {

@ -28,8 +28,6 @@
using namespace std;
#include "modelbahn.h"
#include "json.h"
#include "debug.h"
extern int next_sessionID;

@ -1,10 +1,8 @@
#include "modelbahn.h"
#include "server.h"
#include "debug.h"
Railways::Railways() {
debug (0, "* Railways Constructor");
height = 0;
width = 0;
railways = NULL;
@ -123,7 +121,7 @@ struct s_findway_data Railways::NextPos(struct s_findway_data pos, int dirtype)
}
}
else {
debug (0, "Railways::NextPos dirtype unknown:%d", dirtype);
debug ("dirtype unknown:%d", dirtype);
return np;
}
@ -280,7 +278,7 @@ int Railways::Change(Railway *rw) {
}
else {
debug (DEBUG_INFO, "%s:%d add unknown %d,%d dir(%d) type:%d", __FILE__, __LINE__, rw->x, rw->y, rw->dir, rw->type);
debug ("add unknown %d,%d dir(%d) type:%d", rw->x, rw->y, rw->dir, rw->type);
}
}
@ -296,7 +294,7 @@ void Railways::SetSize (int neww, int newh) {
int oh = height;
int x, y;
debug (0, "* Railways::SetSize (%d, %d)", neww, newh);
debug ("new dimensions: %dx%d", neww, newh);
Lock();
@ -318,7 +316,7 @@ void Railways::SetSize (int neww, int newh) {
void Railways::_New (int neww, int newh) {
int x, y;
debug (0, "* Railways New");
debug ("");
//
// clip to minimum and maximum sizes
@ -521,7 +519,7 @@ string Railways::GetDestBlock(int locoflags, string blockend) {
block = blockend;
}
debug (0, "Railway::GetDestBlock Final split:%d loco short:%d blockend:%s -> block:%s"
debug ("Final split:%d loco short:%d blockend:%s -> block:%s"
, (block_f & BLOCK_F_SPLIT) ? 1 : 0
, (locoflags & LOCO_F_SHORTTRAIN) ? 1: 0
, blockend.c_str()
@ -571,7 +569,7 @@ int Railways::FindWay(string org_blockstart, string org_blockend, string lockedf
int found = 0;
int locoflags = server->locomotives.GetFlags(lockedfor);
debug (0, "Railway::FindWay blockstart:%s blockend:%s lockedfor:%s", org_blockstart.c_str(), org_blockend.c_str(), lockedfor.c_str());
debug ("blockstart:%s blockend:%s lockedfor:%s", org_blockstart.c_str(), org_blockend.c_str(), lockedfor.c_str());
//
// check blocklen
@ -589,7 +587,7 @@ int Railways::FindWay(string org_blockstart, string org_blockend, string lockedf
// allocate and clear memory for checked data
fd_data = (struct s_findway_map *) malloc (sizeof(struct s_findway_map) * width * height);
if (fd_data == NULL) {
printf ("%s:%d (%s) FATAL ERROR: could not allocate enough memory\n", __FILE__, __LINE__, __FUNCTION__);
debug ("*** FATAL ERROR *** could not allocate enough memory");
exit (1);
}
memset (fd_data, 0x0, sizeof(struct s_findway_map) * width*height);
@ -603,7 +601,7 @@ int Railways::FindWay(string org_blockstart, string org_blockend, string lockedf
fd_end.dist = fd_start.dist = 0;
if (FindReference(&fd_start.x, &fd_start.y, blockstart.substr(2, string::npos),0)) {
debug (0, "Railway::FindWay found startblock (%s).", blockstart.c_str());
debug ("found startblock (%s).", blockstart.c_str());
if (Get(fd_start.x, fd_start.y).dir == 1) {
if (blockstart[0] == '+') fd_start.enterfrom = 0;
else fd_start.enterfrom = 2;
@ -617,13 +615,13 @@ int Railways::FindWay(string org_blockstart, string org_blockend, string lockedf
fd_data[GetRIdx(fd_start.x, fd_start.y)].score = 1;
}
else {
debug (0, "Railway::FindWay could not find startblock (%s).", blockstart.c_str());
debug ("could not find startblock (%s).", blockstart.c_str());
free (fd_data);
return 0;
}
if (FindReference(&fd_end.x, &fd_end.y, blockend.substr(2, string::npos), 0)) {
debug (0, "Railway::FindWay found endblock (%s).", blockend.c_str());
debug ("found endblock (%s).", blockend.c_str());
if (Get(fd_end.x, fd_end.y).dir == 1) {
if (blockend[0] == '+') fd_end.enterfrom = 0;
else fd_end.enterfrom = 2;
@ -636,7 +634,7 @@ int Railways::FindWay(string org_blockstart, string org_blockend, string lockedf
fd_data[GetRIdx(fd_end.x, fd_end.y)].e = (1 << fd_end.enterfrom);
}
else {
debug (0, "Railway::FindWay could not find endblock (%s).", blockend.c_str());
debug ("could not find endblock (%s).", blockend.c_str());
free (fd_data);
return 0;
}
@ -681,7 +679,7 @@ int Railways::FindWay(string org_blockstart, string org_blockend, string lockedf
fd_pos.x = -1;
fd_pos.y = -1;
fd_pos.way = "";
debug (0, "Railway::FindWay %s:%d found way. [%s]", __FILE__, __LINE__, next->c_str());
debug ("found way. [%s]", next->c_str());
}
else if (fd_pos.enterfrom >= 0 && fd_start.x == fd_pos.x && fd_start.y == fd_pos.y && fd_start.enterfrom == fd_pos.enterfrom) {
// start found
@ -756,7 +754,7 @@ int Railways::FindWay(string org_blockstart, string org_blockend, string lockedf
}
else if (rpos->type == RAILWAY_BLOCK) {
int blflags = server->blocks.GetFlags(rpos->name);
debug (0, "Railways::FindWay %s:%d found block: %s", __FILE__, __LINE__, rpos->name);
debug ("found block: %s", rpos->name);
//
// check if block is available for entering
@ -823,7 +821,7 @@ int Railways::FindWay(string org_blockstart, string org_blockend, string lockedf
// check that a way is not set twice
//
if (!FindWayCheckIfNoDoubleTurnouts (next)) {
debug (0, "FindWayCheckIfNoDoubleTurnouts way [%s] is not valid.", next->c_str());
debug ("way [%s] is not valid.", next->c_str());
*next = "";
}
}
@ -831,7 +829,7 @@ int Railways::FindWay(string org_blockstart, string org_blockend, string lockedf
free (fd_data);
debug (0, "Railway::FindWay Result (%s) -> (%s) Found:%d Next:%s", blockstart.c_str(), blockend.c_str(), found, next->c_str());
debug ("Result (%s) -> (%s) Found:%d Next:%s", blockstart.c_str(), blockend.c_str(), found, next->c_str());
return found;
};
@ -840,7 +838,6 @@ int Railways::FindWay(string org_blockstart, string org_blockend, string lockedf
int Railways::FindWayCheckIfNoDoubleTurnouts (string *way) {
size_t pos1, pos2; // block positions
size_t tp1, tp2; // turnouts
int wayset;
string s; // search string (should not been found)
for (pos1 = 0, pos2 = way->find(",b:"); pos2 != string::npos; pos1 = pos2, pos2 = way->find(",b:", pos1+1)) {
@ -891,13 +888,12 @@ int Railways::_NextPosIsValid(string loconame, int locoflags, struct s_findway_d
int Railways::_SplitBlockIsFreeAndAllowed(string loconame, int locoflags, string block) {
string pblock;
string nblock;
Railway *rpos = NULL;
int bflags = server->blocks.GetFlags(block);
int nblockflags = 0;
int pblockflags = 0;
int x1, y1, x2, y2, x = 0, y = 0;
debug (0, "Railway::_SplitBlockIsFreeAndAllowed loconame:%s flags:%d block:%s", loconame.c_str(), locoflags, block.c_str());
debug ("loconame:%s flags:%d block:%s", loconame.c_str(), locoflags, block.c_str());
if (locoflags & LOCO_F_SHORTTRAIN) return 0;
if ((locoflags & !LOCO_F_SHORTTRAIN) && (bflags & !BLOCK_F_SPLIT)) return 0;
@ -929,7 +925,7 @@ int Railways::_SplitBlockIsFreeAndAllowed(string loconame, int locoflags, string
// check the way between the blocks
if (_FindReference(&x1, &y1, pblock, 0) == 0) return 0;
if (_FindReference(&x2, &y2, nblock, 0) == 0) return 0;
debug (0, "Railway::_SplitBlockIsFreeAndAllowed p pos(%d,%d) n pos(%d,%d)", x1, y1, x2, y2);
debug ("p pos(%d,%d) n pos(%d,%d)", x1, y1, x2, y2);
x = x1; y = y1;
do {
@ -948,15 +944,15 @@ int Railways::FindRandomWay(string blockstart, string lockedfor, string *next) {
struct s_findway_data fd_tmp;
struct s_findway_data fd_start;
struct s_findway_data fd_end;
Railway *rpos, *rnext;
// Railway *rpos, *rnext;
std::list<struct s_findway_data> fd_list;
struct s_findway_map *fd_data = NULL;
// struct s_findway_map *fd_data = NULL;
string lockedby;
int x ,y;
int found = 0;
int locoflags = server->locomotives.GetFlags(lockedfor);
// int x ,y;
// int found = 0;
// int locoflags = server->locomotives.GetFlags(lockedfor);
debug (0, "Railway::FindRandomWay - disabled for now - needs to be rewritten");
debug (" - disabled for now - needs to be rewritten");
return 0;
}
@ -983,7 +979,7 @@ int Railways::LockWay (string way, string lockedby, int lockonoff, int flags) {
int blockendflags = 0;
int blockstartflags = 0;
debug (0, "* LockWay Way:'%s' for '%s' lockonoff:%d", way.c_str(), lockedby.c_str(), lockonoff);
debug ("Way:'%s' for '%s' lockonoff:%d", way.c_str(), lockedby.c_str(), lockonoff);
end.x = start.x = -1;
end.y = start.y = -1;
@ -1008,7 +1004,7 @@ int Railways::LockWay (string way, string lockedby, int lockonoff, int flags) {
if (!(locoflags & LOCO_F_SHORTTRAIN) && (blockstartflags & BLOCK_F_SPLIT))
startblock2 = server->blocks.GetSecondBlock(startblock.substr(2, string::npos));
else startblock2 = "";
debug (0, "%s:%d LockWay Way: '%s' Startblock: '%s' Startblock2: '%s' Endblock: '%s' Endblock2: '%s'", __FILE__, __LINE__, way.c_str(),
debug ("Way: '%s' Startblock: '%s' Startblock2: '%s' Endblock: '%s' Endblock2: '%s'", way.c_str(),
startblock.c_str(), startblock2.c_str(), endblock.c_str(), endblock2.c_str());
//
@ -1041,7 +1037,7 @@ int Railways::LockWay (string way, string lockedby, int lockonoff, int flags) {
}
}
else {
debug (0, "Railway::LockWay could not find start (%s).", startblock.c_str());
debug ("could not find start (%s).", startblock.c_str());
return 0;
}
@ -1077,7 +1073,7 @@ int Railways::LockWay (string way, string lockedby, int lockonoff, int flags) {
// get the final end position
if (!FindReference(&end.x, &end.y, endblockfinal, 0)) {
debug (0, "Railway::FindWay could not find endblock (%s).", endblockfinal.c_str());
debug ("could not find endblock (%s).", endblockfinal.c_str());
return 0;
}
@ -1091,7 +1087,7 @@ int Railways::LockWay (string way, string lockedby, int lockonoff, int flags) {
else end.enterfrom = 1;
}
printf ("%s:%d LockWay Way:'%s' start [%d,%d -> %d] to [%d,%d -> %d] LockOnOff:%d\n", __FILE__, __LINE__, way.c_str(),
printf ("Way:'%s' start [%d,%d -> %d] to [%d,%d -> %d] LockOnOff:%d\n", way.c_str(),
start.x, start.y, start.enterfrom, end.x, end.y, end.enterfrom, lockonoff);
//
@ -1108,11 +1104,11 @@ int Railways::LockWay (string way, string lockedby, int lockonoff, int flags) {
finished = 0;
do {
r = &railways[GetRIdx(pos.x, pos.y)];
debug (0, "LockWay Position [%d,%d] Name:%s LockedBy:'%s'", pos.x, pos.y, r->name, r->lockedby);
debug ("Position [%d,%d] Name:%s LockedBy:'%s'", pos.x, pos.y, r->name, r->lockedby);
// check if railway is free or locked by me
if (r->lockedby[0] != 0 && lockedby.compare(r->lockedby) != 0 && !(lockonoff == 0 && pos.x == start.x && pos.y == start.y && r->type == RAILWAY_BLOCK)) {
debug (0, "LockWay: Railway currently locked by '%s'.", r->lockedby);
debug ("Railway currently locked by '%s'.", r->lockedby);
UnLock();
return 0;
}
@ -1138,8 +1134,8 @@ int Railways::LockWay (string way, string lockedby, int lockonoff, int flags) {
Lock();
}
else {
debug (0, "*** ERROR *** RailWay BLOCK not start and end (r->name:%s) startblock:%s [%s] endblock:%s [%s]"
, r->name, startblock.c_str(), startblock2.c_str(), endblock.c_str(), endblock2.c_str());
debug ("*** ERROR *** RailWay BLOCK not start and end (r->name:%s) startblock:%s [%s] endblock:%s [%s]",
r->name, startblock.c_str(), startblock2.c_str(), endblock.c_str(), endblock2.c_str());
server->PowerOnOff(0);
}
jp.Clear();
@ -1156,7 +1152,7 @@ int Railways::LockWay (string way, string lockedby, int lockonoff, int flags) {
if (pos.x < 0 || pos.y < 0 || pos.x >= width || pos.y >= height) {
server->interfaces.PowerOnOff(false);
debug (0, "Railway::LockWay %s:%d Error: routing out of surface [%d,%d]", __FILE__, __LINE__, pos.x, pos.y);
debug ("Error: routing out of surface [%d,%d]", pos.x, pos.y);
finished = 1;
break;
}
@ -1184,14 +1180,14 @@ int Railways::LockWay (string way, string lockedby, int lockonoff, int flags) {
// go to next position
if (r->type == RAILWAY_TURNOUT) {
if (curwaypos == string::npos) { // we should have a turnout
debug (0, "LockWay turnout '%s' not on Way '%s'", r->name, way.c_str());
debug ("turnout '%s' not on Way '%s'", r->name, way.c_str());
UnLock();
return 0;
}
pos1 = way.find(":", curwaypos+2);
if (pos1 == string::npos) {
debug (0, "LockWay turnout could not find parameter 'active'" );
debug ("turnout could not find parameter 'active'" );
UnLock();
return 0;
}
@ -1200,7 +1196,7 @@ int Railways::LockWay (string way, string lockedby, int lockonoff, int flags) {
// in case this turnout is not in the way list. It is might in between the splitblocks
if (way.substr(curwaypos+2, pos1-curwaypos-2).compare(r->name) != 0) {
int d = server->turnouts.Get(r->name);
debug (0, "LockWay tournout %s in between start or endblock? Active: %d", r->name, d);
debug ("tournout %s in between start or endblock? Active: %d", r->name, d);
pos = NextPos(pos, d ? r->altdir : r->dir);
}
else {
@ -1217,10 +1213,9 @@ int Railways::LockWay (string way, string lockedby, int lockonoff, int flags) {
int found = 0;
int x = -1, y = -1, cnt = 0;
debug (0, "LockWay connector found Reference:'%s'", r->name);
debug ("connector found Reference:'%s'", r->name);
while (found == 0 && _FindReference(&x, &y, r->name, (cnt++)) == 1) {
if (pos.x != x || pos.y != y) {
debug (0, "%s:%d found %d,%d", __FILE__, __LINE__, x, y);
pos.oldx = pos.x;
pos.oldy = pos.y;
pos.oldenterfrom = pos.enterfrom;
@ -1234,7 +1229,7 @@ int Railways::LockWay (string way, string lockedby, int lockonoff, int flags) {
}
if (found == 0) {
debug (0, "LockWay connector '%s' did not find second end.", r->name );
debug ("connector '%s' did not find second end.", r->name );
UnLock();
return 0;
}

@ -245,10 +245,10 @@ void Sensors::SetFromBus(string name, int addr, int active) {
int i;
JSONParse jp;
debug (0, "* Sensor Interface:%s Addr:%d changed:%d", name.c_str(), addr, active);
debug ("Interface:%s Addr:%d changed:%d", name.c_str(), addr, active);
for (i = 0; i < max; i++) if (sensors[i].name[0] != 0) {
if (strncmp (sensors[i].ifname, name.c_str(), REFERENCENAME_LEN) == 0 && sensors[i].addr == addr) {
debug (0, "* Sensor %s changed:%d", sensors[i].name, active);
debug ("Sensor %s changed:%d", sensors[i].name, active);
if (sensors[i].flags & SENSOR_F_INVERSE) {
if (active) sensors[i].flags &= ~SENSOR_F_ACTIVE;
else sensors[i].flags |= SENSOR_F_ACTIVE;

@ -22,14 +22,14 @@ int Server::Save() {
//
// check if the folder does exists.
if (stat (f.c_str(), &sbuf) != 0) {
debug (DEBUG_ERROR, "* Track::Save could not find directory '%s'. Creating it.", f.c_str());
debug ("could not find directory '%s'. Creating it.", f.c_str());
if (mkdir (f.c_str(), 0755) != 0) {
debug (DEBUG_ERROR, "* Track::Save could not create directory '%s'. (%s)", f.c_str(), strerror(errno));
debug ("could not create directory '%s'. (%s)", f.c_str(), strerror(errno));
return 0;
}
}
if ((sbuf.st_mode & S_IFMT) != S_IFDIR) {
debug (DEBUG_ERROR, "* Track::Save could not stat directory: '%s'. (%s)", f.c_str(), strerror(errno));
debug ("could not stat directory: '%s'. (%s)", f.c_str(), strerror(errno));
if (errno != EINTR) return 0;
}
@ -38,9 +38,9 @@ int Server::Save() {
f = DEFAULT_DATADIR; f = f + "/track.json";
nf = DEFAULT_DATADIR; nf = nf + "/track.json.backup." + to_string(time(NULL));
if (stat (f.c_str(), &sbuf) == 0) {
debug (DEBUG_INFO, "* Track::Save rename backup file to: %s", nf.c_str());
debug ("rename backup file to: %s", nf.c_str());
if (rename (f.c_str(), nf.c_str())) {
debug (DEBUG_ERROR, "* Track::Save could not rename file '%s' to '%s'. Error:(%s)",
debug ("could not rename file '%s' to '%s'. Error:(%s)",
f.c_str(), nf.c_str(), strerror(errno));
}
}
@ -64,7 +64,7 @@ int Server::Load(string fn) {
string s;
int x, y, i;
debug (DEBUG_INFO, "* Load File:%s", fn.c_str());
debug ("File:%s", fn.c_str());
if (stat (fn.c_str(), &sbuf) == 0) {
buf = (char *) malloc(sbuf.st_size+1);
memset (buf, 0x0, sbuf.st_size+1);
@ -75,7 +75,7 @@ int Server::Load(string fn) {
// everything read?
if (len < (size_t) sbuf.st_size) {
free (buf);
debug (DEBUG_ERROR, "* Reading Track File Failed. (len < filesize)");
debug ("Reading Track File Failed. (len < filesize)");
return 0;
}
@ -83,7 +83,7 @@ int Server::Load(string fn) {
json.Set(s);
}
else {
debug (DEBUG_ERROR, "* cloud not stat file (%s)", strerror(errno));
debug ("cloud not stat file (%s)", strerror(errno));
return 0;
}
@ -157,7 +157,7 @@ int Server::Save(string fn) {
JSONElement je;
int x, y, cnt;
debug (DEBUG_INFO, "* Save File:%s", fn.c_str());
debug ("File:%s", fn.c_str());
json.Clear();
json.AddObject("track", railways.GetJSONTrack());

@ -31,7 +31,7 @@ int Server::Start() {
pthread_attr_setdetachstate (&attr, PTHREAD_CREATE_JOINABLE);
err = pthread_create (&thread, &attr, ThreadEntry, this);
if (err != 0) {
debug (DEBUG_ERROR, (char*)"%s(%s:%d) pthread_create errror: %s", __FUNCTION__, __FILE__, __LINE__, strerror (errno));
debug ("pthread_create errror: %s", strerror (errno));
running = 0;
return 0;
}
@ -70,7 +70,7 @@ int Server::TurnoutSet(string name, int active) {
// check if locked
while (server->railways.FindReference(&x, &y, name, (cnt++))) {
r = server->railways.Get(x, y);
debug (0, "%s:%d Reference %d,%d Name:%s Lockedby:%s", __FILE__, __LINE__, x, y, r.name, r.lockedby);
debug ("Reference %d,%d Name:%s Lockedby:%s", x, y, r.name, r.lockedby);
if (r.lockedby[0] != 0) {
locked = 1;
lockedby = r.lockedby;
@ -80,7 +80,7 @@ int Server::TurnoutSet(string name, int active) {
if (simulation) {
int flags;
debug (0, "%s:%d WARNING SIMULATION MODE", __FILE__, __LINE__);
debug ("WARNING SIMULATION MODE");
flags = turnouts.GetFlags(turnouts.GetIdx(name));
if (flags & TURNOUT_F_TURNOUT) flags &= ~TURNOUT_F_TURNOUT;
else flags |= TURNOUT_F_TURNOUT;
@ -90,7 +90,7 @@ int Server::TurnoutSet(string name, int active) {
if (locked == 0) return turnouts.Set(name, active);
else {
debug (0, "%s:%d SetJSONTurnout Element %s is locked by %s", __FILE__, __LINE__, name.c_str(), lockedby.c_str());
debug ("SetJSONTurnout Element %s is locked by %s", name.c_str(), lockedby.c_str());
}
return 0;
@ -107,6 +107,7 @@ void Server::ThreadProcess() {
int cycletime_max = 0;
struct timeval tv_loop, tv;
debug ("Started");
gettimeofday (&tv, NULL);
gettimeofday (&tv_loop, NULL);
timeout10s = tv.tv_sec + 10;
@ -119,7 +120,7 @@ void Server::ThreadProcess() {
// startup process
if (mode == SMODE_STARTUP) {
mode = SMODE_MANUAL;
printf ("%s:%d ************************************************************ fix me\n", __FILE__, __LINE__);
debug ("************************************************************ fix me\n");
SetModeReset(); // currently there is not much to do.
}
@ -149,13 +150,13 @@ void Server::ThreadProcess() {
if (tv_loop.tv_sec > timeout10s) {
timeout10s = tv.tv_sec + 10;
debug (DEBUG_INFO, "Server::ThreadProcess max Cycletime: %dms Cyclelooptime:%dms", cycletime_max, cyclelooptime_max);
debug ("max Cycletime: %dms Cyclelooptime:%dms", cycletime_max, cyclelooptime_max);
cycletime_max = 0;
cyclelooptime_max = 0;
}
tv_loop = tv;
}
debug (0, "Server::ThreadProcess Finished");
debug ("Finished");
thread_running = 0;
};
@ -173,7 +174,7 @@ void Server::UnLockThread() {
//
// return JSONObject with all data
void Server::GetJSONAll(JSONParse *json) {
debug (DEBUG_INFO, "* Track::GetJSONAll data");
debug ("Track::GetJSONAll data");
if (json == NULL) return;
railways.GetJSONAll(json);
@ -198,7 +199,7 @@ bool Server::IsChanged() {
//
// Set Mode Auto
void Server::SetModeAuto() {
debug (0, "%s:%d * Set Mode Auto", __FILE__, __LINE__);
debug ("Set Mode Auto");
if (mode == SMODE_MANUAL) {
mode = SMODE_AUTO;
status_text = "Mode Auto";
@ -208,7 +209,7 @@ void Server::SetModeAuto() {
//
// Set Mode Manual
void Server::SetModeManual() {
debug (0, "%s:%d * Set Mode Manual", __FILE__, __LINE__);
debug ("Set Mode Manual");
mode = SMODE_MANUAL;
status_text = "Mode Manual";
}
@ -225,18 +226,17 @@ void Server::CycleModeReset() {
list<JSONElement>::iterator iter;
json.Clear();
// debug (0, "* CycleModeReset Step:%d", data_reset.mr_step);
if (data_reset.mr_step == SMRESET_STEP_INIT) {
//
// init reset
debug ("Init Reset");
data_reset.mr_idx = -1;
data_reset.mr_step++;
}
else if (data_reset.mr_step == SMRESET_STEP_LOCKS) {
//
// clear all locks
debug (0, "* Clear all Locks", data_reset.mr_lastelm.c_str());
debug ("Clear all Locks");
data_reset.mr_idx = -1;
data_reset.mr_step++;
@ -258,7 +258,7 @@ void Server::CycleModeReset() {
timer_start (&data_reset.mr_timestamp);
if (data_reset.mr_lastelm.length() > 0) {
debug (0, "* Reset Locomotive %s", data_reset.mr_lastelm.c_str());
debug ("Reset Locomotive %s", data_reset.mr_lastelm.c_str());
LocomotiveSetReverse(data_reset.mr_lastelm, 0);
LocomotiveSetSpeed(data_reset.mr_lastelm, 0);
}
@ -287,7 +287,7 @@ void Server::CycleModeReset() {
else active = 0;
timer_start (&data_reset.mr_timestamp);
debug (0, "* Reset Turnout %s", data_reset.mr_lastelm.c_str());
debug ("Reset Turnout %s", data_reset.mr_lastelm.c_str());
TurnoutSet(data_reset.mr_lastelm, active);
}
}
@ -310,7 +310,7 @@ void Server::CycleModeReset() {
for (i = 0; sensors.Get(i, &sensor) == 1; i++) {
oldflags = sensor.flags;
sensor.flags &= ~(SENSOR_F_ACTIVE);
debug (0, "* Reset Sensor: '%s' (%d -> %d)", sensor.name, oldflags, sensor.flags);
debug ("Reset Sensor: '%s' (%d -> %d)", sensor.name, oldflags, sensor.flags);
if (oldflags != sensor.flags) // only update if needed
sensors.Change(&sensor);
}
@ -335,14 +335,14 @@ void Server::CycleModeReset() {
//
// Set Mode Error
void Server::SetModeError(string text) {
debug (0, "%s:%d * Set Mode Error :'%s'", __FILE__, __LINE__, text.c_str());
debug ("Set Mode Error :'%s'", text.c_str());
status_text = "Error:'" + text + "'";
}
//
// Set Mode Reset
void Server::SetModeReset() {
debug (0, "%s:%d * Set Reset Data", __FILE__, __LINE__);
debug ("Set Reset Data");
status_text = "Mode Reset";
mode = SMODE_RESET;

@ -21,7 +21,6 @@
#include <pthread.h>
#include <sys/syscall.h>
#include "json.h"
#include "modelbahn.h"
#include "turnout.h"
#include "railway.h"
@ -58,6 +57,9 @@ struct s_ModeResetData{
} typedef ModeResetData;
#define ERROR_SET_1 1
#define ERROR_SET_NONE 0
class Server {
private:

@ -38,30 +38,24 @@ int Session::ProcessData(JSONParse *jin, JSONParse *jout) {
list<JSONElement>::iterator iter;
jout->Clear();
// debug (0, "* Session sid:%d rid:%d", sessionID, randomID);
//
// found command
if (jin->GetValue("command", &command) == 1) {
//
// editing elements
//
debug (0, "%s:%d JIN:%s", __FILE__, __LINE__, jin->ToString().c_str());
debug ("JIN:%s", jin->ToString().c_str());
if (command.compare("addrailway") == 0) {
debug (0, "* Session Add Railways");
AddJSONRailway(jin);
}
else if (command.compare("delrailway") == 0) {
debug (0, "* Session Del Railways");
DelJSONRailway(jin);
}
else if (command.compare("addinterface") == 0) {
debug (0, "* Session Add Interface");
AddJSONInterface(jin);
}
else if (command.compare("delinterface") == 0) {
debug (0, "* Session Del Interface");
DelJSONInterface(jin);
}
@ -69,16 +63,12 @@ int Session::ProcessData(JSONParse *jin, JSONParse *jout) {
// turnouts
//
else if (command.compare("addsensor") == 0) {
debug (0, "* Session Add Sensor");
AddJSONSensor(jin);
}
else if (command.compare("delsensor") == 0) {
debug (0, "* Session del Sensor");
DelJSONSensor(jin);
}
else if (command.compare("sensorSetActive") == 0) {
debug (0, "* Session Sensor Set Active");
printf ("%s:%d jin:%s", __FILE__, __LINE__, jin->ToString().c_str());
SetJSONSensorActive(jin);
}
@ -86,11 +76,9 @@ int Session::ProcessData(JSONParse *jin, JSONParse *jout) {
// turnouts
//
else if (command.compare("addturnout") == 0) {
debug (0, "* Session Add Turnout");
AddJSONTurnout(jin);
}
else if (command.compare("delturnout") == 0) {
debug (0, "* Session Del Turnout");
DelJSONTurnout(jin);
}
else if (command.compare("setturnout") == 0) {
@ -101,11 +89,9 @@ int Session::ProcessData(JSONParse *jin, JSONParse *jout) {
// Blocks
//
else if (command.compare("addblock") == 0) {
debug (0, "* Session Add Block");
AddJSONBlock(jin);
}
else if (command.compare("delblock") == 0) {
debug (0, "* Session Del Block");
DelJSONBlock(jin);
}
else if (command.compare("blockoff") == 0) {
@ -120,11 +106,9 @@ int Session::ProcessData(JSONParse *jin, JSONParse *jout) {
// Locomotive
//
else if (command.compare("addlocomotive") == 0) {
debug (0, "* Session Add Locomotive");
AddJSONLocomotive(jin);
}
else if (command.compare("dellocomotive") == 0) {
debug (0, "* Session Del Locomotive");
DelJSONLocomotive(jin);
}
else if (command.compare("setlocomotive") == 0) {
@ -158,27 +142,21 @@ int Session::ProcessData(JSONParse *jin, JSONParse *jout) {
// poweron / poweroff / save and resetdata
//
else if (command.compare("poweron") == 0) {
debug (0, "* Session Poweron");
server->PowerOnOff(1);
}
else if (command.compare("poweroff") == 0) {
debug (0, "* Session Poweroff");
server->PowerOnOff(0);
}
else if (command.compare("save") == 0) {
debug (0, "* Save All");
server->Save();
}
else if (command.compare("serverreset") == 0) {
debug (0, "* Server Set to Reset");
server->SetModeReset();
}
else if (command.compare("servermanual") == 0) {
debug (0, "* Server Set to Manual");
server->SetModeManual();
}
else if (command.compare("serverauto") == 0) {
debug (0, "* Server Set to Auto");
server->SetModeAuto();
}
else if (command.compare("getall") == 0) {
@ -188,13 +166,11 @@ int Session::ProcessData(JSONParse *jin, JSONParse *jout) {
// debuggin maybe we need to fix this somehow
elements = json.GetElements();
for (iter = elements.begin(); iter != elements.end(); iter++) {
// printf ("*********************** Session::ProcessData %s:%d\n\n***\n%s\n***\n", __FILE__, __LINE__, (*iter).GetString().c_str());
ChangeListPush("{"+(*iter).GetString()+"}");
}
}
else {
debug (DEBUG_ERROR | DEBUG_SESSION, "%s:%d Unknown command: '%s' JSON:%s",
__FILE__, __LINE__, command.c_str(), jin->ToString().c_str());
debug ("Unknown command: '%s' JSON:%s", command.c_str(), jin->ToString().c_str());
}
}
@ -225,8 +201,6 @@ JSONElement Session::ChangeListGet() {
JSONElement je;
list<string>::iterator iter;
// debug (0, "* Session::ChangeListGet cnt:%d", changes.size());
je.type = JSON_T_ARRAY;
je.name = "changes";
je.value = "[";
@ -265,7 +239,7 @@ void Session::AddJSONRailway(JSONParse *jp) {
server->LockThread();
for (i = 0; jp->GetObjectIdx("rail", i, &element); i++) {
debug (0, "%s:%d AddJSONRailway Element '%s'", __FILE__, __LINE__, element.ToString().c_str());
debug ("Element '%s'", element.ToString().c_str());
r = server->GetRailwayFromJSON(&element);
server->RailwayChange(&r);
jout.Clear();
@ -291,7 +265,7 @@ void Session::DelJSONRailway(JSONParse *jp) {
server->LockThread();
for (i = 0; jp->GetObjectIdx("rail", i, &element); i++) {
debug (0, "%s:%d DelJSONRailway Element %s", __FILE__, __LINE__, element.ToString().c_str());
debug ("Element %s", element.ToString().c_str());
r = server->GetRailwayFromJSON(&element);
r.type = RAILWAY_NOTHING;
server->RailwayChange(&r);
@ -316,7 +290,7 @@ void Session::AddJSONInterface(JSONParse *jp) {
jp->GetObject("interface", &jiface);
iface = server->InterfaceFromJSON(&jiface);
if (iface.name[0] != 0) {
debug (0, "%s:%d AddJSONInterface Element %s", __FILE__, __LINE__, iface.name);
debug ("Element %s", iface.name);
// add element
server->InterfaceChange(&iface);
jout.Clear();
@ -341,7 +315,7 @@ void Session::DelJSONInterface(JSONParse *jp) {
jp->GetObject("interface", &jiface);
iface = server->InterfaceFromJSON(&jiface);
if (iface.name[0] != 0) {
debug (0, "%s:%d DelJSONInterface Element %s", __FILE__, __LINE__, iface.name);
debug ("Element %s", iface.name);
// add element
server->InterfaceDelete(iface.name);
jout.Clear();
@ -366,7 +340,7 @@ void Session::AddJSONSensor(JSONParse *jp) {
jp->GetObject("sensor", &jtmp);
se = server->SensorFromJSON(&jtmp);
if (se.name[0] != 0) {
debug (0, "%s:%d AddJSONSensor Element %s", __FILE__, __LINE__, se.name);
debug ("Element %s", se.name);
// add element
server->SensorChange(&se);
jout.Clear();
@ -391,7 +365,7 @@ void Session::DelJSONSensor(JSONParse *jp) {
jp->GetObject("sensor", &jtmp);
se = server->SensorFromJSON(&jtmp);
if (se.name[0] != 0) {
debug (0, "%s:%d DelJSONSensor Element %s", __FILE__, __LINE__, se.name);
debug ("Element %s", se.name);
// add element
server->SensorDelete(se.name);
jout.Clear();
@ -416,7 +390,7 @@ void Session::AddJSONLocomotive(JSONParse *jp) {
jp->GetObject("locomotive", &jloco);
loco = server->LocomotiveFromJSON(&jloco);
if (loco.name[0] != 0) {
debug (0, "%s:%d AddJSONLocomotive Element %s", __FILE__, __LINE__, loco.name);
debug ("Element %s", loco.name);
// add element
server->LocomotiveChange(&loco);
jout.Clear();
@ -446,19 +420,19 @@ void Session::SetJSONLocomotive(JSONParse *jp) {
if (jloco.GetValueInt("speed", &speed) == 1) {
//
// set speed
debug (0, "%s:%d SetJSONLocomotive Element %s Speed:%d", __FILE__, __LINE__, loconame.c_str(), speed);
debug ("Element %s Speed:%d", loconame.c_str(), speed);
server->LocomotiveSetSpeed(loconame, speed);
}
if (jloco.GetValueInt("reverse", &value) == 1) {
//
// reverse
debug (0, "%s:%d SetJSONLocomotive Element %s Reverse:%d", __FILE__, __LINE__, loconame.c_str(), value);
debug ("Element %s Reverse:%d", loconame.c_str(), value);
server->LocomotiveSetReverse(loconame, value);
}
if (jloco.GetValueInt("function", &func) == 1 && jloco.GetValueInt("value", &value) == 1) {
//
// set function
debug (0, "%s:%d SetJSONLocomotive Element %s Function:%d Value:%d", __FILE__, __LINE__, loconame.c_str(), func, value);
debug ("Element %s Function:%d Value:%d", loconame.c_str(), func, value);
server->LocomotiveSetFunction(loconame, func, speed);
}
jout.Clear();
@ -482,7 +456,7 @@ void Session::DelJSONLocomotive(JSONParse *jp) {
loco = server->LocomotiveFromJSON(&jloco);
server->LockThread();
if (loco.name[0] != 0) {
debug (0, "%s:%d DelJSONLocomotive Element %s", __FILE__, __LINE__, loco.name);
debug ("Element %s", loco.name);
// add element
server->LocomotiveDelete(loco.name);
jout.Clear();
@ -632,7 +606,7 @@ void Session::AddJSONTurnout(JSONParse *jp) {
jp->GetObject("turnout", &jtmp);
to = server->TurnoutFromJSON(&jtmp);
if (to.name[0] != 0) {
debug (0, "%s:%d AddJSONTurnout Element %s", __FILE__, __LINE__, to.name);
debug ("Element %s", to.name);
// add element
server->TurnoutChange(&to);
jout.Clear();
@ -657,7 +631,7 @@ void Session::DelJSONTurnout(JSONParse *jp) {
jp->GetObject("turnout", &jtmp);
to = server->TurnoutFromJSON(&jtmp);
if (to.name[0] != 0) {
debug (0, "%s:%d DelJSONTurnout Element %s", __FILE__, __LINE__, to.name);
debug ("Element %s", to.name);
// add element
server->TurnoutDelete(to.name);
jout.Clear();
@ -686,7 +660,7 @@ void Session::SetJSONTurnout(JSONParse *jp) {
if (name.length() > 0) {
//
// activate
debug (0, "%s:%d SetJSONTurnout Element %s active:%d", __FILE__, __LINE__, name.c_str(), active);
debug ("Element %s active:%d", name.c_str(), active);
server->TurnoutSet(name, active);
}
server->UnLockThread();
@ -705,7 +679,7 @@ void Session::AddJSONBlock(JSONParse *jp) {
jp->GetObject("block", &jtmp);
bl = server->BlockFromJSON(&jtmp);
if (bl.name[0] != 0) {
debug (0, "%s:%d AddJSONBlock Element %s", __FILE__, __LINE__, bl.name);
debug ("Element %s", bl.name);
// add element
server->BlockChange(&bl);
jout.Clear();
@ -730,7 +704,7 @@ void Session::DelJSONBlock(JSONParse *jp) {
jp->GetObject("block", &jtmp);
bl = server->BlockFromJSON(&jtmp);
if (bl.name[0] != 0) {
debug (0, "%s:%d DelJSONBlock Element %s", __FILE__, __LINE__, bl.name);
debug ("Element %s", bl.name);
// add element
server->BlockDelete(bl.name);
jout.Clear();
@ -786,27 +760,6 @@ void Session::SetJSONSensorActive(JSONParse *jp) {
jp->GetValue("sensor", &name);
jp->GetValueInt("enabled", &enabled);
server->SensorSetActive(name, enabled);
// jout.Clear();
// jout.AddObject("block", server->BlockGetJSON(bl.name));
// if (network) network->ChangeListPushToAll(jout.ToString());
server->UnLockThread();
};
/*
res = json.GetValue("command", &value);
if (res && value.compare("addelemens") == 0) {
for (i = 0; json.GetObjectIdx("elements", i, &jelement) != 0; i++) {
s = "";
jelement.GetValue("type", &s);
// printf ("i:%d t:'%s'\n", i, s.c_str());
}
}
snprintf (bufferout, BUFFERSIZE, "{\"success\":1,\"sid\":123}");
client->Write(bufferout, strlen(bufferout));
debug (0, "* write:\n%s\n* %d bytes", bufferout, strlen(bufferout));
result = 1;
*/

@ -1,26 +0,0 @@
#include <iostream>
#include "json.h"
using namespace std;
int main(int argc, char **argv) {
string input;
string json_line;
JSONParse json;
list<JSONElement> l;
list<JSONElement>::iterator iter;
for (json_line = "", input = ""; getline(cin, input);)
json_line += input;
json.Set(json_line);
l = json.GetElements();
for (iter = l.begin(); iter != l.end(); iter++) {
cout << iter->name << endl;
}
return 0;
};

@ -18,12 +18,14 @@ Turnouts::~Turnouts() {
int Turnouts::Lock() {
// debug ("");
if (pthread_mutex_lock(&mtx) == 0) return 1;
else return 0;
}
int Turnouts::UnLock() {
// debug ("");
if (pthread_mutex_unlock(&mtx) == 0) return 1;
else return 0;
}
@ -168,18 +170,19 @@ int Turnouts::Set(string name, int value) {
int i;
JSONParse jp;
debug ("Enter Turnout:%s Value:%d", name.c_str(), value);
//
Lock();
for (i = 0; i < max; i++) if (turnouts[i].name[0] != 0) {
if (name.compare(turnouts[i].name) == 0) {
debug (0, "%s:%d Turnout::Set: Name:%s Flags:%d[%c%c%c%c] Value:%d", __FILE__, __LINE__, name.c_str(), turnouts[i].flags,
debug ("Name:%s Flags:%d[%c%c%c%c] Value:%d", name.c_str(), turnouts[i].flags,
(turnouts[i].flags & TURNOUT_F_ISRELAIS) ? 'R' : '-',
(turnouts[i].flags & TURNOUT_F_TURNOUT) ? 'T' : '-',
(turnouts[i].flags & TURNOUT_F_ACTIVE) ? 'A' : '-',
(turnouts[i].flags & TURNOUT_F_INVERSE) ? 'I' : '-',
value);
if (turnouts[i].flags & TURNOUT_F_ISRELAIS) {
printf ("%s:%d is relais.... %d\n", __FILE__, __LINE__, value);
debug ("is relais.... %d", value);
server->interfaces.SetTurnout(&turnouts[i], value, value);
}
else {
@ -200,6 +203,7 @@ int Turnouts::Set(string name, int value) {
}
}
UnLock();
debug ("Exit Turnout:%s Value:%d", name.c_str(), value);
return 1;
};
@ -230,11 +234,11 @@ void Turnouts::SetFromBus(string ifname, int addr, int value) {
int i;
JSONParse jp;
debug (0, "%s:%d Turnouts::SetFromBus Interface:%s, addr: %d, value:%d", __FILE__, __LINE__, ifname.c_str(), addr, value);
debug ("Interface:%s, addr: %d, value:%d", ifname.c_str(), addr, value);
for (i = 0; i < max; i++) if (turnouts[i].name[0] != 0) {
if (ifname.compare(turnouts[i].ifname) == 0 && turnouts[i].addr == addr) {
debug (0, "%s:%d Turnout::SetFromBus Name:%s Flags:%d[%c%c%c%c]", __FILE__, __LINE__, turnouts[i].name, turnouts[i].flags,
debug ("Name:%s Flags:%d[%c%c%c%c]", turnouts[i].name, turnouts[i].flags,
(turnouts[i].flags & TURNOUT_F_ISRELAIS) ? 'R' : '-',
(turnouts[i].flags & TURNOUT_F_TURNOUT) ? 'T' : '-',
(turnouts[i].flags & TURNOUT_F_ACTIVE) ? 'A' : '-',
@ -251,7 +255,7 @@ void Turnouts::SetFromBus(string ifname, int addr, int value) {
if (value) turnouts[i].flags |= TURNOUT_F_TURNOUT;
else turnouts[i].flags &= ~TURNOUT_F_TURNOUT;
}
debug (0, "%s:%d Turnout::SetFromBus Name:%s Flags:%d[%c%c%c%c]", __FILE__, __LINE__, turnouts[i].name, turnouts[i].flags,
debug ("Name:%s Flags:%d[%c%c%c%c]", turnouts[i].name, turnouts[i].flags,
(turnouts[i].flags & TURNOUT_F_ISRELAIS) ? 'R' : '-',
(turnouts[i].flags & TURNOUT_F_TURNOUT) ? 'T' : '-',
(turnouts[i].flags & TURNOUT_F_ACTIVE) ? 'A' : '-',
@ -286,12 +290,10 @@ void Turnouts::Loop() {
((curtime.tv_usec - turnouts[i].activatetime.tv_usec) / 1000);
if (timediff < 0) gettimeofday (&turnouts[i].activatetime, NULL);
// debug (0, "%s:%d timediff: %d", __FILE__, __LINE__, timediff);
if (timediff > turnouts[i].activetimeout) {
int turnout = (turnouts[i].flags & TURNOUT_F_TURNOUT) != 0 ? 1 : 0;
debug (0, "%s:%d Turnout::Loop Name:%s Flags:%d[%c%c%c%c] Turnout:%d", __FILE__, __LINE__, turnouts[i].name, turnouts[i].flags,
debug ("Name:%s Flags:%d[%c%c%c%c] Turnout:%d", turnouts[i].name, turnouts[i].flags,
(turnouts[i].flags & TURNOUT_F_ISRELAIS) ? 'R' : '-',
(turnouts[i].flags & TURNOUT_F_TURNOUT) ? 'T' : '-',
(turnouts[i].flags & TURNOUT_F_ACTIVE) ? 'A' : '-',
@ -339,6 +341,39 @@ int Turnouts::GetFlags(int idx) {
};
int Turnouts::GetFlags(string name) {
int i, res = -1;
//
Lock();
for (i = 0; i < max; i++) if (turnouts[i].name[0] != 0) {
if (name.compare(turnouts[i].name) == 0) {
res = turnouts[i].flags;
break;
}
}
UnLock();
return res;
};
void Turnouts::SetFlags(string name, int flags) {
int i;
//
Lock();
for (i = 0; i < max; i++) if (turnouts[i].name[0] != 0) {
if (name.compare(turnouts[i].name) == 0) {
turnouts[i].flags = flags;
break;
}
}
UnLock();
};
void Turnouts::SetFlags(int idx, int flags) {
JSONParse jp;

@ -2,6 +2,8 @@
#ifndef _TURNOUT_H_
#define _TURNOUT_H_
#include <string>
#include "modelbahn.h"
#include "server.h"
//
@ -9,6 +11,7 @@
#define TURNOUT_F_ACTIVE 0x0002 // motor/output active
#define TURNOUT_F_TURNOUT 0x0004 // turnout active
#define TURNOUT_F_ISRELAIS 0x0008 // output is relais no auto off
#define TURNOUT_F_ERROR 0x8000 // an error occured
#define TURNOUT_DEFAULT_ACTIVETIMEOUT 250 // active timeout default value
@ -58,6 +61,8 @@ class Turnouts {
int GetIdx(string name);
int GetFlags(int idx);
void SetFlags(int idx, int flags);
int GetFlags(string name);
void SetFlags(string name, int flags);
void SetFromBus(string name, int addr, int active);
};

@ -94,7 +94,10 @@ input {
border: 1px solid var(--input-fg-color);
background-color: var(--input-bg-color);
color: var(--input-fg-color);
font-family: "Lucida Console", Courier, monospace;
font-family: courier new, moonspace;
}
textarea {
}
td {

@ -17,6 +17,7 @@ const TURNOUT_F_INVERSE = 1;
const TURNOUT_F_OUTPUTACTIVE = 2;
const TURNOUT_F_TURNOUT = 4;
const TURNOUT_F_ISRELAIS = 8;
const TURNOUT_F_ERROR = 0x8000;
function rwdetail_requestcallback(response) {
@ -231,6 +232,10 @@ function rwdetail_setData(rw) {
};
//
// with no edit mode activated, every click will end up here.
// on a block the contect menu should be opened.
// on a sensor and if the simulation is acitve the sensor is activated
function rw_Click(x,y) {
var idx = x + y * track.size.x;
if (track.elements[idx]) {
@ -359,6 +364,20 @@ function turnout_IsOutputActive(name) {
}
//
// return if the turnout is active or not
//
function turnout_IsErrorFlag(name) {
for (var i = 0; i < turnouts.length; i++) {
if (name == turnouts[i].name) {
if (turnouts[i].flags & TURNOUT_F_ERROR) return 1
else return 0;
}
}
return 0;
};
//
// delete element from the list
// in arrays we can not delete just an element, so we create a new one
@ -428,7 +447,8 @@ function turndetail_show(turnname, create) {
<label><input id=\"turndet_inverse\" type=\"checkbox\" value=\"\"> Inverse</label><br>\
<label><input id=\"turndet_output\" type=\"checkbox\" value=\"\"> Output Active</label><br>\
<label><input id=\"turndet_relais\" type=\"checkbox\" value=\"\"> Is Relais</label><br>\
<label><input id=\"turndet_active\" type=\"checkbox\" value=\"\"><dfn title=\"save first\"> Active</dfn></label>\
<label><input id=\"turndet_active\" type=\"checkbox\" value=\"\"><dfn title=\"save first\"> Active</dfn></label><br>\
<label><input id=\"turndet_error\" type=\"checkbox\" value=\"\"> Error</label>\
\
</td></tr></table></div> <hr>\
<div align=right> \
@ -443,6 +463,7 @@ function turndetail_show(turnname, create) {
gAddEventListener("turndet_active", 'click', turndetail_cb_active);
gAddEventListener("turndet_output", 'click', turndetail_cb_output);
gAddEventListener("turndet_relais", 'click', turndetail_cb_relais);
gAddEventListener("turndet_error", 'click', turndetail_cb_error);
gAddEventListener("turndet_CLOSE", 'click', turndetail_cb_close);
gAddEventListener("turndet_DELETE", 'click', turndetail_cb_delete);
@ -529,6 +550,19 @@ function turndetail_cb_relais () {
flags.value = Number(flags.value) & (0xFFFF-TURNOUT_F_ISRELAIS);
};
//
// errorflag
function turndetail_cb_error () {
var cb = document.getElementById("turndet_error");
var flags = document.getElementById("turndet_flags");
var name = document.getElementById("turndet_name");
if (cb.checked)
flags.value = Number(flags.value) | TURNOUT_F_ERROR;
else
flags.value = Number(flags.value) & (0xFFFF-TURNOUT_F_ERROR);
};
function turndetail_cb_close () {
var win = document.getElementById("turndetail");
@ -619,6 +653,7 @@ function turndetail_setData(elm) {
var cbactive = document.getElementById("turndet_active");
var cbrelais = document.getElementById("turndet_relais");
var cboutput = document.getElementById("turndet_output");
var cberror = document.getElementById("turndet_error");
if (elm) {
if (turnname) turnname.value = elm.name;
@ -641,6 +676,10 @@ function turndetail_setData(elm) {
if (Number(elm.flags) & TURNOUT_F_ISRELAIS) cbrelais.checked = true;
else cbrelais.checked = false;
}
if (cberror) {
if (Number(elm.flags) & TURNOUT_F_ERROR) cberror.checked = true;
else cberror.checked = false;
}
}
};

@ -322,15 +322,15 @@ function sensorlist_cb_close () {
// ***********************************************************************************************
// ***********************************************************************************************
// sensor contextmenu: show a context menu for the sensor
// this is only if the INTERFACE name is set tu DEBUG
// this function should only called if the simulation mode is on
// ***********************************************************************************************
// ***********************************************************************************************
function sensor_contextmenu(name) {
let innerhtml = "";
console.log ("sensor_contextmenu: " + name);
for (var i = 0; i < sensors.length; i++) {
if (name == sensors[i].name) {
if (sensors[i].ifname == "DEBUG") {
if (simulation == 1) {
innerhtml = "<center>";
innerhtml += "<button id=\"contextbox_On\" type=\"button\">Set On</button><br>";
innerhtml += "<button id=\"contextbox_Off\" type=\"button\">Set Off</button><br>";

@ -8,6 +8,7 @@
var sessionID = "";
var randomID = "";
var request_running = 0;
var simulation = 0;
function serverinout_getRand(min, max) {
return Math.floor(Math.random() * (max - min) + min);
@ -42,12 +43,12 @@ function serverinout(request, callback) {
else
{
var clientstatus = document.getElementById("infoclient");
clientstatus.innerHTML = "-trying-";
clientstatus.innerHTML = "connecting";
}
},
error: function(error) {
var status = document.getElementById("infoclient");
status.innerHTML = "ajax error";
status.innerHTML = "error";
}
});
};
@ -85,19 +86,26 @@ function serverinout_Save(data) {
function serverinout_defaultCallback(data) {
if (data.sid && data.rid) {
var text = document.getElementById("infoserver");
//
// valid data from server
if (data.rid == randomID && data.sid == sessionID) {
//
// infoline
if (data.serverstatus) {
var text = document.getElementById("infoserver");
text.innerHTML = data.serverstatus;
if (data.serverstatus == "Mode Reset") sideBtnModeClick("sidebtn-reset");
if (data.serverstatus == "Mode Manual") sideBtnModeClick("sidebtn-manual");
if (data.serverstatus == "Mode Auto") sideBtnModeClick("sidebtn-auto");
}
//
// simulation?
if (data.simulation) {
if (data.simulation == 1) text.innerHTML = "<b>SIMULATION</b> | ";
simulation = data.simulation;
} else text.innerHTML = " | ";
//
// loop through all the changes
if (data.changes) {

@ -134,7 +134,9 @@ function trackDrawElement(ctx, element, mode) {
ctx.strokeStyle = cssVar('--track-color-locked');
else
ctx.strokeStyle = ctx.strokeStyle = cssVar('--turnout-this');
if (turnout_IsErrorFlag(element.name)) ctx.strokeStyle = cssVar('--track-color-error');
trackDrawTrack (ctx, {x: element.x, y: element.y}, dir);
ctx.setLineDash([0,0]);
if (element.name == "") ctx.strokeStyle = cssVar('--track-color-error');
else ctx.strokeStyle = cssVar('--turnout-other');
@ -693,7 +695,8 @@ function trackMouseup(event) {
}
else {
console.log ("rw_Click was das?");
//
// no edit mode was active, forward click to element.
rw_Click(trackMouse.pos.x, trackMouse.pos.y);
trackMouse.down.x = -1;
trackMouse.down.y = -1;

Loading…
Cancel
Save