Hal.cc

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

Generated on Tue Sep 25 19:23:08 2007 for libzypp by  doxygen 1.5.3