sessionhelper.cc
上传用户:rrhhcc
上传日期:2015-12-11
资源大小:54129k
文件大小:11k
源码类别:

通讯编程

开发平台:

Visual C++

  1. /* -*- Mode:C++; c-basic-offset:8; tab-width:8; indent-tabs-mode:t -*- */
  2. /*
  3.  * Copyright (C) 1997 by the University of Southern California
  4.  * $Id: sessionhelper.cc,v 1.22 2005/09/18 23:33:31 tomh Exp $
  5.  *
  6.  * This program is free software; you can redistribute it and/or
  7.  * modify it under the terms of the GNU General Public License,
  8.  * version 2, as published by the Free Software Foundation.
  9.  *
  10.  * This program is distributed in the hope that it will be useful,
  11.  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  12.  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  13.  * GNU General Public License for more details.
  14.  *
  15.  * You should have received a copy of the GNU General Public License along
  16.  * with this program; if not, write to the Free Software Foundation, Inc.,
  17.  * 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
  18.  *
  19.  *
  20.  * The copyright of this module includes the following
  21.  * linking-with-specific-other-licenses addition:
  22.  *
  23.  * In addition, as a special exception, the copyright holders of
  24.  * this module give you permission to combine (via static or
  25.  * dynamic linking) this module with free software programs or
  26.  * libraries that are released under the GNU LGPL and with code
  27.  * included in the standard release of ns-2 under the Apache 2.0
  28.  * license or under otherwise-compatible licenses with advertising
  29.  * requirements (or modified versions of such code, with unchanged
  30.  * license).  You may copy and distribute such a system following the
  31.  * terms of the GNU GPL for this module and the licenses of the
  32.  * other code concerned, provided that you include the source code of
  33.  * that other code when and as the GNU GPL requires distribution of
  34.  * source code.
  35.  *
  36.  * Note that people who make modified versions of this module
  37.  * are not obligated to grant this special exception for their
  38.  * modified versions; it is their choice whether to do so.  The GNU
  39.  * General Public License gives permission to release a modified
  40.  * version without this exception; this exception also makes it
  41.  * possible to release a modified version which carries forward this
  42.  * exception.
  43.  *
  44.  */
  45. /* 
  46.  * Contributed by Polly Huang (USC/ISI), http://www-scf.usc.edu/~bhuang
  47.  *
  48.  */
  49. #ifndef lint
  50. static const char rcsid[] =
  51.     "@(#) $Header: /cvsroot/nsnam/ns-2/common/sessionhelper.cc,v 1.22 2005/09/18 23:33:31 tomh Exp $ (USC/ISI)";
  52. #endif
  53. #include "config.h"
  54. #include "tclcl.h"
  55. #include "ip.h"
  56. #include "packet.h"
  57. #include "connector.h"
  58. #include "errmodel.h"
  59. //Definitions for special reference count events
  60. class RcEvent : public Event {
  61. public:
  62. Packet* packet_;
  63. Handler* real_handler_;
  64. };
  65. class RcHandler : public Handler {
  66. public:
  67. void handle(Event* event);
  68. } rc_handler;
  69. void RcHandler::handle(Event* e)
  70. {
  71. RcEvent* rc = (RcEvent*)e;
  72. rc->real_handler_->handle(rc->packet_);
  73. delete rc;
  74. }
  75. struct dstobj {
  76. double bw;
  77. double delay;
  78. double prev_arrival;
  79. int ttl;
  80. int dropped;
  81. nsaddr_t addr;
  82. NsObject *obj;
  83. dstobj *next;
  84. };
  85. struct rcv_depobj {
  86. dstobj *obj;
  87. rcv_depobj *next;
  88. };
  89. struct loss_depobj {
  90. ErrorModel *obj;
  91. loss_depobj *loss_dep;
  92. rcv_depobj *rcv_dep;
  93. loss_depobj *next;
  94. };
  95. class SessionHelper : public Connector {
  96. public:
  97. SessionHelper();
  98. int command(int, const char*const*);
  99. void recv(Packet*, Handler*);
  100. protected:
  101. void get_dropped(loss_depobj*, Packet*);
  102. void mark_dropped(loss_depobj*);
  103. void clear_dropped();
  104. dstobj* find_dstobj(NsObject*);
  105. void delete_dstobj(NsObject*);
  106. loss_depobj* find_loss_depobj(ErrorModel*);
  107. void show_dstobj();
  108. void show_loss_depobj(loss_depobj*);
  109. nsaddr_t src_;
  110. dstobj *dstobj_;
  111. loss_depobj *loss_dependency_;
  112. int ndst_;
  113. int rc_; //enable reference count
  114. };
  115. static class SessionHelperClass : public TclClass {
  116. public:
  117. SessionHelperClass() : TclClass("SessionHelper") {}
  118. TclObject* create(int, const char*const*) {
  119. return (new SessionHelper());
  120. }
  121. } class_sessionhelper;
  122. SessionHelper::SessionHelper() : dstobj_(0), ndst_(0), rc_(0)
  123. {
  124. bind("rc_", &rc_);
  125. loss_dependency_ = new loss_depobj;
  126. loss_dependency_->obj = 0;
  127. loss_dependency_->loss_dep = 0;
  128. loss_dependency_->rcv_dep = 0;
  129. loss_dependency_->next = 0;
  130. }
  131. void SessionHelper::recv(Packet* pkt, Handler*)
  132. {
  133. Scheduler& s = Scheduler::instance();
  134. hdr_cmn* th = hdr_cmn::access(pkt);
  135. hdr_ip* iph = hdr_ip::access(pkt);
  136. double tmp_arrival;
  137. //printf ("src %d,  size %d, iface %dn", src_, th->size(), th->iface());
  138. clear_dropped();
  139. get_dropped(loss_dependency_->loss_dep, pkt);
  140. for (dstobj *tmpdst = dstobj_; tmpdst; tmpdst = tmpdst->next) {
  141. int ttl;
  142. if (tmpdst->dropped 
  143.     || (ttl = iph->ttl() - tmpdst->ttl) <= 0)
  144. continue;
  145. if (tmpdst->bw == 0) {
  146. tmp_arrival = tmpdst->delay;
  147. } else {
  148. tmp_arrival = th->size()*8/tmpdst->bw + tmpdst->delay;
  149. }
  150. if (tmpdst->prev_arrival >= tmp_arrival) {
  151. tmp_arrival = tmpdst->prev_arrival + 0.000001;
  152. /* Assume 1 ns process delay; just to maintain the causality */
  153. }
  154. tmpdst->prev_arrival = tmp_arrival;
  155. if (rc_) {
  156. // reference count
  157. //s.rc_schedule(tmpdst->obj, pkt, tmp_arrival);
  158. RcEvent* rc = new RcEvent;
  159. rc->packet_ = pkt->refcopy();
  160. rc->real_handler_ = tmpdst->obj;
  161. s.schedule(&rc_handler, rc, tmp_arrival);
  162. } else {
  163. Packet* tmppkt = pkt->copy();
  164. hdr_ip* tmpiph = hdr_ip::access(tmppkt);
  165. tmpiph->ttl() = ttl;
  166. s.schedule(tmpdst->obj, tmppkt, tmp_arrival);
  167. }
  168. }
  169. Packet::free(pkt);
  170. }
  171. void SessionHelper::get_dropped(loss_depobj* loss_dep, Packet* pkt)
  172. {
  173. if (loss_dep != 0) 
  174. if (loss_dep->obj != 0) {
  175. if (loss_dep->obj->corrupt(pkt)) {
  176. mark_dropped(loss_dep);
  177. } else {
  178. get_dropped(loss_dep->loss_dep, pkt);
  179. }
  180. get_dropped(loss_dep->next, pkt);
  181. }
  182. }
  183. void SessionHelper::mark_dropped(loss_depobj* loss_dep)
  184. {
  185. if (loss_dep != 0) {
  186. rcv_depobj *tmprcv_dep = loss_dep->rcv_dep;
  187. loss_depobj *tmploss_dep = loss_dep->loss_dep;
  188. while (tmprcv_dep != 0) {
  189. tmprcv_dep->obj->dropped = 1;
  190. tmprcv_dep = tmprcv_dep->next;
  191. }
  192. while (tmploss_dep != 0) {
  193. mark_dropped(tmploss_dep);
  194. tmploss_dep = tmploss_dep->next;
  195. }
  196. }
  197. }
  198. void SessionHelper::clear_dropped()
  199. {
  200. dstobj *tmpdst = dstobj_;
  201. while (tmpdst != 0) {
  202. tmpdst->dropped = 0;
  203. tmpdst = tmpdst->next;
  204. }
  205. }
  206. dstobj* SessionHelper::find_dstobj(NsObject* obj) {
  207. dstobj *tmpdst = dstobj_;
  208. while (tmpdst != 0) {
  209. if (tmpdst->obj == obj) return (tmpdst);
  210. tmpdst = tmpdst->next;
  211. }
  212. return 0;
  213. }
  214. loss_depobj* SessionHelper::find_loss_depobj(ErrorModel* err) {
  215. struct stackobj {
  216. loss_depobj *loss_obj;
  217. stackobj *next;
  218. };
  219. if (!loss_dependency_) return 0;
  220. stackobj *top = new stackobj;
  221. top->loss_obj = loss_dependency_;
  222. top->next = 0;
  223. while (top != 0) {
  224. if (top->loss_obj->obj == err) {
  225. loss_depobj *tmp_loss_obj = top->loss_obj;
  226. while (top != 0) {
  227. stackobj *befreed = top;
  228. top = top->next;
  229. free(befreed);
  230. }
  231. return (tmp_loss_obj);
  232. }
  233. loss_depobj *tmploss = top->loss_obj->loss_dep;
  234. stackobj *befreed = top;
  235. top = top->next;
  236. free(befreed);
  237. while (tmploss != 0) {
  238. stackobj *new_element = new stackobj;
  239. new_element->loss_obj = tmploss;
  240. new_element->next = top;
  241. top = new_element;
  242. tmploss = tmploss->next;
  243. }
  244. }
  245. return 0;
  246. }
  247. void SessionHelper::show_dstobj() {
  248. dstobj *tmpdst = dstobj_;
  249. while (tmpdst != 0) {
  250. printf("bw:%.2f, delay:%.2f, ttl:%d, dropped:%d, addr:%d, obj:%sn", tmpdst->bw, tmpdst->delay, tmpdst->ttl, tmpdst->dropped, tmpdst->addr, tmpdst->obj->name());
  251. tmpdst = tmpdst->next;
  252. }
  253. }
  254. void SessionHelper::delete_dstobj(NsObject *obj) {
  255. dstobj *tmpdst = dstobj_;
  256. dstobj *tmpprev = 0;
  257. while (tmpdst != 0) {
  258. if (tmpdst->obj == obj) {
  259. if (tmpprev == 0) dstobj_ = tmpdst->next;
  260. else tmpprev->next = tmpdst->next;
  261. free(tmpdst);
  262. return;
  263. }
  264. tmpprev = tmpdst;
  265. tmpdst = tmpdst->next;
  266. }
  267. }
  268. void SessionHelper::show_loss_depobj(loss_depobj *loss_obj) {
  269. loss_depobj *tmploss = loss_obj->loss_dep;
  270. rcv_depobj *tmprcv = loss_obj->rcv_dep;
  271. while (tmprcv != 0) {
  272. printf("%d ", tmprcv->obj->addr);
  273. tmprcv = tmprcv->next;
  274. }
  275. while (tmploss != 0) {
  276. printf("(%s: ", tmploss->obj->name());
  277. show_loss_depobj(tmploss);
  278. tmploss = tmploss->next;
  279. }
  280. if (loss_obj == loss_dependency_) {
  281. printf("n");
  282. } else {
  283. printf(")");
  284. }
  285. }
  286. int SessionHelper::command(int argc, const char*const* argv)
  287. {
  288. Tcl& tcl = Tcl::instance();
  289. if (argc == 2) {
  290. if (strcmp(argv[1], "list-mbr") == 0) {
  291. dstobj *tmp = dstobj_;
  292. while (tmp != 0) {
  293. tcl.resultf("%s %s", tcl.result(),
  294.     tmp->obj->name());
  295. tmp = tmp->next;
  296. }
  297. return (TCL_OK);
  298. }
  299. if (strcmp(argv[1], "show-loss-depobj") == 0) {
  300. show_loss_depobj(loss_dependency_);
  301. return (TCL_OK);
  302. }
  303. if (strcmp(argv[1], "show-dstobj") == 0) {
  304. show_dstobj();
  305. return (TCL_OK);
  306. }
  307. } else if (argc == 3) {
  308. if (strcmp(argv[1], "set-node") == 0) {
  309. int src = atoi(argv[2]);
  310. src_ = src;
  311. //printf("set node %dn", src_);
  312. return (TCL_OK);
  313. }
  314. if (strcmp(argv[1], "update-loss-top") == 0) {
  315. loss_depobj *tmploss = (loss_depobj*)(atol(argv[2]));
  316. tmploss->next = loss_dependency_->loss_dep;
  317. loss_dependency_->loss_dep = tmploss;
  318. return (TCL_OK);
  319. }
  320. } else if (argc == 4) {
  321. if (strcmp(argv[1], "update-loss-rcv") == 0) {
  322. ErrorModel *tmperr = (ErrorModel*)TclObject::lookup(argv[2]);
  323. NsObject *tmpobj = (NsObject*)TclObject::lookup(argv[3]);
  324. //printf("errmodel %s, agent %sn", tmperr->name(), tmpobj->name());
  325. loss_depobj *tmploss = find_loss_depobj(tmperr);
  326. //printf ("%d, loss_dependency_ %dn", tmploss, loss_dependency_);
  327. if (!tmploss) {
  328. tmploss = new loss_depobj;
  329. tmploss->obj = tmperr;
  330. tmploss->next = 0;
  331. tmploss->rcv_dep = 0;
  332. tmploss->loss_dep = 0;
  333. tcl.resultf("%ld", tmploss);
  334. } else {
  335. tcl.result("0");
  336. }
  337. rcv_depobj *tmprcv = new rcv_depobj;
  338. tmprcv->obj = find_dstobj(tmpobj);
  339. tmprcv->next = tmploss->rcv_dep;
  340. tmploss->rcv_dep = tmprcv;
  341. return (TCL_OK);
  342. }
  343. if (strcmp(argv[1], "update-loss-loss") == 0) {
  344. ErrorModel *tmperrparent = (ErrorModel*)TclObject::lookup(argv[2]);
  345. loss_depobj *tmplossparent = find_loss_depobj(tmperrparent);
  346. loss_depobj *tmplosschild = (loss_depobj*)(atol(argv[3]));
  347. if (!tmplossparent) {
  348. tmplossparent = new loss_depobj;
  349. tmplossparent->obj = tmperrparent;
  350. tmplossparent->next = 0;
  351. tmplossparent->loss_dep = 0;
  352. tmplossparent->rcv_dep = 0;
  353. tcl.resultf("%ld", tmplossparent);
  354. } else {
  355. tcl.result("0");
  356. }
  357. tmplosschild->next = tmplossparent->loss_dep;
  358. tmplossparent->loss_dep = tmplosschild;
  359. return (TCL_OK);
  360. }
  361. if (strcmp(argv[1], "delete-dst") == 0) {
  362. int tmpaddr = atoi(argv[2]);
  363. //NsObject *tmpobj = (NsObject*)TclObject::lookup(argv[3]);
  364. printf ("addr = %dn", tmpaddr);
  365. return (TCL_OK);
  366. }
  367. } else if (argc == 7) {
  368. if (strcmp(argv[1], "add-dst") == 0) {
  369. dstobj *tmp = new dstobj;
  370. tmp->bw = atof(argv[2]);
  371. tmp->delay = atof(argv[3]);
  372. tmp->prev_arrival = 0;
  373. tmp->ttl = atoi(argv[4]);
  374. tmp->addr = atoi(argv[5]);
  375. tmp->obj = (NsObject*)TclObject::lookup(argv[6]);
  376. //printf ("addr = %d, argv3 = %s, obj = %d, ttl=%dn", tmp->addr, argv[3], tmp->obj, tmp->ttl);
  377. tmp->next = dstobj_;
  378. dstobj_ = tmp;
  379. ndst_ += 1;
  380. return (TCL_OK);
  381. }
  382. }
  383. return (Connector::command(argc, argv));
  384. }