00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00025 #include "Configurator.h"
00026 #include "Config.h"
00027 #include "Priority.h"
00028 #include "Parameter.h"
00029 #include "SingleValue.h"
00030 #include "BlobValue.h"
00031 #include "Address.h"
00032 #include <rcudb/Server.h>
00033 #include <rcudb/Sql.h>
00034 #include <iostream>
00035 #include <sstream>
00036 #include <stdexcept>
00037 #include <algorithm>
00038 #include "Rcu.h"
00039 #include "Bc.h"
00040 #include "Altro.h"
00041
00042
00043 RcuConf::Configurator::Configurator(RcuDb::Server& server,
00044 Rcu& rcu,
00045 Bc& bc,
00046 Altro& altro)
00047 : fServer(server),
00048 fRcu(rcu),
00049 fBc(bc),
00050 fAltro(altro),
00051 fErrorString(""),
00052 fCurrent(0),
00053 fOrder(0),
00054 fDebug(false)
00055 {}
00056
00057
00058 int
00059 RcuConf::Configurator::Write(int tag,
00060 int x,
00061 int y,
00062 int z)
00063 {
00064 if (!GetCurrent(tag, x, y, z)) return -1;
00065 if (!GetOrder()) return -1;
00066 if (!GetParams()) return -1;
00067
00068
00069 fRcu.StartBlock();
00070
00071 std::cout << "# Parameters: " << fParams.size() << std::endl;
00072 for (Parameter::List::iterator p = fParams.begin(); p != fParams.end(); ++p){
00073 Component* c = 0;
00074 std::string name;
00075 switch ((*p)->Destination()) {
00076 case Parameter::kRcu: c = &fRcu; name="Rcu"; break;
00077 case Parameter::kBc: c = &fBc; name="Bc"; break;
00078 case Parameter::kAltro: c = &fAltro; name="Altro"; break;
00079 default: c = 0; break;
00080 }
00081 if (!c) {
00082 std::stringstream s;
00083 s << "Configurator: Invalid component: " << (*p)->Destination();
00084 fErrorString = s.str();
00085 return -1;
00086 }
00087
00088 if (name == "Rcu") continue;
00089 if (fDebug)
00090 std::cout << "Processing " << name << " parameter " << (*p)->Name()
00091 << std::endl;
00092 if (!Write(*c, *(*p))) return -1;
00093 }
00094 return fRcu.EndBlock();
00095 }
00096
00097
00098 bool
00099 RcuConf::Configurator::GetCurrent(int tag,
00100 int x,
00101 int y,
00102 int z)
00103 {
00104 if (tag < 0) return false;
00105 if (fCurrent) delete fCurrent;
00106 fCurrent = 0;
00107
00108
00109
00110 bool ret = true;
00111 int tags[] = { tag, 0, 0 };
00112 int coords[] = { x, y, z, x, y, z, 0, 0, 0 };
00113 Config::List confs;
00114 for (size_t i = 0; i < 3; i++) {
00115 ret = Config::Select(confs, fServer, tags[i],
00116 coords[3*i+0], coords[3*i+1], coords[3*i+2]);
00117 if (ret && confs.size() > 0) break;
00118 if (fServer.IsError()) {
00119 std::stringstream s;
00120 s << "Configurator: Failed to get configuration for tag="
00121 << tag << " (x,y,z)=(" << x << "," << y << "," << z
00122 << ") or any of the fall-back configurations: "
00123 << fServer.ErrorString();
00124 fErrorString = s.str();
00125 return false;
00126 }
00127 }
00128
00129
00130 if (confs.size() < 1) {
00131 fErrorString = "Configurator: Didn't get any configuration";
00132 return false;
00133 }
00134
00135
00136 Config::List::iterator iter = confs.begin();
00137 fCurrent = *iter;
00138 ++iter;
00139
00140
00141 for (; iter != confs.end(); ++iter) delete *iter;
00142
00143 if (fDebug) std::cout << "Current config:\n\t" << std::flush;
00144 fCurrent->Print();
00145
00146 return ret;
00147 }
00148
00149
00150 bool
00151 RcuConf::Configurator::GetOrder()
00152 {
00153 if (fOrder) delete fOrder;
00154 fOrder = 0;
00155
00156
00157 bool ret = false;
00158 Priority::List priors;
00159 for (size_t i = 0; i < 2; i++) {
00160 if (i == 0) ret = Priority::Select(priors,fServer,*fCurrent);
00161 else ret = Priority::Select(priors,fServer,"description='default'");
00162 if (ret && priors.size() > 0) break;
00163
00164 if (fServer.IsError()) {
00165 std::stringstream s;
00166 s << "Failed to get " << (i == 0 ? " " : " default ")
00167 << "priority list";
00168 if (i == 0) s << " for configuration " << fCurrent->Id();
00169 s << ": " << fServer.ErrorString();
00170 fErrorString = s.str();
00171 return false;
00172 }
00173 }
00174 if (priors.size() <= 0) {
00175 fErrorString = "Configurator: Didn't get any priority list";
00176 return false;
00177 }
00178
00179
00180 Priority::List::iterator iter = priors.begin();
00181 fOrder = *iter;
00182 ++iter;
00183
00184
00185 for (; iter != priors.end(); ++iter) delete *iter;
00186
00187 if (fDebug) std::cout << "Current priority list:\n\t" << std::flush;
00188 fOrder->Print();
00189
00190 return ret;
00191 }
00192
00193
00194
00195 bool
00196 RcuConf::Configurator::GetParams()
00197 {
00198 for (Parameter::List::iterator i = fParams.begin(); i != fParams.end(); ++i)
00199 delete (*i);
00200 fParams.clear();
00201
00202
00203 std::vector<int> order;
00204 fOrder->Params(order);
00205 RcuDb::Sql parSel;
00206 for (std::vector<int>::iterator i = order.begin(); i != order.end(); ++i){
00207 if (i != order.begin()) parSel << " OR";
00208 parSel << " id=" << *i;
00209 }
00210
00211
00212 if (!Parameter::Select(fParams, fServer, parSel)) {
00213 std::stringstream s;
00214 s << "Configurator: Failed to get parameters: " << fServer.ErrorString();
00215 fErrorString = s.str();
00216 return false;
00217 }
00218 return true;
00219 }
00220
00221
00222 bool
00223 RcuConf::Configurator::CheckWrite(int ret,
00224 const std::string& name,
00225 int addr)
00226 {
00227 if (ret == 0) return true;
00228
00229 std::stringstream s;
00230 s << "Configurator: Failed to write " << (addr < 0 ? "broadcast " : "")
00231 << "value of " << name;
00232 if (addr >= 0) s << " to address 0x" << std::hex << addr << std::dec;
00233 s << " - ";
00234 if (ret < 0)
00235 s << "Error from Rcu++: " << fRcu.ErrorString(-ret);
00236 else {
00237 switch (ret) {
00238 case Component::kNotSupported:
00239 s << "Operation not supported for this component"; break;
00240 case Component::kUnknownParameter:
00241 s << "The parameter does not belong to this component"; break;
00242 case Component::kInvalidValue:
00243 s << "The value has wrong cardinality for the parameter"; break;
00244 case Component::kInvalidAddress:
00245 s << "Invalid address for this register";
00246 case Component::kFailure:
00247 s << "Other errors"; break;
00248 default:
00249 s << "Uknown error"; break;
00250 }
00251 }
00252 fErrorString = s.str();
00253 if (fDebug) std::cout << fErrorString << std::endl;
00254 return false;
00255 }
00256
00257
00258
00259 bool
00260 RcuConf::Configurator::Write(Component& c, Parameter& p)
00261 {
00262 int confs[] = { fCurrent->Id(), 0 };
00263 int pid = p.Id();
00264 bool ret = true;
00265 std::string tab = (p.IsBlob() ? BlobValue::fgName : SingleValue::fgName);
00266 Value::List bl;
00267
00268
00269
00270 for (size_t i = 0; i < 2; i++) {
00271 ret = Value::Select(bl, fServer, tab, confs[i], pid, -1);
00272 if (ret && bl.size() > 0) break;
00273 if (fServer.IsError()) {
00274 std::stringstream s;
00275 s << "Configurator: Failed to get broadcast values for parameter "
00276 << p.Name() << " for configuration " << fCurrent->Id();
00277 fErrorString = s.str();
00278 return ret;
00279 }
00280 }
00281
00282
00283
00284 if (bl.size() > 0) {
00285 Value* v = *(bl.begin());
00286 int ret = 0;
00287 if (p.IsBlob()) {
00288 BlobValue* b = static_cast<BlobValue*>(v);
00289 ret = c.Write(p, *b);
00290 }
00291 else {
00292 SingleValue* s = static_cast<SingleValue*>(v);
00293 ret = c.Write(p, *s);
00294 }
00295 if (!CheckWrite(ret, p.Name(), -1)) return false;
00296 }
00297
00298 Value::List ll;
00299
00300 for (size_t i = 0; i < 2; i++) {
00301 ret = Value::Select(ll, fServer, tab, confs[i], pid, 0);
00302 if (ret && ll.size() > 0) break;
00303 if (fServer.IsError()) {
00304 std::stringstream s;
00305 s << "Configurator: Failed to get local values for parameter "
00306 << p.Name() << " for configuration " << fCurrent->Id();
00307 fErrorString = s.str();
00308 return ret;
00309 }
00310 }
00311
00312
00313 int last = -1;
00314 for (Value::List::iterator i = ll.begin(); i != ll.end(); ++i) {
00315 if ((*i)->AddressId() == last) continue;
00316 last = (*i)->AddressId();
00317
00318
00319 Address::List al;
00320 if (!Address::Select(al, fServer, *(*i))) {
00321 std::stringstream s;
00322 s << "Configurator: Failed to get address for value of parameter "
00323 << p.Name() << " for configuration " << fCurrent->Id();
00324 fErrorString = s.str();
00325 return ret;
00326 }
00327
00328 if (al.size() <= 0) continue;
00329 Address* a = *(al.begin());
00330 int ret = 0;
00331 Value* v = (*i);
00332 if (p.IsBlob()) {
00333 BlobValue* b = static_cast<BlobValue*>(v);
00334 ret = c.Write(p, *b, *a);
00335 }
00336 else {
00337 SingleValue* s = static_cast<SingleValue*>(v);
00338 ret = c.Write(p, *s, *a);
00339 }
00340 if (!CheckWrite(ret, p.Name(), a->RawValue())) return false;
00341 }
00342 return true;
00343 }
00344
00345
00346
00347
00348