solarpowerlog trunk
/home/tobi/workspace/solarpowerlog/src/Connections/CSharedConnectionSlave.cpp
Go to the documentation of this file.
00001 /*
00002  * CConnectSlave.cpp
00003  *
00004  *  Created on: Sep 13, 2010
00005  *      Author: tobi
00006  */
00007 
00008 #ifdef HAVE_CONFIG_H
00009 #include "config.h"
00010 #include "porting.h"
00011 #endif
00012 
00013 #ifdef HAVE_COMMS_SHAREDCONNECTION
00014 
00015 #include "CSharedConnectionSlave.h"
00016 #include "configuration/CConfigHelper.h"
00017 #include "Inverters/interfaces/InverterBase.h"
00018 #include "CSharedConnection.h"
00019 
00020 // Slave Configuration Parameter
00021 // useconnection = "name"  Name of the inverter having the master connection.
00022 // timeout = "override for timeout if not specified for receive operations. Unit ms"
00023 
00024 
00025 CSharedConnectionSlave::CSharedConnectionSlave(const string & configurationname) :
00026      IConnect(configurationname)
00027 {
00028      master = NULL;
00029 }
00030 
00031 CSharedConnectionSlave::~CSharedConnectionSlave()
00032 {
00033 }
00034 
00035 bool CSharedConnectionSlave::Connect(ICommand *callback)
00036 {
00037      assert(master);
00038      return master->Connect(callback);
00039 }
00040 
00041 bool CSharedConnectionSlave::Disconnect(ICommand *callback)
00042 {
00043      // only the master will be allowed to disconnect for the time being.
00044      assert(master);
00045      callback->addData(ICMD_ERRNO, 0);
00046      Registry::GetMainScheduler()->ScheduleWork(callback);
00047      return true;
00048 }
00049 
00050 bool CSharedConnectionSlave::Send(const char *tosend, unsigned int len,
00051           ICommand *callback)
00052 {
00053      assert(master);
00054      return master->Send(tosend, len, callback);
00055 }
00056 
00057 bool CSharedConnectionSlave::Send(const string& tosend, ICommand *callback)
00058 {
00059      assert(master);
00060      return master->Send(tosend, callback);
00061 }
00062 
00063 bool CSharedConnectionSlave::Receive(ICommand *callback)
00064 {
00065      assert(master);
00066 
00067      // If there is no timeout specified in the callback, derive it from
00068      // the configuration or default. (The master does not have access to the
00069      // slaves configuration, so we have to make it sure here...)
00070 #warning configuration parameter: check in configcheck() and documentation missing
00071 
00072      unsigned long timeout = 0;
00073 
00074      try {
00075           timeout
00076                     = boost::any_cast<long>(callback->findData(ICONN_TOKEN_TIMEOUT));
00077      } catch (...) {
00078           CConfigHelper cfg(ConfigurationPath);
00079           cfg.GetConfig("timeout", timeout);
00080           if (timeout != 0) {
00081                callback->addData(ICONN_TOKEN_TIMEOUT, timeout);
00082           }
00083      }
00084 
00085      // Now, tell the master to do the job.
00086      // (The master will add the timestamp for timeout handling for us....)
00087      return master->Receive(callback);
00088 }
00089 
00090 bool CSharedConnectionSlave::CheckConfig(void)
00091 {
00092 
00093      CConfigHelper cfg(ConfigurationPath);
00094      bool fail = false;
00095      std::string s;
00096      fail |= !cfg.GetConfig("useconnection", s);
00097 
00098      fail |= !cfg.CheckConfig("useconnection", libconfig::Setting::TypeString,
00099                false);
00100 
00101      fail |= !cfg.CheckConfig("timeout", libconfig::Setting::TypeInt, true);
00102 
00103      if (fail)
00104           return false;
00105 
00106      IInverterBase *base = Registry::Instance().GetInverter(s);
00107 
00108      if (!base) {
00109           LOGERROR(logger,"useconnection must point to a known Inverter and this "
00110                     "inverter must be declared first. Inverter: " << s;);
00111           return false;
00112      }
00113 
00114      CConfigHelper bcfg(base->GetConfigurationPath());
00115      bcfg.GetConfig("comms", s, std::string(""));
00116      if (s != "SharedConnection") {
00117           LOGERROR(logger,"inverter " << base->GetName() <<
00118                     " does not use a shared connection.");
00119           return false;
00120      }
00121 
00122      bcfg.GetConfig("sharedconnection_type", s);
00123      if (s != "master") {
00124           LOGERROR(logger,"inverter " << base->GetName() <<
00125                     " does not use a shared master connection" );
00126           return false;
00127      }
00128 
00129      master = (CSharedConnection*) base->getConnection();
00130 
00131      return true;
00132 
00133 }
00134 
00135 bool CSharedConnectionSlave::IsConnected(void)
00136 {
00137      assert(master);
00138      return master->IsConnected();
00139 }
00140 
00141 #endif