00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018 #include "LOW_netSegment.h"
00019 #include "LOW_deviceFactory.h"
00020
00021
00022
00023
00024
00025
00026
00027
00028 LOW_netSegment::segmentID_t LOW_netSegment::segmentCount = 0;
00029
00030
00031
00032
00033
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>();
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
00060
00061
00062 LOW_netSegment::netSegPtrVec_t LOW_netSegment::newSegmentsFromLink( LOW_link &inLink)
00063 {
00064 netSegPtrVec_t segments;
00065
00066
00067
00068
00069 segments.push_back( new LOW_netSegment( inLink));
00070
00071 return segments;
00072 }
00073
00074
00075
00076
00077
00078
00079
00080
00081 bool LOW_netSegment::operator==(LOW_netSegment &inSegment) const
00082 {
00083 return (segmentID==inSegment.segmentID);
00084 }
00085
00086
00087
00088
00089
00090
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
00133
00134
00135 void LOW_netSegment::unregisterDevice( const LOW_device *inDev)
00136 {
00137 removeDevice( inDev);
00138 }
00139
00140
00141
00142
00143
00144
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();
00199 LOW_deviceIDRaw foundID;
00200 LOW_deviceIDRaw discrVec;
00201 int lastDiscr = 0;
00202 LOW_deviceID::deviceIDVec_t foundIDVec;
00203
00204
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
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 ) {
00240 break;
00241 }
00242
00243 lastDiscr = newDiscr;
00244
00245
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
00298
00299
00300 void LOW_netSegment::buryDevice( const LOW_device *inDev)
00301 {
00302
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
00313 }
00314
00315
00316 void LOW_netSegment::revitalizeDevice( const LOW_device *inDev)
00317 {
00318
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
00329 }
00330
00331
00332 LOW_device* LOW_netSegment::addDevice( const LOW_deviceID inDevID)
00333 {
00334
00335 LOW_device::deviceMap_t::iterator foundAlive = aliveDevMap.find( inDevID);
00336 if ( foundAlive != aliveDevMap.end() ) {
00337 return foundAlive->second;
00338 }
00339
00340
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
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
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
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