00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
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;
00054 down_ = pdown;
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
00063 if (isup) {
00064 open_contact(false);
00065 } else {
00066 close_contact(false);
00067 }
00068 }
00069
00070
00071
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
00137 if (!forever) {
00138
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
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
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
00171 ASSERT(chewing_event_ != NULL);
00172
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
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
00219
00220 chewing_event_ = NULL;
00221 chewing_complete( e1->msg_->size(),e1->msg_);
00222
00223 break;
00224 }
00225 default:
00226 PANIC("undefined event \n");
00227 }
00228 }
00229
00230
00231
00232
00233
00234
00235 }