00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018 #include <oasys/util/OptParser.h>
00019 #include <oasys/util/StringBuffer.h>
00020
00021 #include "SimConvergenceLayer.h"
00022 #include "Node.h"
00023 #include "Simulator.h"
00024 #include "Topology.h"
00025 #include "bundling/Bundle.h"
00026 #include "bundling/BundleEvent.h"
00027 #include "bundling/BundleList.h"
00028
00029 namespace dtnsim {
00030
00034 class SimCLInfo : public CLInfo {
00035 public:
00036 SimCLInfo()
00037 {
00038 params_.deliver_partial_ = true;
00039 params_.reliable_ = true;
00040 }
00041
00042 ~SimCLInfo() {};
00043
00044 struct Params {
00047 bool deliver_partial_;
00048
00052 bool reliable_;
00053
00054 } params_;
00055
00056 Node* peer_node_;
00057 };
00058
00059 SimConvergenceLayer* SimConvergenceLayer::instance_;
00060
00061 SimConvergenceLayer::SimConvergenceLayer()
00062 : ConvergenceLayer("SimConvergenceLayer", "sim")
00063 {
00064 }
00065
00066 bool
00067 SimConvergenceLayer::init_link(Link* link, int argc, const char* argv[])
00068 {
00069 oasys::OptParser p;
00070
00071 SimCLInfo* info = new SimCLInfo();
00072 info->peer_node_ = Topology::find_node(link->nexthop());
00073 ASSERT(info->peer_node_);
00074
00075 p.addopt(new oasys::BoolOpt("deliver_partial",
00076 &info->params_.deliver_partial_));
00077 p.addopt(new oasys::BoolOpt("reliable", &info->params_.reliable_));
00078
00079 const char* invalid;
00080 if (! p.parse(argc, argv, &invalid)) {
00081 log_err("error parsing link options: invalid option %s", invalid);
00082 return false;
00083 }
00084
00085 link->set_cl_info(info);
00086
00087 return true;
00088 }
00089
00090 bool
00091 SimConvergenceLayer::open_contact(const ContactRef& contact)
00092 {
00093 log_debug("opening contact for link [*%p]", contact.object());
00094
00095 BundleDaemon::post(new ContactUpEvent(contact));
00096
00097 return true;
00098 }
00099
00100 void
00101 SimConvergenceLayer::send_bundle(const ContactRef& contact, Bundle* bundle)
00102 {
00103 log_debug("send_bundles on contact %s", contact->link()->nexthop());
00104
00105 SimCLInfo* info = (SimCLInfo*)contact->link()->cl_info();
00106 ASSERT(info);
00107
00108
00109
00110
00111
00112 Node* src_node = Node::active_node();
00113 Node* dst_node = info->peer_node_;
00114
00115 ASSERT(src_node != dst_node);
00116
00117 bool reliable = info->params_.reliable_;
00118
00119 BlockInfoVec* blocks = bundle->xmit_blocks_.find_blocks(contact->link());
00120 ASSERT(blocks != NULL);
00121
00122
00123
00124
00125 if (bundle->payload_.location() == BundlePayload::NODATA) {
00126 BlockInfo* payload = const_cast<BlockInfo*>(
00127 blocks->find_block(BundleProtocol::PAYLOAD_BLOCK));
00128 ASSERT(payload != NULL);
00129 payload->set_data_length(0);
00130 }
00131
00132 bool complete = false;
00133 size_t len = BundleProtocol::produce(bundle, blocks,
00134 buf_, 0, sizeof(buf_),
00135 &complete);
00136 ASSERTF(complete, "BundleProtocol non-payload blocks must fit in "
00137 "65 K buffer size");
00138
00139 size_t total_len = len + bundle->payload_.length();
00140
00141 complete = false;
00142 Bundle* new_bundle = new Bundle(bundle->payload_.location());
00143 int cc = BundleProtocol::consume(new_bundle, buf_, len, &complete);
00144 ASSERT(cc == (int)len);
00145 ASSERT(complete);
00146
00147 if (bundle->payload_.location() == BundlePayload::NODATA) {
00148 new_bundle->payload_.set_length(bundle->payload_.length());
00149 }
00150
00151 BundleTransmittedEvent* tx_event =
00152 new BundleTransmittedEvent(bundle, contact, contact->link(),
00153 total_len, reliable ? total_len : 0);
00154 Simulator::post(new SimRouterEvent(Simulator::time(),
00155 src_node, tx_event));
00156
00157 BundleReceivedEvent* rcv_event =
00158 new BundleReceivedEvent(bundle, EVENTSRC_PEER, total_len);
00159 Simulator::post(new SimRouterEvent(Simulator::time(),
00160 dst_node, rcv_event));
00161 }
00162
00163
00164 }