Configurator.cxx

Go to the documentation of this file.
00001 // -*- mode: C++ -*- 
00002 //
00003 // Copyright (C) 2006 Christian Holm Christensen <cholm@nbi.dk>
00004 //
00005 // This library is free software; you can redistribute it and/or
00006 // modify it under the terms of the GNU Lesser General Public License
00007 // as published by the Free Software Foundation; either version 2.1
00008 // of the License, or (at your option) any later version.
00009 //
00010 // This library is distributed in the hope that it will be useful,
00011 // but WITHOUT ANY WARRANTY; without even the implied warranty of
00012 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00013 // Lesser General Public License for more details.
00014 //
00015 // You should have received a copy of the GNU Lesser General Public
00016 // License along with this library; if not, write to the Free
00017 // Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
00018 // 02111-1307 USA
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   // Start a configuration block 
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     // For testing, we ignore the RCU commands 
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   // Try specified configuration, fall-back for this RCU, and general
00109   // fall-back. 
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   // Check that we actually something back 
00130   if (confs.size() < 1) {
00131     fErrorString = "Configurator: Didn't get any configuration";
00132     return false;
00133   }
00134 
00135   // Get the identifier of the configuration 
00136   Config::List::iterator iter = confs.begin();
00137   fCurrent                    = *iter;
00138   ++iter;
00139 
00140   // Clean up result set 
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   // Try the specified order 
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   // Get the identifier of the Priority list
00180   Priority::List::iterator iter = priors.begin();
00181   fOrder                        = *iter;
00182   ++iter;
00183 
00184   // Clean up result set 
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   // Get the parameters we need 
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   // Get the parameters 
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   // std::cout << "Processing parameter " << p.Name() << std::endl;
00269   // First, we try to get the broadcast values 
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   // std::cout << "Got back " << bl.size() << " matches" << std::endl;
00282   
00283   // Try to write newest broadcast value 
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   // Then, try to get he local values
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   // Loop over the local variables 
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     // Try to get the address from the database 
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     // This is silently ignored
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 // EOF
00348 //
Top of page Last update Fri Apr 27 01:54:15 2007
Copyright © 2004 Christian Holm Created by DoxyGen 1.3.5