Hal.cc

Go to the documentation of this file.
00001 /*---------------------------------------------------------------------\
00002 |                          ____ _   __ __ ___                          |
00003 |                         |__  / \ / / . \ . \                         |
00004 |                           / / \ V /|  _/  _/                         |
00005 |                          / /__ | | | | | |                           |
00006 |                         /_____||_| |_| |_|                           |
00007 |                                                                      |
00008 \---------------------------------------------------------------------*/
00012 #include <iostream>
00013 
00014 #define ZYPP_BASE_LOGGER_LOGGROUP "HAL"
00015 #include "zypp/base/Logger.h"
00016 
00017 #include "zypp/target/hal/Hal.h"
00018 
00019 #ifndef FAKE_HAL
00020 
00021 #include <glib.h>
00022 
00023 #include <dbus/dbus-glib-lowlevel.h>
00024 #include <dbus/dbus-glib.h>
00025 #include <hal/libhal.h>
00026 
00027 #endif
00028 
00029 using std::endl;
00030 using std::string;
00031 
00033 namespace zypp
00034 { 
00035 
00036   namespace target
00037   { 
00038 
00039     namespace hal
00040     { 
00041 
00042 #ifndef FAKE_HAL
00044 //
00045 //      CLASS NAME : Hal::Impl
00046 //
00048 struct Hal::Impl
00049 {
00053     DBusConnection *_connection;
00054 
00058     LibHalContext *_context;
00059 
00063     void
00064     report_error (const std::string & reason, DBusError & error) const
00065     {
00066         ERR << reason << ": " << string (error.name) << ": " << string(error.message);
00067         dbus_error_init(&error);
00068         return;
00069     }
00070 
00072     Impl()
00073     {
00074         DBusError error;
00075         dbus_error_init (&error);
00076 
00077         _connection = dbus_bus_get (DBUS_BUS_SYSTEM, &error);                   // get shared connection to DBUS 'socket'
00078         //_connection = dbus_bus_get_private (DBUS_BUS_SYSTEM, &error);         // get private connection DBUS 'socket'
00079         if (_connection) {
00080             _context = libhal_ctx_new ();                                       // create empty HAL context
00081             if (_context) {
00082                 if (libhal_ctx_set_dbus_connection (_context, _connection)) {   // connect to HAL daemon via DBUS
00083                     if (libhal_ctx_init (_context, &error)) {                   // fill HAL context
00084                         return;
00085                     } else {
00086                         report_error ("libhal_ctx_init", error);
00087                     }
00088                 } else {
00089                     report_error ("libhal_ctx_set_dbus_connection", error);
00090                 }
00091                 libhal_ctx_free (_context);                                     // clean up
00092                 _context = NULL;
00093             } else {
00094                 report_error ("libhal_ctx_new: Can't create libhal context", error);
00095             }
00096             // dbus_connection_close (_connection);                             // call only if dbus_bus_get_private was used
00097             dbus_connection_unref (_connection);
00098             _connection = NULL;
00099         } else {
00100             report_error ("dbus_bus_get", error);
00101         }
00102     }
00103 
00104 
00106     ~Impl()
00107     {
00108         if (_context) {
00109             libhal_ctx_free (_context);
00110         }
00111         if (_connection) {
00112             // dbus_connection_close (_connection);                             // call only if dbus_bus_get_private was used
00113             dbus_connection_unref (_connection);
00114         }
00115     }
00116 
00121     bool query( const std::string & cap_r ) const
00122     { return query( cap_r, Rel::ANY, std::string() ); }
00123 
00127     bool  query( const std::string & cap_r,
00128                Rel op_r,
00129                const std::string & val_r ) const
00130     {
00131         DBusError error;
00132         dbus_error_init (&error);
00133 
00134         // ask HAL which devices provide the needed capability
00135 
00136         bool result = false;
00137 
00138         int device_count;
00139         char **device_names = libhal_find_device_by_capability (_context, cap_r.c_str(), &device_count, &error);
00140 
00141         if (device_names == NULL) {
00142             report_error ("libhal_find_device_by_capability", error);
00143             result = false;
00144         }
00145         else if (device_count > 0) {
00146 
00147 #if 0           // once we get a capabilities value from HAL, we can compare it ...
00148             if (value) {
00149                 string lhs (value);
00150                 int cmp = (lhs != rhs) ? ((lhs < rhs) ? -1 : 1) : 0;
00151 
00152                 switch ( relation.inSwitch() )
00153                 {
00154                     case Rel::EQ_e:
00155                         res = (cmp == 0);
00156                         break;
00157                     case Rel::NE_e:
00158                         res = (cmp != 0);
00159                         break;
00160                     case Rel::LT_e:
00161                         res = (cmp == -1);
00162                         break;
00163                     case Rel::LE_e:
00164                         res = (cmp != 1);
00165                         break;
00166                     case Rel::GT_e:
00167                         res = (cmp == 1);
00168                         break;
00169                     case Rel::GE_e:
00170                         res = (cmp != -1);
00171                         break;
00172                     case Rel::ANY_e:
00173                         res = true;
00174                         break;
00175                     case Rel::NONE_e:
00176                         res = false;
00177                         break;
00178                     default:
00179                         // We shouldn't get here.
00180                         INT << "Unknown relational opertor '" << relation << "' treated as  'NONE'" << endl;
00181                         break;
00182                 }
00183             }
00184 #endif
00185 
00186             result = true;
00187 
00188         }
00189 
00190         if (device_names != NULL)
00191             libhal_free_string_array (device_names);
00192 
00193         return result;
00194     }
00195 
00196   public:
00198     static shared_ptr<Impl> nullimpl()
00199     {
00200         static shared_ptr<Impl> _nullimpl( new Impl );
00201         return _nullimpl;
00202     }
00203 
00204 };  // struct Hal::Impl
00205 
00206 
00207 #else // FAKE_HAL
00208       struct Hal::Impl
00209       {
00210         bool query( const std::string & cap_r ) const
00211         { return query( cap_r, Rel::ANY, std::string() ); }
00212         bool  query( const std::string & cap_r,
00213                      Rel op_r,
00214                      const std::string & val_r ) const
00215         { return false; }
00217         static shared_ptr<Impl> nullimpl()
00218         {
00219           static shared_ptr<Impl> _nullimpl( new Impl );
00220           return _nullimpl;
00221         }
00222       };
00223 #endif
00224 
00226 
00231 inline std::ostream & operator<<( std::ostream & str, const Hal::Impl & obj )
00232 {
00233   return str << "Hal::Impl";
00234 }
00235 
00237 //
00238 //      CLASS NAME : Hal
00239 //
00241 
00243 //
00244 //      METHOD NAME : Hal::Hal
00245 //      METHOD TYPE : Ctor
00246 //
00247 Hal::Hal()
00248 : _pimpl( Impl::nullimpl() )
00249 {}
00250 
00252 //
00253 //      METHOD NAME : Hal::~Hal
00254 //      METHOD TYPE : Dtor
00255 //
00256 Hal::~Hal()
00257 {}
00258 
00260 //
00261 //      METHOD NAME : Hal::instance
00262 //      METHOD TYPE : Hal &
00263 //
00264 Hal & Hal::instance()
00265 {
00266   static Hal _singleton;
00267   return _singleton;
00268 }
00269 
00271 // Foreward to implenemtation
00273 
00274 bool Hal::query( const std::string & cap_r ) const
00275 { return _pimpl->query( cap_r ); }
00276 
00277 bool Hal::query( const std::string & cap_r,
00278                  Rel op_r,
00279                  const std::string & val_r ) const
00280 { return _pimpl->query( cap_r, op_r, val_r ); }
00281 
00282 /******************************************************************
00283 **
00284 **      FUNCTION NAME : operator<<
00285 **      FUNCTION TYPE : std::ostream &
00286 */
00287 std::ostream & operator<<( std::ostream & str, const Hal & obj )
00288 {
00289   return str << *obj._pimpl;
00290 }
00291 
00293     } // namespace hal
00296   } // namespace target
00299 } // namespace zypp

Generated on Tue Nov 28 16:49:33 2006 for zypp by  doxygen 1.5.0