#include "modelbahn.h" #include "interface.h" // ************************************************************************** // * // * I N T E R F A C E (gateway to different devices) // * // ************************************************************************** Interface::Interface() { name[0] = 0; host[0] = 0; flags = 0; type = INTF_T_OFF_UNKNOWN; needs_update = true; }; Interface::~Interface() { }; void Interface::Connect () { 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() { 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) { debug (DEBUG_INFO | DEBUG_IFACE, "* Interface (%s) PowerOnOff %d", name, onoff); switch (type) { case INTF_T_Z21: intz21.PowerOnOff(onoff); break; default: break; } }; // // Turnout // void Interface::SetTurnout(Turnout *t, int active, int motoractive) { debug (DEBUG_INFO | DEBUG_IFACE, "* Interface (%s) SetTurnout Addr:%d FinalAcitve:%d Motor:%d", name, t->addr, active, motoractive); switch (type) { case INTF_T_Z21: intz21.SetTurnout(t, active, motoractive); break; default: break; } // // make sure we turn the motor later off if (motoractive) t->flags |= TURNOUT_F_ACTIVE; else t->flags &= ~TURNOUT_F_ACTIVE; gettimeofday (&t->activatetime, NULL); }; // // Locomotive // void Interface::SetLocoSpeed(Locomotive *l, int 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) { 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; } }; int Interface::Loop() { int ret = 0; flags &= ~(INTF_F_CONNECTED | INTF_F_POWER | INTF_F_STOP | INTF_F_SHORT_CIRCUIT | INTF_F_PROGRAMMING); if (needs_update) { ret = 1; 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; }; bool Interface::IsConnected() { bool ret = false; switch (type) { case INTF_T_Z21: ret = intz21.IsConnected(); break; default: break; } return ret; } bool Interface::IsPoweron() { bool ret = false; switch (type) { case 1: ret = intz21.IsPoweron(); break; default: break; } 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; LockThread(); 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; if (abs(speed) < l->vmin) step = 0; if (abs(speed) >= l->vmin) step = (speed * (l->steps-1)) / l->vmax; if (abs(speed) > l->vmax) step = l->steps-1; 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()); } } };