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/block.cc

344 lines
6.1 KiB

#include "modelbahn.h"
#include "block.h"
Blocks::Blocks () {
changed = 0;
blocks = (Block*) malloc(sizeof(Block)*SENSORS_MAX);
max = BLOCKS_MAX;
last_blockidx = -1;
};
Blocks::~Blocks() {
free (blocks);
blocks = NULL;
max = 0;
};
int Blocks::Lock() {
if (pthread_mutex_lock(&mtx) == 0) return 1;
else return 0;
}
int Blocks::UnLock() {
if (pthread_mutex_unlock(&mtx) == 0) return 1;
else return 0;
}
JSONParse Blocks::_GetJSON(Block *bl) {
JSONParse json;
JSONElement je;
string s = "";
json.Clear();
s = bl->name; json.AddObject("name", s);
json.AddObject("flags", bl->flags);
json.AddObject("lockedby", bl->lockedby);
json.AddObject("sensor_pos_1", bl->s_pos_1);
json.AddObject("sensor_center", bl->s_center);
json.AddObject("sensor_neg_1", bl->s_neg_1);
return json;
};
JSONParse Blocks::GetJSON(string name) {
int i;
JSONParse jp;
jp.Clear();
Lock();
for (i = 0; i < max; i++) if (blocks[i].name[0] != 0) {
if (name.compare(blocks[i].name) == 0) {
jp = _GetJSON(i);
}
}
UnLock();
return jp;
};
void Blocks::GetJSONAll(JSONParse *json) {
int i, cnt;
JSONElement je;
Lock();
//
// write all railway data
// create json object array manualy
je.type = JSON_T_ARRAY;
je.name = "blocks";
for (cnt = 0, i = 0; i < max; i++)
if (blocks[i].name[0] != 0) {
if (cnt != 0) je.value += ","; // not first element
je.value += _GetJSON(i).ToString();
cnt++;
}
json->AddObject(je);
UnLock();
};
Block Blocks::GetBlockFromJSON(JSONParse *j) {
Block bl;
string s;
bl.name[0] = 0;
bl.flags = 0;
j->GetValue("name", &s);
strncpy (bl.name, s.c_str(), REFERENCENAME_LEN);
j->GetValueInt("flags", &bl.flags);
// j->GetValue("lockedby", &s);
// strncpy (bl.lockedby, s.c_str(), REFERENCENAME_LEN);
s = ""; j->GetValue("sensor_pos_1", &s);
strncpy (bl.s_pos_1, s.c_str(), REFERENCENAME_LEN);
s = ""; j->GetValue("sensor_center", &s);
strncpy (bl.s_center, s.c_str(), REFERENCENAME_LEN);
s = ""; j->GetValue("sensor_neg_1", &s);
strncpy (bl.s_neg_1, s.c_str(), REFERENCENAME_LEN);
printf ("%s:%d Sensor (%s ---> %s ---> %s\n", __FILE__, __LINE__, bl.s_pos_1, bl.s_center, bl.s_neg_1);
return bl;
};
int Blocks::Change(Block *bl) {
int i;
int ifree = -1;
Lock();
for (i = 0; i < max; i++) {
if (blocks[i].name[0] != 0) {
// found element
if (strncmp(blocks[i].name, bl->name, REFERENCENAME_LEN) == 0) {
ifree = i;
break;
}
}
else if (ifree == -1) ifree = i;
}
// element not found add new element
if (ifree != -1 && ifree < max) {
blocks[ifree] = *bl;
strncpy (blocks[ifree].name, bl->name, REFERENCENAME_LEN);
}
changed = 1;
UnLock();
return 1;
};
int Blocks::Delete(string name) {
int i;
Lock();
for (i = 0; i < max; i++) if (blocks[i].name[0] != 0) {
if (name.compare(blocks[i].name) == 0) {
blocks[i].name[0] = 0;
blocks[i].flags = 0;
changed = 1;
break;
}
}
UnLock();
return 1;
};
//
// thread will not be locked..
int Blocks::SetOff(string blname) {
Block *bl = NULL;
JSONParse jp;
Lock();
if ((bl = FindBlock(blname)) != NULL) {
changed = 1;
bl->flags |= BLOCK_F_OFF;
printf ("%s:%d set block %s off", __FILE__, __LINE__, bl->name);
jp.AddObject("block",_GetJSON(bl));
if(network) network->ChangeListPushToAll(jp.ToString());
UnLock();
return 1;
}
UnLock();
return 1;
};
int Blocks::IsOff(string blname) {
// return -1 if not found, 0 on no lock, 1 on lock
Block *bl = NULL;
int res = -1;
Lock();
if ((bl = FindBlock(blname)) != NULL) {
if (bl->flags & BLOCK_F_OFF) res = 1;
else res = 0;
}
UnLock();
return res;
};
int Blocks::SetLockedby (string blname, string lockedby, int lock_onoff) {
// return -1 if not found, 0 on no lock, 1 on lock
Block *bl = NULL;
JSONParse jp;
int res = -1;
Lock();
if ((bl = FindBlock(blname)) != NULL) {
if (lockedby.compare (bl->lockedby) == 0) res = 1;
else if (bl->lockedby[0] == 0) {
strncpy (bl->lockedby, lockedby.c_str(), REFERENCENAME_LEN);
jp.AddObject("block",_GetJSON(bl));
if(network) network->ChangeListPushToAll(jp.ToString());
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);
res = 0;
}
}
else {
debug (0, "Blocks::SetLockedby could not find block '%s'.", blname.c_str());
}
UnLock();
return res;
};
string Blocks::GetLockedby (string blname) {
Block *bl = NULL;
string lb;
Lock();
if ((bl = FindBlock(blname)) != NULL) {
lb = bl->lockedby;
UnLock();
return lb;
}
UnLock();
return "";
};
Block* Blocks::FindBlock(string name) {
Block *bl = NULL;
if (last_blockidx >= 0 && last_blockidx < max)
if (name.compare (blocks[last_blockidx].name) == 0)
return &blocks[last_blockidx];
for (last_blockidx = 0; last_blockidx < max; last_blockidx++) {
if (name.compare (blocks[last_blockidx].name) == 0)
return &blocks[last_blockidx];
}
return bl;
};
int Blocks::Clear(string name) {
Block *bl = NULL;
Lock();
if ((bl = FindBlock(name)) != NULL) {
changed = 1;
bl->flags &= ~BLOCK_F_OFF;
printf ("%s:%d clear block %s off", __FILE__, __LINE__, bl->name);
UnLock();
return 1;
}
UnLock();
return 0;
};
void Blocks::ClearLockedby(string name) {
int i;
JSONParse jp;
Lock();
for (i = 0; i < max; i++) {
if (name.compare(blocks[i].lockedby) == 0) {
blocks[i].lockedby[0] = 0;
changed = 1;
jp.AddObject("block",_GetJSON(i));
if(network) network->ChangeListPushToAll(jp.ToString());
}
}
UnLock();
};
string Blocks::GetSensorMinus (string blname) {
string res = "";
int i;
JSONParse jp;
Lock();
for (i = 0; i < max; i++) if (blname.compare(blocks[i].name) == 0) {
res = blocks[i].s_neg_1;
}
UnLock();
return res;
};
string Blocks::GetSensorCenter (string blname) {
string res = "";
int i;
JSONParse jp;
Lock();
for (i = 0; i < max; i++) if (blname.compare(blocks[i].name) == 0) {
res = blocks[i].s_center;
}
UnLock();
return res;
};
string Blocks::GetSensorPlus (string blname) {
string res = "";
int i;
JSONParse jp;
Lock();
for (i = 0; i < max; i++) if (blname.compare(blocks[i].name) == 0) {
res = blocks[i].s_pos_1;
}
UnLock();
return res;
};