Go to the documentation of this file.00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019 #include <boost/bind.hpp>
00020
00021 #include "master_proxy.hpp"
00022 #include "OpenPDU.hpp"
00023 #include "ClosePDU.hpp"
00024 #include "ResponsePDU.hpp"
00025 #include "RegisterPDU.hpp"
00026 #include "GetPDU.hpp"
00027 #include "helper.hpp"
00028 #include "types.hpp"
00029
00030 #include <iostream>
00031 using namespace std;
00032
00033 using namespace agentxcpp;
00034 using namespace boost;
00035 using boost::shared_ptr;
00036
00037
00038
00039
00040
00041
00042 master_proxy::master_proxy(boost::asio::io_service* _io_service,
00043 std::string _description,
00044 byte_t _default_timeout,
00045 oid _id,
00046 std::string _filename) :
00047 io_service(_io_service),
00048 io_service_by_user(true),
00049 socket_file(_filename.c_str()),
00050 description(_description),
00051 default_timeout(_default_timeout),
00052 id(_id)
00053 {
00054
00055 byte_t timeout;
00056 timeout = (this->default_timeout == 0) ? 1 : this->default_timeout;
00057 connection = new connector(shared_ptr<boost::asio::io_service>(io_service),
00058 _filename.c_str(),
00059 timeout);
00060
00061
00062 this->connection->register_handler( this );
00063
00064
00065 try
00066 {
00067
00068 this->connect();
00069 }
00070 catch(disconnected)
00071 {
00072
00073 }
00074 }
00075
00076
00077
00078 master_proxy::master_proxy(std::string _description,
00079 byte_t _default_timeout,
00080 oid _id,
00081 std::string _filename) :
00082 io_service(new boost::asio::io_service()),
00083 io_service_by_user(false),
00084 socket_file(_filename.c_str()),
00085 description(_description),
00086 default_timeout(_default_timeout),
00087 id(_id)
00088 {
00089
00090 byte_t timeout;
00091 timeout = (this->default_timeout == 0) ? 1 : this->default_timeout;
00092 connection = new connector(shared_ptr<boost::asio::io_service>(io_service),
00093 _filename.c_str(),
00094 timeout);
00095
00096
00097 this->connection->register_handler( this );
00098
00099
00100 try
00101 {
00102
00103 this->connect();
00104 }
00105 catch(disconnected)
00106 {
00107
00108 }
00109 catch(...)
00110 {
00111
00112 }
00113
00114
00115 }
00116
00117
00118 void master_proxy::connect()
00119 {
00120 if( this->connection->is_connected() )
00121 {
00122
00123 return;
00124 }
00125
00126
00127 registrations.clear();
00128
00129
00130 try
00131 {
00132 this->connection->connect();
00133 }
00134 catch(boost::system::system_error)
00135 {
00136 throw;
00137 }
00138
00139 boost::shared_ptr<ResponsePDU> response;
00140
00141 try
00142 {
00143
00144 OpenPDU openpdu;
00145 openpdu.set_timeout(default_timeout);
00146 openpdu.set_id(id);
00147
00148 this->connection->send(openpdu);
00149
00150
00151
00152 response = this->connection->wait_for_response(openpdu.get_packetID());
00153 }
00154 catch(disconnected)
00155 {
00156 throw;
00157 }
00158 catch(timeout_error)
00159 {
00160 throw disconnected();
00161 }
00162
00163
00164 if(response->get_error() != ResponsePDU::noAgentXError)
00165 {
00166
00167 this->connection->disconnect();
00168 throw disconnected();
00169 }
00170
00171
00172 this->sessionID = response->get_sessionID();
00173 }
00174
00175
00176
00177
00178 void master_proxy::disconnect(ClosePDU::reason_t reason)
00179 {
00180 if( ! this->connection->is_connected() )
00181 {
00182
00183 return;
00184 }
00185
00186
00187
00188
00189
00190
00191 boost::shared_ptr<ResponsePDU> response;
00192
00193
00194 try
00195 {
00196
00197 std::list< boost::shared_ptr<RegisterPDU> >::const_iterator r;
00198 r = this->registrations.begin();
00199 while (r != this->registrations.end())
00200 {
00201 this->undo_registration(create_unregister_pdu(*r));
00202 r++;
00203 }
00204
00205
00206 ClosePDU closepdu(this->sessionID, reason);
00207
00208 this->connection->send(closepdu);
00209
00210
00211
00212 response = this->connection->wait_for_response(closepdu.get_packetID());
00213
00214
00215 if(response->get_error() != ResponsePDU::noAgentXError)
00216 {
00217
00218
00219
00220 }
00221 }
00222 catch(...)
00223 {
00224
00225
00226 }
00227
00228
00229 this->connection->disconnect();
00230 }
00231
00232 master_proxy::~master_proxy()
00233 {
00234
00235 this->disconnect(ClosePDU::reasonShutdown);
00236
00237
00238
00239 delete this->connection;
00240
00241
00242 if( ! this->io_service_by_user )
00243 {
00244 delete this->io_service;
00245 }
00246 }
00247
00248
00249 void master_proxy::do_registration(boost::shared_ptr<RegisterPDU> pdu)
00250 {
00251
00252 if( ! is_connected())
00253 {
00254 throw(disconnected());
00255 }
00256
00257
00258
00259 this->connection->send(*pdu);
00260
00261
00262
00263 boost::shared_ptr<ResponsePDU> response;
00264 response = this->connection->wait_for_response(pdu->get_packetID());
00265
00266
00267 switch(response->get_error())
00268 {
00269
00270
00271 case ResponsePDU::parseError:
00272
00273 throw(internal_error());
00274
00275 case ResponsePDU::notOpen:
00276
00277
00278 throw(disconnected());
00279
00280 case ResponsePDU::unsupportedContext:
00281
00282
00283 throw(internal_error());
00284
00285 case ResponsePDU::processingError:
00286
00287 throw(master_is_unable());
00288
00289 case ResponsePDU::noAgentXError:
00290
00291 break;
00292
00293
00294
00295 case ResponsePDU::duplicateRegistration:
00296 throw(duplicate_registration());
00297
00298 case ResponsePDU::requestDenied:
00299 throw(master_is_unwilling());
00300
00301 default:
00302
00303
00304
00305
00306 throw(parse_error());
00307 }
00308
00309
00310 return;
00311 }
00312
00313
00314
00315
00316
00317 void master_proxy::register_subtree(oid subtree,
00318 byte_t priority,
00319 byte_t timeout)
00320 {
00321
00322 boost::shared_ptr<RegisterPDU> pdu(new RegisterPDU);
00323 pdu->set_subtree(subtree);
00324 pdu->set_priority(priority);
00325 pdu->set_timeout(timeout);
00326
00327
00328 try
00329 {
00330 this->do_registration(pdu);
00331 }
00332 catch( internal_error )
00333 {
00334
00335
00336 throw(parse_error());
00337 }
00338 catch(...)
00339 {
00340
00341 throw;
00342 }
00343
00344
00345 this->registrations.push_back(pdu);
00346
00347 }
00348
00349
00350
00351 void master_proxy::unregister_subtree(oid subtree,
00352 byte_t priority)
00353 {
00354
00355 boost::shared_ptr<UnregisterPDU> pdu;
00356
00357
00358 std::list< boost::shared_ptr<RegisterPDU> >::iterator r;
00359 r = this->registrations.begin();
00360 while (r != this->registrations.end())
00361 {
00362 if( (*r)->get_priority() == priority
00363 && (*r)->get_subtree() == subtree
00364 && (*r)->get_range_subid() == 0
00365 && (*r)->get_upper_bound() == 0 )
00366 {
00367
00368
00369
00370 pdu = create_unregister_pdu(*r);
00371
00372
00373 r = registrations.erase(r);
00374 }
00375 else
00376 {
00377
00378 r++;
00379 }
00380 }
00381
00382
00383 try
00384 {
00385 this->undo_registration(pdu);
00386 }
00387 catch( internal_error )
00388 {
00389
00390
00391 throw(parse_error());
00392 }
00393 catch(...)
00394 {
00395
00396 throw;
00397 }
00398 }
00399
00400
00401
00402 void master_proxy::undo_registration(boost::shared_ptr<UnregisterPDU> pdu)
00403 {
00404
00405 if( ! is_connected())
00406 {
00407 throw(disconnected());
00408 }
00409
00410
00411
00412 this->connection->send(*pdu);
00413
00414
00415
00416 boost::shared_ptr<ResponsePDU> response;
00417 response = this->connection->wait_for_response(pdu->get_packetID());
00418
00419
00420 switch(response->get_error())
00421 {
00422
00423
00424 case ResponsePDU::parseError:
00425
00426 throw(internal_error());
00427
00428 case ResponsePDU::notOpen:
00429
00430
00431 throw(disconnected());
00432
00433 case ResponsePDU::unsupportedContext:
00434
00435
00436 throw(internal_error());
00437
00438 case ResponsePDU::processingError:
00439
00440 throw(master_is_unable());
00441
00442 case ResponsePDU::noAgentXError:
00443
00444 break;
00445
00446
00447
00448 case ResponsePDU::unknownRegistration:
00449 throw(unknown_registration());
00450
00451 default:
00452
00453
00454
00455
00456 throw(parse_error());
00457 }
00458
00459
00460 return;
00461 }
00462
00463
00464
00465 boost::shared_ptr<UnregisterPDU> master_proxy::create_unregister_pdu(
00466 boost::shared_ptr<RegisterPDU> pdu)
00467 {
00468 boost::shared_ptr<UnregisterPDU> new_pdu(new UnregisterPDU());
00469 new_pdu->set_subtree( pdu->get_subtree() );
00470 new_pdu->set_range_subid( pdu->get_range_subid() );
00471 new_pdu->set_upper_bound( pdu->get_upper_bound() );
00472 new_pdu->set_priority( pdu->get_priority() );
00473
00474 return new_pdu;
00475 }
00476