You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
Modelbahn/server/interfaces.cc

288 lines
6.0 KiB

#include <string>
#include "modelbahn.h"
#include "interface.h"
#include "interface-z21.h"
#include "interfaces.h"
// **************************************************************************
// *
// * I N T E R F A C E S (gateway to all devices)
// *
// **************************************************************************
Interfaces::Interfaces () {
max = INTERFACES_MAX;
for (int i = 0; i < max; i++) interfaces[i] = NULL;
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();
if (interfaces[idx] != NULL) {
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] != NULL){
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] != NULL)
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;
printf ("Interface Type:%d\n", iface->type);
LockThread();
for (i = 0; i < max; i++) {
if (interfaces[i] != NULL) {
// found element
if (strncmp(interfaces[i]->name, iface->name, REFERENCENAME_LEN) == 0) {
delete interfaces[i];
interfaces[i] = NULL;
ifree = i;
break;
}
}
else if (ifree == -1) ifree = i;
}
// element found or we need to add the element.
if (ifree != -1 && ifree < max) {
if (iface->type == INTF_T_Z21) interfaces[ifree] = new InterfaceZ21();
else interfaces[ifree] = new Interface();
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] != NULL) {
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;
delete interfaces[i];
interfaces[i] = NULL;
changed = 1;
break;
}
}
UnLockThread();
return 1;
};
void Interfaces::PowerOnOff(int onoff) {
int i;
LockThread();
for (i = 0; i < max; i++) if (interfaces[i] != NULL) {
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);
//
// if the interfacename is debug ... simulate a change in the turnout
//
if (strncmp(t->ifname, "DEBUG", REFERENCENAME_LEN) == 0) {
if (active) t->flags |= TURNOUT_F_ACTIVE;
else t->flags &= ~TURNOUT_F_ACTIVE;
server->TurnoutAddrMode(t->ifname, t->addr, active);
}
else {
for (i = 0; i < max; i++) if (interfaces[i] != NULL) {
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] != NULL) {
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] != NULL) {
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] != NULL) {
if (interfaces[i]->Loop()) {
//
// now we need to send an update
jout.Clear();
jout.AddObject ("interface", _GetJSON(i));
if (network) network->ChangeListPushToAll(jout.ToString());
}
}
};