00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017 #include "SimContact.h"
00018 #include "Simulator.h"
00019
00020 namespace dtnsim {
00021
00022
00023 SimContact::SimContact (int id, Node* src, Node* dst,
00024 double bw, double latency, bool isup, int pup, int pdown)
00025 : Logger ("/sim/simcontact")
00026 {
00027 id_ = id;
00028 src_ = src;
00029 dst_ = dst;
00030 bw_ = bw;
00031 latency_ = latency;
00032 up_ = pup;
00033 down_ = pdown;
00034 ASSERT(bw > 0 && latency >= 0) ;
00035
00036 log_info("C[%d]: CONTACT CREATED: N[%d]->N[%d]\n",
00037 id_,src_->id(),dst_->id());
00038
00039 chewing_event_ = NULL;
00040 future_updown_event_ = NULL;
00041
00042 if (isup) {
00043 open_contact(false);
00044 } else {
00045 close_contact(false);
00046 }
00047 }
00048
00049
00050
00051 void
00052 SimContact::chew_message(Message* msg)
00053 {
00054 log_info("C[%d]: CH_ST id:%d src:%d size:%f",
00055 id(), msg->id(), msg->src(),msg->size());
00056
00057 ASSERT(state_ == OPEN);
00058 state_ = BUSY;
00059 double tr = msg->size()/bw_;
00060 ASSERT(tr >0);
00061 double tmp = Simulator::time() + tr ;
00062 Event_chew_fin* e2 =
00063 new Event_chew_fin(tmp,this,msg,Simulator::time());
00064 chewing_event_ = e2;
00065 log_debug("ChSt-ChEvent[%d]: event:%p",id(), e2);
00066 Simulator::post(e2);
00067 }
00068
00069
00070 bool
00071 SimContact::is_open()
00072 {
00073 return state_ == OPEN ;
00074 }
00075
00076
00077
00078 void
00079 SimContact::chewing_complete(double size, Message* msg)
00080 {
00081 log_info("C[%d]: CH_CMP id:%d src:%d size:%2f trans:%2f",
00082 id(),msg->id(),msg->src(),msg->size(),size);
00083 if (size > msg->size()) {
00084 log_debug(" transmit size exceeding message (%d) size (%2f > %2f) "
00085 ,msg->id(),size,msg->size());
00086 size = msg->size();
00087 }
00088
00089 if (state_ == CLOSE)
00090 log_err("C[%d]: closed when chewing complete",id());
00091
00092 if (size != 0) {
00093 Event_message_received* e =
00094 new Event_message_received(Simulator::time()+latency_,dst_,size,this,msg);
00095 Simulator::post(e);
00096 }
00097 src_->chewing_complete(this,size,msg);
00098 }
00099
00100
00101 void
00102 remove_event(Event* e)
00103 {
00104 if (e != NULL)
00105 Simulator::remove_event(e);
00106 }
00107
00108
00109 void
00110 SimContact::open_contact(bool forever)
00111 {
00112 remove_event(future_updown_event_);
00113 future_updown_event_ = NULL;
00114
00115
00116 if (!forever) {
00117
00118 double next = up_;
00119 Event_contact_down* e = new Event_contact_down(Simulator::time()+next,this);
00120 Simulator::post(e);
00121 future_updown_event_ = e;
00122 }
00123
00124 state_ = OPEN;
00125
00126 src_->open_contact(this);
00127 }
00128
00129
00130
00131 void
00132 SimContact::close_contact(bool forever)
00133 {
00134
00135 remove_event(future_updown_event_);
00136 future_updown_event_ = NULL;
00137 if (!forever) {
00138
00139 double next = down_;
00140 Event_contact_up* e = new Event_contact_up(Simulator::time()+next,this);
00141 Simulator::post(e);
00142 future_updown_event_ = e;
00143 }
00144
00145
00146 if (state_ == BUSY) {
00147 log_info("C[%d]: state busy while closing",
00148 id());
00149
00150 ASSERT(chewing_event_ != NULL);
00151
00152 double transmit_time = Simulator::time() - chewing_event_->chew_starttime_;
00153 double size_transmit = (bw_*transmit_time);
00154
00155 if (!SimContact::ALLOW_FRAGMENTATION) {
00156 size_transmit = 0;
00157 } else if (SimContact::DISALLOW_FRACTIONAL_TRANSFERS) {
00158 size_transmit = (int)(size_transmit);
00159 }
00160 chewing_complete(size_transmit,chewing_event_->msg_);
00161 remove_event(chewing_event_);
00162 chewing_event_ = NULL;
00163
00164 }
00165
00166 src_->close_contact(this);
00167 state_ = CLOSE;
00168 }
00169
00170
00171 void
00172 SimContact::process(Event* e)
00173 {
00174 switch (e->type()) {
00175 case CONTACT_UP : {
00176 log_info("C[%d]: N[%d]->N[%d] UP NOW",id(),src_->id(),dst_->id());
00177 open_contact(((Event_contact_up* )e)->forever_);
00178 break;
00179 }
00180 case CONTACT_DOWN : {
00181 log_info("C[%d]: N[%d]->N[%d] DOWN NOW",id(),src_->id(),dst_->id());
00182 close_contact(((Event_contact_down* )e)->forever_);
00183 break;
00184 }
00185 case CONTACT_CHEWING_FINISHED : {
00186 Event_chew_fin* e1 = (Event_chew_fin* )e;
00187 log_debug(
00188 "CChFin[%d] event:%p bundleid:%d chewing_event:%p start at:%f",
00189 id(),e,e1->msg_->id(),chewing_event_,e1->chew_starttime_);
00190 if (state_ == CLOSE) {
00191 ASSERT(false);
00192 return;
00193 }
00194 state_ = OPEN;
00195 log_debug("chewing_event NULL:%p",chewing_event_);
00196
00197
00198
00199 chewing_event_ = NULL;
00200 chewing_complete( e1->msg_->size(),e1->msg_);
00201
00202 break;
00203 }
00204 default:
00205 PANIC("undefined event \n");
00206 }
00207 }
00208
00209
00210
00211
00212
00213
00214 }