Main Page   Class Hierarchy   Alphabetical List   Compound List   File List   Compound Members   File Members   Related Pages  

LOW_netSegment.cpp

Go to the documentation of this file.
00001 /***************************************************************************
00002                           LOW_netSegment.cpp  -  description
00003                              -------------------
00004     begin                : Sun Jul 7 2002
00005     copyright            : (C) 2002 by Harald Roelle, Helmut Reiser
00006     email                : roelle@informatik.uni-muenchen.de, reiser@informatik.uni-muenchen.de
00007  ***************************************************************************/
00008 
00009 /***************************************************************************
00010  *                                                                         *
00011  *   This program is free software; you can redistribute it and/or modify  *
00012  *   it under the terms of the GNU General Public License as published by  *
00013  *   the Free Software Foundation; either version 2 of the License, or     *
00014  *   (at your option) any later version.                                   *
00015  *                                                                         *
00016  ***************************************************************************/
00017 
00018 #include "LOW_netSegment.h"
00019 #include "LOW_deviceFactory.h"
00020 
00021 
00022 
00023 //=====================================================================================
00024 //
00025 // static attributes
00026 //
00027   
00028 LOW_netSegment::segmentID_t  LOW_netSegment::segmentCount = 0;
00029 
00030 
00031 //=====================================================================================
00032 //
00033 // constructors
00034 //
00035 
00036 LOW_netSegment::LOW_netSegment( LOW_link &inLink) :
00037   segmentID( segmentCount++), 
00038   link( inLink)
00039 {
00040   hasExternalPower = link.getHasExternalPower();
00041 
00042   searchDevices<LOW_device>();  //find all devices on bus
00043 }
00044 
00045 
00046 LOW_netSegment::~LOW_netSegment()
00047 {
00048   for( LOW_device::deviceMap_t::const_iterator a=aliveDevMap.begin(); a!=aliveDevMap.end(); ++a)
00049     delete a->second;
00050 
00051   for( LOW_device::deviceMap_t::const_iterator a=graveyardMap.begin(); a!=graveyardMap.end(); ++a)
00052     delete a->second;
00053 }
00054 
00055 
00056 
00057 //=====================================================================================
00058 //
00059 // static methods
00060 //
00061 
00062 LOW_netSegment::netSegPtrVec_t LOW_netSegment::newSegmentsFromLink( LOW_link &inLink)
00063 {
00064   netSegPtrVec_t  segments;
00065   
00066   /** @warning  By now only a single segment is supported
00067       @todo Add support for multi-segment links
00068    */
00069   segments.push_back( new LOW_netSegment( inLink));
00070 
00071   return segments;
00072 }
00073 
00074 
00075 
00076 //=====================================================================================
00077 //
00078 // operator overloading
00079 //
00080 
00081 bool LOW_netSegment::operator==(LOW_netSegment &inSegment) const
00082 {
00083   return (segmentID==inSegment.segmentID);
00084 }
00085 
00086 
00087 
00088 //=====================================================================================
00089 //
00090 // public methods
00091 //
00092 
00093 LOW_link& LOW_netSegment::getLink()
00094 {
00095   return link;
00096 }
00097 
00098 
00099 bool LOW_netSegment::getHasExternalPower() const
00100 {
00101   return hasExternalPower;
00102 }
00103 
00104 
00105 bool LOW_netSegment::verifyDevice( const LOW_deviceID inDevID, const bool inOnlyAlarm, const bool inDoReset)
00106 {
00107   bool isPresent = cmd_SearchROMVerify( inDevID, inOnlyAlarm, inDoReset);
00108   
00109   if ( !inOnlyAlarm ) {
00110     if ( isPresent ) {
00111       addDevice( inDevID);
00112     }
00113     else { 
00114       addDevice( inDevID);
00115       try {
00116         LOW_device *theDev = getDevice<LOW_device>( inDevID);
00117         revitalizeDevice( theDev);
00118       }
00119       catch ( LOW_exception ex) {
00120         return false;
00121       }
00122     }
00123   }
00124 
00125   return isPresent;
00126 }
00127 
00128 
00129 
00130 //=====================================================================================
00131 //
00132 // methods
00133 //
00134   
00135 void LOW_netSegment::unregisterDevice( const LOW_device *inDev)
00136 {
00137   removeDevice( inDev);
00138 }
00139 
00140 
00141                               
00142 //=====================================================================================
00143 //
00144 // addressing/searching methods
00145 //
00146 
00147 void LOW_netSegment::cmd_MatchROM( const LOW_device *inDevice) const
00148 {
00149   LOW_link::commLock lock( link);
00150   
00151   if ( link.resetBus() == false )
00152     throw noDevice_error( "Reset indicated no devices", __FILE__, __LINE__);
00153   
00154   byteVec_t outVec;
00155     
00156   outVec.push_back( LOW_device::MatchROM_COMMAND);
00157   
00158   byteVec_t id = inDevice->getID().getRomIDVec();  
00159   outVec.insert( outVec.end(), id.begin(), id.end());
00160     
00161   link.writeData( outVec);
00162 }
00163 
00164 
00165 LOW_deviceID LOW_netSegment::cmd_ReadROM() const
00166 {
00167   LOW_link::commLock lock( link);
00168   
00169   if ( link.resetBus() == false )
00170     throw noDevice_error( "Reset indicated no devices", __FILE__, __LINE__);
00171       
00172   link.writeData( LOW_device::ReadROM_COMMAND);
00173 
00174   byteVec_t idBytes = byteVec_t( sizeof( LOW_deviceIDRaw::devRomID_t));
00175   
00176   link.readData( idBytes);
00177 
00178   return LOW_deviceID( idBytes);
00179 }
00180 
00181 
00182 void LOW_netSegment::cmd_SkipROM() const
00183 {
00184   LOW_link::commLock lock( link);
00185   
00186   if ( link.resetBus() == false )
00187     throw noDevice_error( "Reset indicated no devices", __FILE__, __LINE__);
00188       
00189   link.writeData( LOW_device::SkipROM_COMMAND);
00190 }
00191     
00192 
00193 LOW_deviceID::deviceIDVec_t LOW_netSegment::cmd_SearchROM( const bool inOnlyAlarm,
00194                                                            const LOW_deviceIDRaw::devFamCode_t inFamCode) const
00195 {
00196   LOW_link::commLock lock( link);
00197   
00198   LOW_deviceIDRaw                searchVec = LOW_deviceIDRaw();  // init with 0
00199   LOW_deviceIDRaw                foundID;
00200   LOW_deviceIDRaw                discrVec;
00201   int                            lastDiscr = 0;
00202   LOW_deviceID::deviceIDVec_t    foundIDVec;
00203   
00204   // preload family type
00205   if ( inFamCode != LOW_device::anyDev_famCode )
00206     searchVec.setFamilyCode( inFamCode);
00207   
00208   while ( true ) {
00209   
00210     if ( link.resetBus() == false )
00211       throw noDevice_error( "Reset indicated no devices", __FILE__, __LINE__);
00212   
00213     if ( inOnlyAlarm )
00214       link.writeData( LOW_device::SearchAlarmROM_COMMAND);
00215     else
00216       link.writeData( LOW_device::SearchROM_COMMAND);
00217   
00218     link.doSearchSequence( searchVec, foundID, discrVec);
00219     
00220     if ( foundID.getBit( 63)==true && discrVec.getBit( 63)==true)
00221       throw noDevice_error( "No devices during search found", __FILE__, __LINE__);
00222     
00223     LOW_deviceID newID = LOW_deviceID( foundID);     
00224     
00225     if ( inFamCode!=LOW_device::anyDev_famCode && newID.getFamilyCode()!=inFamCode )
00226       break;
00227           
00228     foundIDVec.push_back( newID);
00229     
00230     // find last discrepancy
00231     int newDiscr = 0xff;
00232     for( int a=63 ; a>=0; a--) {
00233       if ( discrVec.getBit( a)==true && foundID.getBit( a)==false) {
00234         newDiscr = a;
00235         break;
00236       }
00237     }
00238     
00239     if ( newDiscr==0xff /*|| newDiscr==lastDiscr*/ ) {  // search has ended
00240       break;
00241     }
00242     
00243     lastDiscr = newDiscr;
00244     
00245     // prepare next search vector
00246     for( int a=0; a<64; a++) {
00247       if ( a<lastDiscr ) {
00248         searchVec.setBit( a, foundID.getBit( a));
00249       }
00250       else if ( a==lastDiscr ) {
00251         searchVec.setBit( a, true);
00252       }
00253       else {
00254         searchVec.setBit( a, false);
00255       }
00256     }
00257 
00258   }  
00259   
00260   if ( link.resetBus() == false )
00261     throw noDevice_error( "Reset indicated no devices", __FILE__, __LINE__);
00262   
00263   return foundIDVec;
00264 }
00265     
00266 
00267 bool LOW_netSegment::cmd_SearchROMVerify( const LOW_deviceID inDevID, const bool inOnlyAlarm, const bool inDoReset) const
00268 {
00269   LOW_link::commLock lock( link);
00270   
00271   if ( link.resetBus() == false )
00272     throw noDevice_error( "Reset indicated no devices", __FILE__, __LINE__);
00273   
00274   if ( inOnlyAlarm )
00275     link.writeData( LOW_device::SearchAlarmROM_COMMAND);
00276   else
00277     link.writeData( LOW_device::SearchROM_COMMAND);
00278   
00279   LOW_deviceIDRaw  foundID;
00280   LOW_deviceIDRaw  discrVec;
00281   link.doSearchSequence( inDevID, foundID, discrVec);
00282     
00283   bool retVal = (foundID == inDevID);
00284   
00285   if ( inDoReset ) {
00286     if ( link.resetBus() == false )
00287       throw noDevice_error( "Reset indicated no devices", __FILE__, __LINE__);
00288   }
00289   
00290   return retVal;
00291 }
00292 
00293 
00294 
00295 //=====================================================================================
00296 //
00297 // active map / graveyard management
00298 //
00299 
00300 void LOW_netSegment::buryDevice( const LOW_device *inDev)
00301 {
00302   // look in alive map, if not present simply return
00303   LOW_device::deviceMap_t::iterator foundAlive = aliveDevMap.find( inDev->getID());
00304   if ( foundAlive == aliveDevMap.end() ) {
00305     return;
00306   }
00307   
00308   LOW_device *theDev = foundAlive->second;
00309   aliveDevMap.erase( foundAlive);
00310   
00311   graveyardMap[theDev->getID()] = theDev;
00312   // theDev.bury();
00313 }
00314 
00315 
00316 void LOW_netSegment::revitalizeDevice( const LOW_device *inDev)
00317 {
00318   // look in graveyard, if not present simply return
00319   LOW_device::deviceMap_t::iterator foundGraveyard = graveyardMap.find( inDev->getID());
00320   if ( foundGraveyard == graveyardMap.end() ) {
00321     return;
00322   }
00323   
00324   LOW_device *theDev = foundGraveyard->second;
00325   graveyardMap.erase( foundGraveyard);
00326   
00327   aliveDevMap[theDev->getID()] = theDev;
00328   // theDev.revitalize();
00329 }
00330 
00331 
00332 LOW_device* LOW_netSegment::addDevice( const LOW_deviceID inDevID)
00333 {
00334   // look in alive map, if present simply return device
00335   LOW_device::deviceMap_t::iterator foundAlive = aliveDevMap.find( inDevID);
00336   if ( foundAlive != aliveDevMap.end() ) {
00337     return foundAlive->second;
00338   }
00339     
00340   // look in graveyard, if present revitalize it and return it
00341   LOW_device::deviceMap_t::iterator foundGraveyard = graveyardMap.find( inDevID);
00342   if ( foundGraveyard != graveyardMap.end() ) {
00343     LOW_device *theDev = foundGraveyard->second;
00344     revitalizeDevice( theDev);
00345     return theDev;
00346   }
00347 
00348   // now it must be really new, so create it, add it to alive map and return it
00349   LOW_device* newDev = LOW_deviceFactory::new_SpecificDevice( *this, inDevID);
00350   aliveDevMap[inDevID] = newDev;
00351   return newDev;
00352 }
00353 
00354 
00355 void LOW_netSegment::removeDevice( const LOW_device *inDev)
00356 {
00357   const LOW_deviceID devID = inDev->getID();
00358   
00359   // look in alive map, if present delete it and return
00360   LOW_device::deviceMap_t::iterator foundAlive = aliveDevMap.find( inDev->getID());
00361   if ( foundAlive != aliveDevMap.end() ) {
00362     aliveDevMap.erase( foundAlive);
00363     return;
00364   }
00365     
00366   // look in graveyard, if present delete it and return
00367   LOW_device::deviceMap_t::iterator foundGraveyard = graveyardMap.find( inDev->getID());
00368   if ( foundGraveyard != graveyardMap.end() ) {
00369     graveyardMap.erase( foundGraveyard);
00370     return;
00371   }
00372 }
00373 

Generated on Sun Jan 12 21:07:43 2003 by doxygen1.2.13.1 written by Dimitri van Heesch, © 1997-2001