IBR-DTNSuite  0.8
daemon/src/core/StatusReportGenerator.cpp
Go to the documentation of this file.
00001 /*
00002  * StatusReportGenerator.cpp
00003  *
00004  *  Created on: 17.02.2010
00005  *      Author: morgenro
00006  */
00007 
00008 #include "core/StatusReportGenerator.h"
00009 #include "core/BundleEvent.h"
00010 #include "core/BundleGeneratedEvent.h"
00011 #include "core/BundleCore.h"
00012 #include <ibrdtn/data/MetaBundle.h>
00013 
00014 namespace dtn
00015 {
00016         namespace core
00017         {
00018                 using namespace dtn::data;
00019 
00020                 StatusReportGenerator::StatusReportGenerator()
00021                 {
00022                         bindEvent(BundleEvent::className);
00023                 }
00024 
00025                 StatusReportGenerator::~StatusReportGenerator()
00026                 {
00027                         unbindEvent(BundleEvent::className);
00028                 }
00029 
00030                 void StatusReportGenerator::createStatusReport(const dtn::data::MetaBundle &b, StatusReportBlock::TYPE type, StatusReportBlock::REASON_CODE reason)
00031                 {
00032                         // create a new bundle
00033                         Bundle bundle;
00034 
00035                         // create a new statusreport block
00036                         StatusReportBlock &report = bundle.push_back<StatusReportBlock>();
00037 
00038                         bundle.set(dtn::data::PrimaryBlock::APPDATA_IS_ADMRECORD, true);
00039 
00040                         // get the flags and set the status flag
00041                         report._status |= type;
00042 
00043                         // set the reason code
00044                         report._reasoncode |= reason;
00045 
00046                         switch (type)
00047                         {
00048                                 case StatusReportBlock::RECEIPT_OF_BUNDLE:
00049                                         report._timeof_receipt.set();
00050                                 break;
00051 
00052                                 case StatusReportBlock::CUSTODY_ACCEPTANCE_OF_BUNDLE:
00053                                         report._timeof_custodyaccept.set();
00054                                 break;
00055 
00056                                 case StatusReportBlock::FORWARDING_OF_BUNDLE:
00057                                         report._timeof_forwarding.set();
00058                                 break;
00059 
00060                                 case StatusReportBlock::DELIVERY_OF_BUNDLE:
00061                                         report._timeof_delivery.set();
00062                                 break;
00063 
00064                                 case StatusReportBlock::DELETION_OF_BUNDLE:
00065                                         report._timeof_deletion.set();
00066                                 break;
00067 
00068                                 default:
00069 
00070                                 break;
00071                         }
00072 
00073                         // set source and destination
00074                         bundle._source = dtn::core::BundleCore::local;
00075                         bundle.set(dtn::data::PrimaryBlock::DESTINATION_IS_SINGLETON, true);
00076                         bundle._destination = b.reportto;
00077 
00078                         // set bundle parameter
00079                         if (b.get(Bundle::FRAGMENT))
00080                         {
00081                                 report._fragment_offset = b.offset;
00082                                 report._fragment_length = b.appdatalength;
00083                                 report._admfield |= 1;
00084                         }
00085 
00086                         report._bundle_timestamp = b.timestamp;
00087                         report._bundle_sequence = b.sequencenumber;
00088                         report._source = b.source;
00089 
00090                         dtn::core::BundleGeneratedEvent::raise(bundle);
00091                 }
00092 
00093                 void StatusReportGenerator::raiseEvent(const Event *evt)
00094                 {
00095                         try {
00096                                 const BundleEvent &bundleevent = dynamic_cast<const BundleEvent&>(*evt);
00097                                 const dtn::data::MetaBundle &b = bundleevent.getBundle();
00098 
00099                                 // do not generate status reports for other status reports or custody signals
00100                                 if (b.get(dtn::data::PrimaryBlock::APPDATA_IS_ADMRECORD)) return;
00101 
00102                                 switch (bundleevent.getAction())
00103                                 {
00104                                 case BUNDLE_RECEIVED:
00105                                         if ( b.get(Bundle::REQUEST_REPORT_OF_BUNDLE_RECEPTION))
00106                                         {
00107                                                 createStatusReport(b, StatusReportBlock::RECEIPT_OF_BUNDLE, bundleevent.getReason());
00108                                         }
00109                                         break;
00110                                 case BUNDLE_DELETED:
00111                                         if ( b.get(Bundle::REQUEST_REPORT_OF_BUNDLE_DELETION))
00112                                         {
00113                                                 createStatusReport(b, StatusReportBlock::DELETION_OF_BUNDLE, bundleevent.getReason());
00114                                         }
00115                                         break;
00116 
00117                                 case BUNDLE_FORWARDED:
00118                                         if ( b.get(Bundle::REQUEST_REPORT_OF_BUNDLE_FORWARDING))
00119                                         {
00120                                                 createStatusReport(b, StatusReportBlock::FORWARDING_OF_BUNDLE, bundleevent.getReason());
00121                                         }
00122                                         break;
00123 
00124                                 case BUNDLE_DELIVERED:
00125                                         if ( b.get(Bundle::REQUEST_REPORT_OF_BUNDLE_DELIVERY))
00126                                         {
00127                                                 createStatusReport(b, StatusReportBlock::DELIVERY_OF_BUNDLE, bundleevent.getReason());
00128                                         }
00129                                         break;
00130 
00131                                 case BUNDLE_CUSTODY_ACCEPTED:
00132                                         if ( b.get(Bundle::REQUEST_REPORT_OF_CUSTODY_ACCEPTANCE))
00133                                         {
00134                                                 createStatusReport(b, StatusReportBlock::CUSTODY_ACCEPTANCE_OF_BUNDLE, bundleevent.getReason());
00135                                         }
00136                                         break;
00137 
00138                                 default:
00139                                         break;
00140                                 }
00141                         } catch (const std::bad_cast&) { };
00142                 }
00143         }
00144 }