#include #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; pthread_mutex_init(&mtx, NULL); 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; debug (0, "Interfaces::SetLocoSpeed Loco:'%s' Speed:%d", l->name, speed); 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; debug (0, "Interfaces::SetLocoFunction Loco:'%s' Function:%d Value:%d", l->name, func, value); 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()); } } };