SimContact.cc

Go to the documentation of this file.
00001 /*
00002  * IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING. By
00003  * downloading, copying, installing or using the software you agree to
00004  * this license. If you do not agree to this license, do not download,
00005  * install, copy or use the software.
00006  * 
00007  * Intel Open Source License 
00008  * 
00009  * Copyright (c) 2004 Intel Corporation. All rights reserved. 
00010  * 
00011  * Redistribution and use in source and binary forms, with or without
00012  * modification, are permitted provided that the following conditions are
00013  * met:
00014  * 
00015  *   Redistributions of source code must retain the above copyright
00016  *   notice, this list of conditions and the following disclaimer.
00017  * 
00018  *   Redistributions in binary form must reproduce the above copyright
00019  *   notice, this list of conditions and the following disclaimer in the
00020  *   documentation and/or other materials provided with the distribution.
00021  * 
00022  *   Neither the name of the Intel Corporation nor the names of its
00023  *   contributors may be used to endorse or promote products derived from
00024  *   this software without specific prior written permission.
00025  *  
00026  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
00027  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
00028  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
00029  * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE INTEL OR
00030  * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
00031  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
00032  * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
00033  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
00034  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
00035  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
00036  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
00037  */
00038 #include "SimContact.h"
00039 #include "Simulator.h"
00040 
00041 namespace dtnsim {
00042 
00043 
00044 SimContact::SimContact (int id, Node* src, Node* dst, 
00045 double bw, double latency, bool isup, int pup, int pdown) 
00046     : Logger ("/sim/simcontact") 
00047 {
00048     id_ = id;
00049     src_ = src;
00050     dst_ = dst;
00051     bw_ = bw;
00052     latency_ = latency;
00053     up_ = pup; // length of up period
00054     down_ = pdown; // length of down period
00055     ASSERT(bw > 0 && latency >= 0) ;
00056     
00057     log_info("C[%d]: CONTACT CREATED: N[%d]->N[%d]\n",
00058              id_,src_->id(),dst_->id());
00059     
00060     chewing_event_ = NULL;
00061     future_updown_event_ = NULL;
00062     // start state
00063     if (isup) {
00064         open_contact(false);
00065     } else  {
00066         close_contact(false);
00067     }
00068 }
00069 
00070 
00071 // This defines behavior of starting of eating of a message
00072 void 
00073 SimContact::chew_message(Message* msg) 
00074 {
00075     log_info("C[%d]: CH_ST id:%d src:%d size:%f",
00076         id(), msg->id(), msg->src(),msg->size());
00077     
00078     ASSERT(state_ == OPEN);
00079     state_ = BUSY;
00080     double tr = msg->size()/bw_;
00081     ASSERT(tr >0);
00082     double tmp = Simulator::time() + tr ; 
00083     Event_chew_fin* e2 =
00084         new Event_chew_fin(tmp,this,msg,Simulator::time());
00085     chewing_event_ = e2;
00086     log_debug("ChSt-ChEvent[%d]: event:%p",id(), e2);
00087     Simulator::post(e2);
00088 }
00089 
00090 
00091 bool
00092 SimContact::is_open() 
00093 {
00094     return state_ == OPEN ;
00095 }
00096 
00097 
00098 
00099 void 
00100 SimContact::chewing_complete(double size, Message* msg) 
00101 {
00102     log_info("C[%d]: CH_CMP id:%d src:%d size:%2f trans:%2f", 
00103              id(),msg->id(),msg->src(),msg->size(),size);
00104     if (size > msg->size()) {
00105         log_debug(" transmit size exceeding message (%d) size (%2f > %2f) "
00106                   ,msg->id(),size,msg->size());
00107         size = msg->size();
00108     }
00109     
00110     if (state_ == CLOSE)
00111         log_err("C[%d]: closed when chewing complete",id());
00112     
00113     if (size != 0) {
00114         Event_message_received* e = 
00115             new Event_message_received(Simulator::time()+latency_,dst_,size,this,msg);
00116         Simulator::post(e);
00117     }
00118     src_->chewing_complete(this,size,msg);
00119 }
00120 
00121 
00122 void 
00123 remove_event(Event* e) 
00124 {
00125     if (e != NULL)
00126         Simulator::remove_event(e);
00127 }
00128 
00129 
00130 void
00131 SimContact::open_contact(bool forever) 
00132 {
00133     remove_event(future_updown_event_);
00134     future_updown_event_ = NULL;
00135     
00136     // if it is a regular scheduled open, schedule a future down event
00137     if (!forever) {
00138         // schedule a link down event
00139         double next = up_;
00140         Event_contact_down* e = new Event_contact_down(Simulator::time()+next,this);
00141         Simulator::post(e);
00142         future_updown_event_ = e;
00143     }
00144     
00145     state_ = OPEN;
00146     // send message to src, telling about that the contact is available
00147     src_->open_contact(this);
00148 }
00149 
00150 
00151 
00152 void 
00153 SimContact::close_contact(bool forever) 
00154 {
00155 
00156     remove_event(future_updown_event_);
00157     future_updown_event_ = NULL;
00158     if (!forever) {
00159         // schedule a link up event
00160         double next = down_;
00161         Event_contact_up* e = new Event_contact_up(Simulator::time()+next,this);
00162         Simulator::post(e);
00163         future_updown_event_ = e;
00164     }
00165     
00166     
00167     if (state_ == BUSY) {
00168         log_info("C[%d]: state busy while closing",
00169                  id());
00170         // fragmentation has to occur
00171         ASSERT(chewing_event_ != NULL);
00172         // schedule partial chewing complete
00173         double transmit_time = Simulator::time() - chewing_event_->chew_starttime_;
00174         double size_transmit = (bw_*transmit_time);
00175         
00176         if (!SimContact::ALLOW_FRAGMENTATION) {
00177             size_transmit = 0;
00178         } else if (SimContact::DISALLOW_FRACTIONAL_TRANSFERS) {
00179             size_transmit = (int)(size_transmit);
00180         }
00181         chewing_complete(size_transmit,chewing_event_->msg_);
00182         remove_event(chewing_event_);
00183         chewing_event_ = NULL;
00184         
00185     }
00186     // tell the source that this contact is closed
00187     src_->close_contact(this);
00188     state_ = CLOSE;
00189 }
00190 
00191 
00192 void 
00193 SimContact::process(Event* e) 
00194 {
00195     switch (e->type()) {
00196     case CONTACT_UP : {
00197         log_info("C[%d]: N[%d]->N[%d] UP NOW",id(),src_->id(),dst_->id());
00198         open_contact(((Event_contact_up* )e)->forever_);
00199         break;
00200     }
00201     case CONTACT_DOWN : {
00202         log_info("C[%d]: N[%d]->N[%d] DOWN NOW",id(),src_->id(),dst_->id());
00203         close_contact(((Event_contact_down* )e)->forever_);
00204         break;
00205     }
00206     case CONTACT_CHEWING_FINISHED : {
00207         Event_chew_fin* e1 = (Event_chew_fin* )e;
00208         log_debug(
00209             "CChFin[%d] event:%p bundleid:%d chewing_event:%p start at:%f",
00210             id(),e,e1->msg_->id(),chewing_event_,e1->chew_starttime_);
00211         if (state_ == CLOSE)  {
00212             ASSERT(false);
00213             return;
00214         }
00215         state_ = OPEN;
00216         log_debug("chewing_event NULL:%p",chewing_event_);
00217             
00218         //we have to make sure that this event is set to NULL
00219         //before we call chewing_complete
00220         chewing_event_ = NULL;
00221         chewing_complete( e1->msg_->size(),e1->msg_);
00222         //src_->open_contact(this);
00223         break;
00224     } 
00225     default:
00226         PANIC("undefined event \n");
00227     }
00228 }
00229 
00230 
00231 
00232 
00233 
00234 
00235 } // namespace dtnsim

Generated on Fri Dec 22 14:48:00 2006 for DTN Reference Implementation by  doxygen 1.5.1