SimConvergenceLayer.cc

Go to the documentation of this file.
00001 /*
00002  *    Copyright 2004-2006 Intel Corporation
00003  * 
00004  *    Licensed under the Apache License, Version 2.0 (the "License");
00005  *    you may not use this file except in compliance with the License.
00006  *    You may obtain a copy of the License at
00007  * 
00008  *        http://www.apache.org/licenses/LICENSE-2.0
00009  * 
00010  *    Unless required by applicable law or agreed to in writing, software
00011  *    distributed under the License is distributed on an "AS IS" BASIS,
00012  *    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
00013  *    See the License for the specific language governing permissions and
00014  *    limitations under the License.
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     // XXX/demmer add Connectivity check to see if it's open and add
00109     // bw/latency restrictions. then move the following events to
00110     // there
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     // since we don't really have any payload to send, we find the
00123     // payload block and overwrite the data_length to be zero, then
00124     // adjust the payload_ on the new bundle
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 } // namespace dtnsim

Generated on Thu Jun 7 16:56:52 2007 for DTN Reference Implementation by  doxygen 1.5.1