InterfaceZ21 is now a subclass of Interface

master
Steffen Pohle 4 years ago
parent 206871b2c0
commit 9b1eb38f29

@ -1,3 +1,6 @@
2022-02-13:
- Interfaces are now virtual classes.
2021-12-19: 2021-12-19:
- adding sensor context menu for sensor simulation - adding sensor context menu for sensor simulation

@ -17,8 +17,8 @@ DEPENDFILE=.depend
TARGET=modelbahn-server TARGET=modelbahn-server
SERVEROBJ=server.o network.o session.o server-loadsave.o debug.o \ SERVEROBJ=server.o network.o session.o server-loadsave.o debug.o \
json.o main.o sensor.o turnout.o railway.o interface.o locomotive.o \ json.o main.o sensor.o turnout.o railway.o interfaces.o locomotive.o \
block.o interface-z21.o block.o interface.o interface-z21.o
CURDIR=`pwd` CURDIR=`pwd`

@ -33,11 +33,14 @@ static unsigned char RX_RMBUS_DATACHANGED[] { 0x0F, 0x00, 0x80, 0x00 };
#define Z21_IDX_SETTURNOUT_CHK 8 #define Z21_IDX_SETTURNOUT_CHK 8
InterfaceZ21::InterfaceZ21 () { InterfaceZ21::InterfaceZ21 () {
debug (DEBUG_INFO | DEBUG_IFACE, "InterfaceZ21:%s", __FUNCTION__);
status_connected = false; status_connected = false;
status_poweron = false; status_poweron = false;
status_programmingmode = false; status_programmingmode = false;
status_shortcircuit = false; status_shortcircuit = false;
status_emergencystop = false; status_emergencystop = false;
timer_start(&turnouttimeout);
send_logon = false; send_logon = false;
@ -45,7 +48,6 @@ InterfaceZ21::InterfaceZ21 () {
rmsensorinit = 0; rmsensorinit = 0;
serial = ""; serial = "";
hostname = "";
timeout = time(NULL); timeout = time(NULL);
rmgetdatatimeout = time(NULL) - INTF_Z21_RMGETDATA_TIMEOUT; rmgetdatatimeout = time(NULL) - INTF_Z21_RMGETDATA_TIMEOUT;
}; };
@ -55,11 +57,11 @@ InterfaceZ21::~InterfaceZ21() {
}; };
void InterfaceZ21::Connect (string destination) {
debug (DEBUG_INFO | DEBUG_IFACE, "%s:%d Connect to: %s", __FILE__, __LINE__, destination.c_str()); void InterfaceZ21::Connect () {
debug (DEBUG_INFO | DEBUG_IFACE, "InterfaceZ21: Connect to: %s", host);
if (status_connected) Disconnect(); if (status_connected) Disconnect();
hostname = destination;
if (udp.Listen(0) == 0) { if (udp.Listen(0) == 0) {
debug (DEBUG_ERROR | DEBUG_IFACE, "%s:%d Error could not bind UDP socket (%s)", debug (DEBUG_ERROR | DEBUG_IFACE, "%s:%d Error could not bind UDP socket (%s)",
@ -102,7 +104,14 @@ int InterfaceZ21::Loop(string interfacename) {
string source; string source;
int inlen; int inlen;
int i; int i;
int update = false; int needs_update = false;
// debug (DEBUG_INFO | DEBUG_IFACE, "* InterfaceZ21 (%s) Loop", name);
flags &= ~(INTF_F_CONNECTED | INTF_F_POWER | INTF_F_STOP | INTF_F_SHORT_CIRCUIT | INTF_F_PROGRAMMING);
if (needs_update) {
needs_update = 0;
}
if (status_connected) { if (status_connected) {
// //
@ -110,14 +119,14 @@ int InterfaceZ21::Loop(string interfacename) {
if ((timeout + 2 * INTF_Z21_TIMEOUT) < curtime) { 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 (DEBUG_ERROR | DEBUG_IFACE, "%s:%d connection timed out (%d)", __FILE__, __LINE__, curtime-(timeout + 2 * INTF_Z21_TIMEOUT));
Disconnect(); Disconnect();
update = true; needs_update = true;
} }
else if (send_logon == false && (timeout + INTF_Z21_TIMEOUT) < curtime) { else if (send_logon == false && (timeout + INTF_Z21_TIMEOUT) < curtime) {
send_logon = true; send_logon = true;
send_GET_SERIAL_NUMBER(); send_GET_SERIAL_NUMBER();
send_SET_BROADCASTFLAGS(); send_SET_BROADCASTFLAGS();
timeout = time(NULL); timeout = time(NULL);
update = true; needs_update = true;
} }
// //
@ -173,7 +182,7 @@ int InterfaceZ21::Loop(string interfacename) {
debug (0, "%s:%d cs:%d csex:%d", __FILE__, __LINE__, cs, csex); debug (0, "%s:%d cs:%d csex:%d", __FILE__, __LINE__, cs, csex);
update = true; needs_update = true;
//if ( old_poweron != status_poweron || //if ( old_poweron != status_poweron ||
// old_shortcircuit != status_shortcircuit || // old_shortcircuit != status_shortcircuit ||
// old_programmingmode != status_programmingmode || // old_programmingmode != status_programmingmode ||
@ -286,7 +295,7 @@ int InterfaceZ21::Loop(string interfacename) {
} }
} }
return update; return needs_update;
}; };
@ -294,14 +303,14 @@ int InterfaceZ21::Loop(string interfacename) {
// send_SET_BROADCASTFLAGS(); // send_SET_BROADCASTFLAGS();
void InterfaceZ21::send_SET_BROADCASTFLAGS() { void InterfaceZ21::send_SET_BROADCASTFLAGS() {
unsigned char buffer[] = { 0x08, 0x00, 0x50, 0x00, 0x0F, 0x01, 0x00, 0x03 }; unsigned char buffer[] = { 0x08, 0x00, 0x50, 0x00, 0x0F, 0x01, 0x00, 0x03 };
udp.Write(hostname, (char*)buffer, sizeof (buffer)); udp.Write(host, (char*)buffer, sizeof (buffer));
} }
// //
// send_GET_SERIAL_NUMBER // send_GET_SERIAL_NUMBER
void InterfaceZ21::send_GET_SERIAL_NUMBER() { void InterfaceZ21::send_GET_SERIAL_NUMBER() {
unsigned char buffer[] = { 0x04, 0x00, 0x10, 0x00 }; unsigned char buffer[] = { 0x04, 0x00, 0x10, 0x00 };
udp.Write(hostname, (char*)buffer, sizeof (buffer)); udp.Write(host, (char*)buffer, sizeof (buffer));
} }
@ -311,7 +320,7 @@ void InterfaceZ21::send_RM_GETDATA(int group) {
unsigned char buffer[] = { 0x05, 0x00, 0x81, 0x00, 0x00 }; unsigned char buffer[] = { 0x05, 0x00, 0x81, 0x00, 0x00 };
if (group < INTF_Z21_RMSENSOR_GROUPS) { if (group < INTF_Z21_RMSENSOR_GROUPS) {
buffer[4] = (unsigned char)group; buffer[4] = (unsigned char)group;
udp.Write(hostname, (char*)buffer, sizeof (buffer)); udp.Write(host, (char*)buffer, sizeof (buffer));
} }
} }
@ -322,7 +331,7 @@ void InterfaceZ21::send_LOGOFF() {
if (status_connected == false) return; if (status_connected == false) return;
unsigned char buffer[] = { 0x04, 0x00, 0x30, 0x00 }; unsigned char buffer[] = { 0x04, 0x00, 0x30, 0x00 };
udp.Write(hostname, (char*)buffer, sizeof (buffer)); udp.Write(host, (char*)buffer, sizeof (buffer));
} }
@ -383,7 +392,7 @@ void InterfaceZ21::SetLocoSpeed(Locomotive *l, int step) {
printf ("%02x:", z); printf ("%02x:", z);
} }
printf ("\n"); printf ("\n");
udp.Write(hostname, (char*)buffer, sizeof (buffer)); udp.Write(host, (char*)buffer, sizeof (buffer));
loconet_last.addr = l->addr; loconet_last.addr = l->addr;
loconet_last.dir = l->flags & LOCO_F_REVERSE; loconet_last.dir = l->flags & LOCO_F_REVERSE;
loconet_last.speed = l->speed; loconet_last.speed = l->speed;
@ -404,6 +413,17 @@ void InterfaceZ21::SetLocoFunction(Locomotive *l, int func, int value) {
void InterfaceZ21::SetTurnout(Turnout *t, int activate, int outputactive) { void InterfaceZ21::SetTurnout(Turnout *t, int activate, int outputactive) {
unsigned char buffer[] = { 0x09, 0x00, 0x40, 0x00, 0x53, 0x00, 0x00, 0x00, 0x00 }; 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);
//
//
if (outputactive == 1 && timer_get(&turnouttimeout) < 100) {
debug (0, "%s:%d Interface need to wait between two turnout commands", __FILE__, __LINE__);
return;
}
timer_start(&turnouttimeout);
// //
// setup turnout addr // setup turnout addr
buffer[Z21_IDX_SETTURNOUT_ADRL] = (unsigned char) (t->addr & 0xFF); buffer[Z21_IDX_SETTURNOUT_ADRL] = (unsigned char) (t->addr & 0xFF);
@ -420,14 +440,14 @@ void InterfaceZ21::SetTurnout(Turnout *t, int activate, int outputactive) {
for (int i = 4; i < (int) sizeof (buffer)-1; i++) for (int i = 4; i < (int) sizeof (buffer)-1; i++)
buffer[Z21_IDX_SETTURNOUT_CHK] = (unsigned char)buffer[Z21_IDX_SETTURNOUT_CHK] xor (unsigned char)buffer[i]; buffer[Z21_IDX_SETTURNOUT_CHK] = (unsigned char)buffer[Z21_IDX_SETTURNOUT_CHK] xor (unsigned char)buffer[i];
/* printf ("Send Data:"); udp.Write(host, (char*)buffer, sizeof (buffer));
for (int i = 0; i < sizeof (buffer); i++) {
int z = (unsigned char) buffer[i]; //
printf ("%02x:", z); // set the output flag
} if (outputactive) t->flags |= TURNOUT_F_ACTIVE;
printf ("\n"); else t->flags &= ~TURNOUT_F_ACTIVE;
*/ gettimeofday (&t->activatetime, NULL);
udp.Write(hostname, (char*)buffer, sizeof (buffer));
}; };
@ -438,9 +458,9 @@ void InterfaceZ21::PowerOnOff(int onoff) {
if (status_connected == false) return; if (status_connected == false) return;
if (onoff) { if (onoff) {
udp.Write(hostname, (char*)TX_X_SET_TRACK_POWER_ON, sizeof (TX_X_SET_TRACK_POWER_ON)); udp.Write(host, (char*)TX_X_SET_TRACK_POWER_ON, sizeof (TX_X_SET_TRACK_POWER_ON));
} }
else { else {
udp.Write(hostname, (char*)TX_X_SET_TRACK_POWER_OFF, sizeof (TX_X_SET_TRACK_POWER_OFF)); udp.Write(host, (char*)TX_X_SET_TRACK_POWER_OFF, sizeof (TX_X_SET_TRACK_POWER_OFF));
} }
}; };

@ -28,9 +28,8 @@ struct s_loconet_map{
int maxspeed; int maxspeed;
}; };
class InterfaceZ21 { class InterfaceZ21: public Interface {
private: private:
string hostname;
string serial; string serial;
char inbuffer[INTF_Z21_INBUFFER]; char inbuffer[INTF_Z21_INBUFFER];
struct s_loconet_map loconet_map[INTF_Z21_LOCONET_MAXADDR]; struct s_loconet_map loconet_map[INTF_Z21_LOCONET_MAXADDR];
@ -39,6 +38,7 @@ class InterfaceZ21 {
UDP udp; UDP udp;
time_t timeout; time_t timeout;
time_t rmgetdatatimeout; time_t rmgetdatatimeout;
struct timeval turnouttimeout;
bool send_logon; bool send_logon;
bool status_poweron; bool status_poweron;
@ -61,7 +61,7 @@ class InterfaceZ21 {
InterfaceZ21(); InterfaceZ21();
~InterfaceZ21(); ~InterfaceZ21();
void Connect(string destination); void Connect();
void Disconnect(); void Disconnect();
bool IsConnected() { return status_connected; }; bool IsConnected() { return status_connected; };

@ -10,12 +10,13 @@
// ************************************************************************** // **************************************************************************
Interface::Interface() { Interface::Interface() {
debug (DEBUG_INFO | DEBUG_IFACE, "Interface:%s", __FUNCTION__);
name[0] = 0; name[0] = 0;
host[0] = 0; host[0] = 0;
flags = 0; flags = 0;
type = INTF_T_OFF_UNKNOWN; type = INTF_T_OFF_UNKNOWN;
needs_update = true; needs_update = true;
timer_start(&turnouttimeout);
}; };
Interface::~Interface() { Interface::~Interface() {
@ -24,31 +25,16 @@ Interface::~Interface() {
void Interface::Connect () { void Interface::Connect () {
debug (DEBUG_INFO | DEBUG_IFACE, "* Interface (%s) Connect to %s", name, host); debug (DEBUG_INFO | DEBUG_IFACE, "* Interface (%s) Connect to %s", name, host);
switch (type) {
case INTF_T_Z21: intz21.Connect(host); break;
default: break;
}
}; };
void Interface::Disconnect() { void Interface::Disconnect() {
debug (DEBUG_INFO | DEBUG_IFACE, "* Interface (%s) Disconnect", name); debug (DEBUG_INFO | DEBUG_IFACE, "* Interface (%s) Disconnect", name);
switch (type) {
case INTF_T_Z21: intz21.Disconnect(); break;
default: break;
}
}; };
void Interface::PowerOnOff(int onoff) { void Interface::PowerOnOff(int onoff) {
debug (DEBUG_INFO | DEBUG_IFACE, "* Interface (%s) PowerOnOff %d", name, onoff); debug (DEBUG_INFO | DEBUG_IFACE, "* Interface (%s) PowerOnOff %d", name, onoff);
switch (type) {
case INTF_T_Z21: intz21.PowerOnOff(onoff); break;
default: break;
}
}; };
/* /*
@ -61,25 +47,6 @@ void Interface::SetTurnout(Turnout *t, int active, int outputactive) {
debug (DEBUG_INFO | DEBUG_IFACE, "%s:%d Interface (%s) SetTurnout Addr:%d Acitve:%d Output:%d", __FILE__, __LINE__, name, debug (DEBUG_INFO | DEBUG_IFACE, "%s:%d Interface (%s) SetTurnout Addr:%d Acitve:%d Output:%d", __FILE__, __LINE__, name,
t->addr, active, outputactive); t->addr, active, outputactive);
//
//
if (outputactive == 1 && timer_get(&turnouttimeout) < 100) {
debug (0, "%s:%d Interface need to wait between two turnout commands", __FILE__, __LINE__);
return;
}
timer_start(&turnouttimeout);
switch (type) {
case INTF_T_Z21: intz21.SetTurnout(t, active, outputactive); break;
default: break;
}
//
// set the output flag
if (outputactive) t->flags |= TURNOUT_F_ACTIVE;
else t->flags &= ~TURNOUT_F_ACTIVE;
gettimeofday (&t->activatetime, NULL);
}; };
// //
@ -87,329 +54,42 @@ void Interface::SetTurnout(Turnout *t, int active, int outputactive) {
// //
void Interface::SetLocoSpeed(Locomotive *l, int step) { void Interface::SetLocoSpeed(Locomotive *l, int step) {
debug (DEBUG_INFO | DEBUG_IFACE, "* Interface (%s) SetLocoSpeed Addr:%d Speed:%d ", name, l->addr, step); debug (DEBUG_INFO | DEBUG_IFACE, "* Interface (%s) SetLocoSpeed Addr:%d Speed:%d ", name, l->addr, step);
switch (type) {
case INTF_T_Z21: intz21.SetLocoSpeed(l, step); break;
default: break;
}
}; };
void Interface::SetLocoFunction(Locomotive *l, int func, int value) { 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 (DEBUG_INFO | DEBUG_IFACE, "* Interface (%s) SetLocoFunction Addr:%d Func:%d:%d", name, l->addr, func, value);
switch (type) {
case INTF_T_Z21: intz21.SetLocoFunction(l, func, value); break;
default: break;
}
}; };
//
// if update is needed return 1
//
int Interface::Loop() { int Interface::Loop() {
int ret = 0; 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); flags &= ~(INTF_F_CONNECTED | INTF_F_POWER | INTF_F_STOP | INTF_F_SHORT_CIRCUIT | INTF_F_PROGRAMMING);
if (needs_update) { if (needs_update) {
ret = 1; ret = 1;
needs_update = 0; needs_update = 0;
} }
switch (type) {
case INTF_T_Z21:
ret = intz21.Loop(name);
if (intz21.IsConnected()) flags |= INTF_F_CONNECTED;
if (intz21.IsPoweron()) flags |= INTF_F_POWER;
if (intz21.IsEmergencyStop()) flags |= INTF_F_STOP;
if (intz21.IsSortCircuit()) flags |= INTF_F_SHORT_CIRCUIT;
break;
default: break;
}
// debug (DEBUG_INFO | DEBUG_IFACE, "%s:%d Interface: name:'%s' , Flags: %d", __FILE__, __LINE__, name, flags);
return ret; return ret;
}; };
bool Interface::IsConnected() { bool Interface::IsConnected() {
bool ret = false; bool ret = false;
debug (DEBUG_INFO | DEBUG_IFACE, "* Interface (%s) IsConnected", name);
switch (type) {
case INTF_T_Z21: ret = intz21.IsConnected(); break;
default: break;
}
return ret; return ret;
} }
bool Interface::IsPoweron() { bool Interface::IsPoweron() {
bool ret = false; bool ret = false;
debug (DEBUG_INFO | DEBUG_IFACE, "* Interface (%s) IsPoweron", name);
switch (type) {
case 1: ret = intz21.IsPoweron(); break;
default: break;
}
return ret; return ret;
} }
// **************************************************************************
// *
// * I N T E R F A C E S (gateway to all devices)
// *
// **************************************************************************
Interfaces::Interfaces () {
max = INTERFACES_MAX;
changed = 0;
};
Interfaces::~Interfaces() {
max = 0;
};
int Interfaces::LockThread() {
if (pthread_mutex_lock(&mtx) == 0) return 1;
else return 0;
}
int Interfaces::UnLockThread() {
if (pthread_mutex_unlock(&mtx) == 0) return 1;
else return 0;
}
JSONParse Interfaces::_GetJSON(int idx) {
JSONParse json;
JSONElement je;
string s = "";
json.Clear();
s = interfaces[idx].name; json.AddObject("name", s);
s = interfaces[idx].host; json.AddObject("host", s);
json.AddObject("flags", interfaces[idx].flags);
json.AddObject("type", interfaces[idx].type);
return json;
};
JSONParse Interfaces::GetJSON(string name) {
int i;
JSONParse jp;
jp.Clear();
LockThread();
for (i = 0; i < max; i++) if (interfaces[i].name[0] != 0) {
if (name.compare(interfaces[i].name) == 0) {
jp = _GetJSON(i);
}
}
UnLockThread();
return jp;
};
void Interfaces::GetJSONAll(JSONParse *json) {
int i, cnt;
JSONElement je;
LockThread();
//
// write all railway data
// create json object array manualy
je.type = JSON_T_ARRAY;
je.name = "interfaces";
for (cnt = 0, i = 0; i < max; i++)
if (interfaces[i].name[0] != 0) {
if (cnt != 0) je.value += ","; // not first element
je.value += _GetJSON(i).ToString();
cnt++;
}
json->AddObject(je);
UnLockThread();
};
Interface Interfaces::GetInterfaceFromJSON(JSONParse *j) {
Interface i;
string s;
i.name[0] = 0;
i.host[0] = 0;
j->GetValue("name", &s);
strncpy (i.name, s.c_str(), REFERENCENAME_LEN);
j->GetValue("host", &s);
strncpy (i.host, s.c_str(), REFERENCENAME_LEN);
j->GetValueInt("flags", &i.flags);
j->GetValueInt("type", &i.type);
return i;
};
int Interfaces::Change(Interface *iface) {
int i;
int ifree = -1;
LockThread();
for (i = 0; i < max; i++) {
if (interfaces[i].name[0] != 0) {
// found element
if (strncmp(interfaces[i].name, iface->name, REFERENCENAME_LEN) == 0) {
ifree = i;
break;
}
}
else if (ifree == -1) ifree = i;
}
// element not found add new element
if (ifree != -1 && ifree < max) {
strncpy (interfaces[ifree].name, iface->name, REFERENCENAME_LEN);
strncpy (interfaces[ifree].host, iface->host, REFERENCENAME_LEN);
interfaces[ifree].flags = iface->flags;
interfaces[ifree].type = iface->type;
interfaces[ifree].Connect();
}
changed = 1;
UnLockThread();
return 1;
};
int Interfaces::Delete(string name) {
int i;
LockThread();
for (i = 0; i < max; i++) if (interfaces[i].name[0] != 0) {
if (name.compare(interfaces[i].name) == 0) {
interfaces[i].Disconnect();
interfaces[i].name[0] = 0;
interfaces[i].host[0] = 0;
interfaces[i].flags = 0;
interfaces[i].type = INTF_T_OFF_UNKNOWN;
changed = 1;
break;
}
}
UnLockThread();
return 1;
};
void Interfaces::PowerOnOff(int onoff) {
int i;
LockThread();
for (i = 0; i < max; i++) if (interfaces[i].name[0] != 0) {
if (!interfaces[i].IsConnected()) interfaces[i].Connect();
interfaces[i].PowerOnOff(onoff);
}
UnLockThread();
};
//
// Turnouts
//
void Interfaces::SetTurnout(Turnout *t, int active, int motoractive) {
int i;
if (t == NULL) return;
LockThread();
debug (0, "%s:%d Interfaces::SetTurnout Name:%s active:%d Output%d", __FILE__, __LINE__, t->name, active, motoractive);
for (i = 0; i < max; i++) if (interfaces[i].name[0] != 0) {
if (!interfaces[i].IsConnected()) interfaces[i].Connect();
if (strncmp(t->ifname, interfaces[i].name, REFERENCENAME_LEN) == 0)
interfaces[i].SetTurnout(t, active, motoractive);
}
UnLockThread();
};
//
// Locomotives
//
void Interfaces::SetLocoSpeed(Locomotive *l, int speed) {
int i;
int step = 0, maxstep = 0;
switch(l->stepcode) {
case LOCO_INT_DCC14: maxstep = 14; break;
case LOCO_INT_DCC28: maxstep = 28; break;
case LOCO_INT_DCC128: maxstep = 126; break;
default: maxstep = 0; break;
}
if (abs(speed) < l->vmin) step = 0;
if (abs(speed) >= l->vmin) step = (speed * (maxstep)) / l->vmax;
if (abs(speed) > l->vmax) step = maxstep;
l->speed = speed;
LockThread();
for (i = 0; i < max; i++) if (interfaces[i].name[0] != 0) {
if (!interfaces[i].IsConnected()) interfaces[i].Connect();
if (strncmp(l->ifname, interfaces[i].name, REFERENCENAME_LEN) == 0)
interfaces[i].SetLocoSpeed(l, step);
}
UnLockThread();
};
void Interfaces::SetLocoFunction(Locomotive *l, int func, int value) {
int i;
LockThread();
for (i = 0; i < max; i++) if (interfaces[i].name[0] != 0) {
if (!interfaces[i].IsConnected()) interfaces[i].Connect();
if (strncmp(l->ifname, interfaces[i].name, REFERENCENAME_LEN) == 0)
interfaces[i].SetLocoFunction(l, func, value);
}
UnLockThread();
};
void Interfaces::Loop() {
int i;
JSONParse jout;
for (i = 0; i < max; i++) if (interfaces[i].name[0] != 0) {
if (interfaces[i].Loop()) {
//
// now we need to send an update
jout.Clear();
jout.AddObject ("interface", _GetJSON(i));
if (network) network->ChangeListPushToAll(jout.ToString());
}
}
};

@ -6,7 +6,6 @@
#include "server.h" #include "server.h"
#include "UDPTCPNetwork.h" #include "UDPTCPNetwork.h"
#include "json.h" #include "json.h"
#include "interface-z21.h"
#define INTF_F_CONNECTED 0x0001 #define INTF_F_CONNECTED 0x0001
#define INTF_F_POWER 0x0002 #define INTF_F_POWER 0x0002
@ -15,15 +14,10 @@
#define INTF_F_PROGRAMMING 0x0010 #define INTF_F_PROGRAMMING 0x0010
#define INTF_F_NEEDUPDATE 0x8000 // if something changes during the Loop #define INTF_F_NEEDUPDATE 0x8000 // if something changes during the Loop
#define INTF_T_OFF_UNKNOWN 0
#define INTF_T_Z21 1
class Interface { class Interface {
private: private:
InterfaceZ21 intz21;
bool needs_update; bool needs_update;
struct timeval turnouttimeout;
public: public:
char name[REFERENCENAME_LEN]; char name[REFERENCENAME_LEN];
char host[NET_HOSTLEN]; char host[NET_HOSTLEN];
@ -31,57 +25,20 @@ public:
int type; int type;
Interface(); Interface();
~Interface(); virtual ~Interface();
void Connect();
void Disconnect();
void PowerOnOff(int onoff);
void SetLocoSpeed(Locomotive *l, int step);
void SetLocoFunction(Locomotive *l, int func, int value);
void SetTurnout(Turnout *t, int active, int motoractive);
bool IsConnected();
bool IsPoweron();
int Loop();
};
class Interfaces {
private:
Interface interfaces[INTERFACES_MAX];
int max;
int changed;
pthread_mutex_t mtx;
int LockThread();
int UnLockThread();
// not thread safe
JSONParse _GetJSON(int idx);
public:
Interfaces();
~Interfaces();
bool IsChanged() { return changed; }
void ClearChanged() { changed = 0; };
int Change(Interface *iface); virtual void Connect();
int Delete(string name); virtual void Disconnect();
JSONParse GetJSON(string name); virtual void PowerOnOff(int onoff);
void GetJSONAll(JSONParse *json); virtual void SetLocoSpeed(Locomotive *l, int step);
Interface GetInterfaceFromJSON(JSONParse *j); virtual void SetLocoFunction(Locomotive *l, int func, int value);
virtual void SetTurnout(Turnout *t, int active, int motoractive);
// virtual bool IsConnected();
// virtual bool IsPoweron();
void PowerOnOff(int onoff);
void SetLocoSpeed(Locomotive *l, int speed);
void SetLocoFunction(Locomotive *l, int func, int value);
void SetTurnout(Turnout *t, int active, int outputactive);
void Loop(); virtual int Loop();
}; };
#endif #endif

@ -117,11 +117,15 @@ int Interfaces::Change(Interface *iface) {
int i; int i;
int ifree = -1; int ifree = -1;
printf ("Interface Type:%d\n", iface->type);
LockThread(); LockThread();
for (i = 0; i < max; i++) { for (i = 0; i < max; i++) {
if (interfaces[i] != NULL) { if (interfaces[i] != NULL) {
// found element // found element
if (strncmp(interfaces[i]->name, iface->name, REFERENCENAME_LEN) == 0) { if (strncmp(interfaces[i]->name, iface->name, REFERENCENAME_LEN) == 0) {
delete interfaces[i];
interfaces[i] = NULL;
ifree = i; ifree = i;
break; break;
} }
@ -129,7 +133,7 @@ int Interfaces::Change(Interface *iface) {
else if (ifree == -1) ifree = i; else if (ifree == -1) ifree = i;
} }
// element not found add new element // element found or we need to add the element.
if (ifree != -1 && ifree < max) { if (ifree != -1 && ifree < max) {
if (iface->type == INTF_T_Z21) interfaces[ifree] = new InterfaceZ21(); if (iface->type == INTF_T_Z21) interfaces[ifree] = new InterfaceZ21();
else interfaces[ifree] = new Interface(); else interfaces[ifree] = new Interface();

@ -1,12 +1,13 @@
#ifndef _INTERFACE_H_ #ifndef _INTERFACES_H_
#define _INTERFACE_H_ #define _INTERFACES_H_
#include "modelbahn.h" #include "modelbahn.h"
#include "server.h" #include "server.h"
#include "UDPTCPNetwork.h" #include "UDPTCPNetwork.h"
#include "json.h" #include "json.h"
#include "interface-z21.h" #include "interface.h"
#include "interfaces.h"
#define INTF_F_CONNECTED 0x0001 #define INTF_F_CONNECTED 0x0001
#define INTF_F_POWER 0x0002 #define INTF_F_POWER 0x0002
@ -15,39 +16,12 @@
#define INTF_F_PROGRAMMING 0x0010 #define INTF_F_PROGRAMMING 0x0010
#define INTF_F_NEEDUPDATE 0x8000 // if something changes during the Loop #define INTF_F_NEEDUPDATE 0x8000 // if something changes during the Loop
#define INTF_T_OFF_UNKNOWN 0 enum {
#define INTF_T_Z21 1 INTF_T_OFF_UNKNOWN = 0,
INTF_T_Z21,
INTF_T_MAX
class Interface {
private:
InterfaceZ21 intz21;
bool needs_update;
struct timeval turnouttimeout;
public:
char name[REFERENCENAME_LEN];
char host[NET_HOSTLEN];
int flags;
int type;
Interface();
virtual ~Interface();
virtual void Connect();
virtual void Disconnect();
virtual void PowerOnOff(int onoff);
virtual void SetLocoSpeed(Locomotive *l, int step);
virtual void SetLocoFunction(Locomotive *l, int func, int value);
virtual void SetTurnout(Turnout *t, int active, int motoractive);
virtual bool IsConnected();
virtual bool IsPoweron();
virtual int Loop();
}; };
class Interfaces { class Interfaces {
private: private:
Interface *interfaces[INTERFACES_MAX]; Interface *interfaces[INTERFACES_MAX];

@ -27,7 +27,7 @@
#include "railway.h" #include "railway.h"
#include "locomotive.h" #include "locomotive.h"
#include "sensor.h" #include "sensor.h"
#include "interface.h" #include "interfaces.h"
#include "block.h" #include "block.h"
enum SMODE { enum SMODE {

Loading…
Cancel
Save