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
00039 #include "conv_layers/ConvergenceLayer.h"
00040 #include "bundling/BundleActions.h"
00041 #include "contacts/ContactManager.h"
00042 #include "bundling/BundleDaemon.h"
00043 #include "routing/RouteTable.h"
00044 #include <oasys/io/NetUtils.h>
00045 #include "contacts/InterfaceTable.h"
00046 #include "conv_layers/TCPConvergenceLayer.h"
00047
00048 #include "TcaRouter.h"
00049
00050 namespace dtn {
00051
00052
00053
00054
00055
00056 static const std::string BL = "tca://localhost/bundlelayer";
00057
00058
00060
00061
00062
00063
00064
00065 static std::string
00066 get_payload_str(const Bundle* b)
00067 {
00068 size_t len = b->payload_.length();
00069 u_char data[len+1];
00070 const u_char* p = b->payload_.read_data(0, len, data);
00071 return (const char*)p;
00072 }
00073
00074
00075
00076 static bool
00077 check_nargs(const TcaControlBundle& cb, uint n_expected)
00078 {
00079 if (cb.args_.size() != n_expected)
00080 {
00081 log_err("dtn/tca", "TcaRouter: bundle '%s' contains wrong number "
00082 "of args. %d expected.", cb.str().c_str(), n_expected);
00083 return false;
00084 }
00085 return true;
00086 }
00087
00088
00089
00090 static void
00091 log_bundle(const std::string& comment, const Bundle* b, bool include_payload)
00092 {
00093 (void)comment;
00094 (void)b;
00095
00096 if (include_payload)
00097 log_debug("/dtn/tca", "%s [%s] -> [%s] : '%s'", comment.c_str(),
00098 b->source_.str().c_str(), b->dest_.c_str(),
00099 get_payload_str(b).c_str());
00100 else
00101 log_debug("/dtn/tca", "%s [%s] -> [%s]", comment.c_str(),
00102 b->source_.str().c_str(), b->dest_.c_str());
00103 }
00104
00105
00106 static void
00107 log_controlbundle(const TcaControlBundle& cb)
00108 {
00109 log_debug("/dtn/tca", " code='%s', args=%d",
00110 cb.code_.c_str(), (u_int)cb.args_.size());
00111 for (unsigned int i=0; i<cb.args_.size(); ++i)
00112 {
00113 log_debug("/dtn/tca", " '%s'", cb.args_[i].c_str());
00114 }
00115 }
00116
00117
00118
00119
00120
00121
00122
00123
00124
00125
00126
00127
00129
00130
00131 TcaRouter::TcaRouter(Role role)
00132 : TableBasedRouter("TcaRouter", "TcaRouter")
00133 {
00134 role_ = role;
00135
00136
00137 admin_app_ = BundleDaemon::instance()->local_eid();
00138 admin_app_.set_app("admin");
00139
00140 logpathf("/dtn/tca");
00141
00142 log_info("TcaRouter started: role='%s', admin_app='%s'",
00143 get_role_str().c_str(), admin_app_.c_str());
00144 }
00145
00146
00147 std::string
00148 TcaRouter::get_role_str() const
00149 {
00150 switch (role_)
00151 {
00152 case TCA_MOBILE: return "mobile";
00153 case TCA_ROUTER: return "router";
00154 case TCA_GATEWAY: return "gateway";
00155 default: return "null";
00156 }
00157
00158 }
00159
00160
00161 void
00162 TcaRouter::handle_bundle_received(BundleReceivedEvent* event)
00163 {
00164 Bundle* bundle = event->bundleref_.object();
00165
00166
00167
00168
00169
00170
00171
00172
00173 EndpointID dest = bundle->dest_;
00174
00175 if (dest.scheme_str() == "tca")
00176 {
00177 log_bundle("TcaRouter: tca bundle received", bundle, true);
00178
00179 TcaEndpointID tca_dest(dest);
00180
00181 if (tca_dest.ssp() == "//registry")
00182 {
00183 handle_register(bundle);
00184 }
00185
00186 else if (tca_dest.app() == "admin.coa")
00187 {
00188 handle_coa(bundle);
00189 }
00190
00191 else if (tca_dest.ssp().substr(0,11) == "//anonymous")
00192 {
00193 handle_anonymous_bundle(bundle);
00194 }
00195
00196 else if (tca_dest.ssp() == "//localhost/bundlelayer")
00197 {
00198 handle_bl_control_bundle(bundle);
00199 }
00200
00201 else if (tca_dest.host() != admin_app_.host())
00202 {
00203
00204
00205
00206 handle_tca_unbound_bundle(bundle);
00207 }
00208 }
00209
00210 else
00211 {
00212
00213 fwd_to_matching(bundle);
00214 }
00215 }
00216
00217
00218 void
00219 TcaRouter::handle_bundle_transmitted(BundleTransmittedEvent* event)
00220 {
00221 Bundle* b = event->bundleref_.object();
00222 log_debug("TcaRouter: handle bundle transmitted: *%p", b);
00223
00224 EndpointID dest = b->dest_;
00225
00226 if (dest.scheme_str() == "tca")
00227 {
00228
00229
00230
00231
00232
00233
00234
00235 TcaEndpointID tca_dest(dest);
00236 if (tca_dest.app() == "admin.coa")
00237 {
00238 TcaControlBundle cb(get_payload_str(b));
00239 on_coa_transmitted(b, cb);
00240 }
00241 else if (tca_dest.app() == "admin.ask")
00242 {
00243 TcaControlBundle cb(get_payload_str(b));
00244 on_ask_transmitted(b, cb);
00245 }
00246 else if (tca_dest.app() == "admin")
00247 {
00248 TcaControlBundle cb(get_payload_str(b));
00249 if (cb.code_ == "adv")
00250 {
00251 on_adv_transmitted(b, cb);
00252 }
00253 }
00254 }
00255 }
00256
00257
00258
00259
00260
00261 void
00262 TcaRouter::handle_contact_up(ContactUpEvent* event)
00263 {
00264
00265
00266 TableBasedRouter::handle_contact_up(event);
00267 log_debug("TcaRouter::contact up");
00268 post_bundle(BL, admin_app_, "contact_up");
00269 }
00270
00271
00272 void
00273 TcaRouter::handle_contact_down(ContactDownEvent* event)
00274 {
00275 (void)event;
00276 log_debug("TcaRouter::contact down");
00277 post_bundle(BL, admin_app_, "contact_down");
00278
00279 }
00280
00281
00282 void
00283 TcaRouter::handle_link_available(LinkAvailableEvent* event)
00284 {
00285
00286
00287 TableBasedRouter::handle_link_available(event);
00288 log_debug("TcaRouter::link available");
00289 post_bundle(BL, admin_app_, "link_available");
00290 }
00291
00292
00293 void
00294 TcaRouter::handle_link_unavailable(LinkUnavailableEvent* event)
00295 {
00296 (void)event;
00297 log_debug("TcaRouter::link unavailable");
00298 post_bundle(BL, admin_app_, "link_unavailable");
00299 }
00300
00301
00302 void
00303 TcaRouter::handle_shutdown_request(ShutdownRequest* event)
00304 {
00305 (void)event;
00306 log_debug("TcaRouter::daemon shutdown");
00307 post_bundle(BL, admin_app_, "daemon_shutdown");
00308 }
00309
00310
00311
00312
00313
00314 int
00315 TcaRouter::fwd_to_all(Bundle* bundle)
00316 {
00317 RouteEntryVec matches;
00318 RouteEntryVec::iterator iter;
00319
00320 std::string pattern = "tca://*";
00321 EndpointID tca_all = pattern;
00322
00323 route_table_->get_matching(tca_all, &matches);
00324
00325 int count = 0;
00326 for (iter = matches.begin(); iter != matches.end(); ++iter)
00327 {
00328 log_debug("TcaRouter::fwd_to_all: %s",
00329 (*iter)->dest_pattern_.str().c_str());
00330 fwd_to_nexthop(bundle, *iter);
00331 ++count;
00332 }
00333
00334 log_debug("TcaRouter::fwd_to_all dest='%s': %d matches",
00335 bundle->dest_.c_str(), count);
00336 return count;
00337 }
00338
00339
00340
00341
00342
00343
00344
00345 int
00346 TcaRouter::fwd_to_matching(Bundle* bundle, Link* next_hop)
00347 {
00348 ForwardingRule fwd_rule = get_forwarding_rule(bundle);
00349 return fwd_to_matching_r(bundle, next_hop, fwd_rule);
00350 }
00351
00352
00353
00354
00355
00356
00357 int
00358 TcaRouter::fwd_to_matching_r(Bundle* bundle, Link* next_hop,
00359 ForwardingRule fwd_rule)
00360 {
00361 log_debug("TcaRouter::fwd_to_matching_r: owner='%s'",
00362 bundle->owner_.c_str());
00363 log_debug("TcaRouter::fwd_to_matching_r: fwd_rule=%d", fwd_rule);
00364
00365 if (fwd_rule == FWD_NEVER) return 0;
00366
00367 RouteEntryVec matches;
00368 RouteEntryVec::iterator iter;
00369
00370 route_table_->get_matching(bundle->dest_, &matches);
00371
00372
00373 RouteEntry* default_route = NULL;
00374 RouteEntryVec hard_matches;
00375 for (iter = matches.begin(); iter != matches.end(); ++iter)
00376 {
00377 if ((*iter)->dest_pattern_.str() == "tca://*")
00378 {
00379 default_route = *iter;
00380 }
00381 else
00382 {
00383 hard_matches.push_back(*iter);
00384 }
00385 }
00386
00387 if (fwd_rule == FWD_UDR_EXCLUSIVELY)
00388 {
00389 if (default_route != NULL)
00390 {
00391 fwd_to_nexthop(bundle, default_route);
00392 return 1;
00393 }
00394 }
00395
00396 int count = 0;
00397
00398
00399 if (fwd_rule == FWD_UDR_ALWAYS ||
00400 (fwd_rule == FWD_UDR_IFNECESSARY && hard_matches.size() == 0))
00401 {
00402 if (default_route != NULL)
00403 {
00404 fwd_to_nexthop(bundle, default_route);
00405 ++ count;
00406 }
00407 }
00408
00409
00410 for (iter = hard_matches.begin(); iter != hard_matches.end(); ++iter)
00411 {
00412 if (next_hop == NULL || (next_hop == (*iter)->next_hop_))
00413 {
00414 fwd_to_nexthop(bundle, *iter);
00415 ++count;
00416 }
00417 else
00418 {
00419 log_debug("fwd_to_matching_r dest='%s': "
00420 "ignoring match %s since next_hop link %s set",
00421 bundle->dest_.c_str(), (*iter)->next_hop_->name(),
00422 next_hop->name());
00423 }
00424 }
00425
00426 log_debug("fwd_to_matching_r dest='%s': %d matches",
00427 bundle->dest_.c_str(), count);
00428
00429 return count;
00430 }
00431
00432
00433 bool
00434 TcaRouter::on_coa_transmitted(Bundle* b, const TcaControlBundle& cb)
00435 {
00436 log_debug("TcaRouter: COA bundle transmitted");
00437
00438 TcaWrappedBundle wb(cb);
00439
00440 log_debug(" coa: source=%s, dest=%s",
00441 b->source_.c_str(),
00442 b->dest_.c_str());
00443
00444
00445 std::string coa_sent_payload = "coa_sent:";
00446 coa_sent_payload += b->source_.str();
00447 coa_sent_payload += "\t";
00448 coa_sent_payload += b->dest_.str();
00449 coa_sent_payload += "\t";
00450 coa_sent_payload += cb.args_[0];
00451
00452 log_debug(" coa_sent, payload='%s'", coa_sent_payload.c_str());
00453 post_bundle(BL, admin_app_, coa_sent_payload);
00454
00455 return true;
00456 }
00457
00458
00459 bool
00460 TcaRouter::on_ask_transmitted(Bundle* b, const TcaControlBundle& cb)
00461 {
00462 log_debug("TcaRouter: ASK bundle transmitted");
00463
00464 if (!check_nargs(cb, 1)) return false;
00465
00466
00467 std::string ask_sent= "ask_sent:";
00468 ask_sent += b->source_.str();
00469 ask_sent += "\t";
00470 ask_sent += b->dest_.str();
00471 ask_sent += "\t";
00472 ask_sent += cb.args_[0];
00473
00474 log_debug(" ask sent, payload='%s'", ask_sent.c_str());
00475 post_bundle(BL, admin_app_, ask_sent);
00476
00477 return false;
00478 }
00479
00480
00481 bool
00482 TcaRouter::on_adv_transmitted(Bundle* b, const TcaControlBundle& cb)
00483 {
00484 log_debug("TcaRouter: ADV bundle transmitted");
00485
00486 if (!check_nargs(cb, 2)) return false;
00487
00488
00489 std::string adv_sent= "adv_sent:";
00490 adv_sent += b->source_.str();
00491 adv_sent += "\t";
00492 adv_sent += b->dest_.str();
00493 adv_sent += "\t";
00494 adv_sent += cb.args_[0];
00495 adv_sent += "\t";
00496 adv_sent += cb.args_[1];
00497
00498 log_debug(" adv_sent, payload='%s'", adv_sent.c_str());
00499 post_bundle(BL, admin_app_, adv_sent);
00500
00501 return false;
00502 }
00503
00504
00505 bool
00506 TcaRouter::handle_register(Bundle* b)
00507 {
00508
00509
00510
00511
00512
00513 if (b->source_.str() == admin_app_.str())
00514 {
00515
00516
00517 fwd_to_matching_r(b, NULL, FWD_UDR_EXCLUSIVELY);
00518 }
00519 else
00520 {
00521
00522
00523
00524 TcaControlBundle cb(get_payload_str(b));
00525
00526 TcaWrappedBundle reg_received("reg_received",
00527 b->source_.str(), b->dest_.str());
00528
00529 log_debug("TcaRouter::handle_register:");
00530 log_controlbundle(cb);
00531
00532 if (cb.args_.size() == 2)
00533 {
00534
00535
00536 reg_received.append_arg(cb.args_[0]);
00537 reg_received.append_arg(cb.args_[1]);
00538 }
00539 else
00540 {
00541
00542
00543 reg_received.append_arg(b->source_.str());
00544 reg_received.append_arg("NULL");
00545 }
00546
00547 post_bundle(BL, admin_app_, reg_received.str());
00548 }
00549
00550 return true;
00551 }
00552
00553
00554 bool
00555 TcaRouter::handle_coa(Bundle* b)
00556 {
00557 log_debug("TcaRouter: COA bundle received");
00558
00559
00560 fwd_to_matching_r(b, NULL, FWD_UDR_NEVER);
00561
00562
00563
00564 return true;
00565 }
00566
00567
00568 bool
00569 TcaRouter::handle_anonymous_bundle(Bundle* b)
00570 {
00571
00572
00573
00574
00575 TcaEndpointID dest(b->dest_);
00576
00577 TcaControlBundle cb(get_payload_str(b));
00578
00579 if (cb.code_ == "ask")
00580 {
00581 return handle_ask(b, cb);
00582 }
00583 else
00584 {
00585 log_debug("TcaRouter:: unrecognized anonymous bundle code '%s'",
00586 cb.code_.c_str());
00587 return false;
00588 }
00589 }
00590
00591
00592 bool
00593 TcaRouter::handle_ask(Bundle* b, const TcaControlBundle& cb)
00594 {
00595 if (is_local_source(b))
00596 {
00597
00598
00599 fwd_to_matching_r(b, NULL, FWD_UDR_NEVER);
00600 }
00601 else
00602 {
00603 if (!check_nargs(cb, 1)) return false;
00604
00605
00606 std::string payload = "ask_received:";
00607 payload += b->source_.str();
00608 payload += "\t";
00609 payload += b->dest_.str();
00610 payload += "\t";
00611 payload += cb.args_[0];
00612
00613 post_bundle(BL, admin_app_, payload);
00614 }
00615
00616 return true;
00617 }
00618
00619
00620
00621
00622
00623
00624 bool
00625 TcaRouter::handle_bl_control_bundle(Bundle* b)
00626 {
00627 TcaControlBundle cb(get_payload_str(b));
00628
00629
00630 if (cb.code_ == "ask")
00631 {
00632 return handle_ask(b, cb);
00633 }
00634 else if (cb.code_ == "get_routes")
00635 {
00636 return handle_get_routes(b, cb);
00637 }
00638 else if (cb.code_ == "add_route")
00639 {
00640 return handle_add_route(b, cb);
00641 }
00642 else if (cb.code_ == "del_route")
00643 {
00644 return handle_del_route(b, cb);
00645 }
00646
00647 log_debug("TcaRouter: unknown control bundle type '%s'", cb.code_.c_str());
00648 return false;
00649
00650 }
00651
00652
00653 bool
00654 TcaRouter::handle_bl_ask(Bundle* b, const TcaControlBundle& cb)
00655 {
00656 (void)cb;
00657
00658
00659 return post_bundle(BL, b->source_,
00660 "adv:Don\'t ASK me. You should probably ASK the Control App,"
00661 " not the Bundle Layer.");
00662 }
00663
00664
00665 bool
00666 TcaRouter::handle_get_routes(Bundle* b, const TcaControlBundle& cb)
00667 {
00668 if (!check_nargs(cb, 1)) return false;
00669
00670 log_debug("TcaRouter:: get_routes bundle received. body = '%s'",
00671 cb.args_[0].c_str());
00672
00673 RouteEntryVec matches;
00674 RouteEntryVec::iterator iter;
00675
00676 EndpointIDPattern pattern(cb.args_[0]);
00677 route_table_->get_matching(pattern, &matches);
00678
00679 std::string response = "routes:";
00680 for (iter = matches.begin(); iter != matches.end(); ++iter)
00681 {
00682 response += (*iter)->dest_pattern_.str().c_str();
00683 response += "\t";
00684 }
00685
00686 post_bundle(BL, b->source_, response);
00687
00688 return true;
00689 }
00690
00691
00692 bool
00693 TcaRouter::handle_add_route(Bundle* b, const TcaControlBundle& cb)
00694 {
00695 (void)b;
00696
00697 if (!check_nargs(cb, 2)) return false;
00698
00699 const std::string& pattern = cb.args_[0];
00700 const std::string& link = cb.args_[1];
00701
00702 log_debug("TcaRouter:: add_route bundle received. "
00703 "pattern='%s', link='%s'\n", pattern.c_str(), link.c_str());
00704
00705 if (pattern.length() == 0 || link.length() == 0) return false;
00706
00707
00708
00709 return create_route(pattern, link);
00710 }
00711
00712
00713 bool
00714 TcaRouter::handle_del_route(Bundle* b, const TcaControlBundle& cb)
00715 {
00716 (void)b;
00717
00718 if (!check_nargs(cb, 1)) return false;
00719
00720 log_debug("TcaRouter:: del_route bundle received. body = '%s'",
00721 cb.args_[0].c_str());
00722
00723
00724
00725 route_table_->del_entries(cb.args_[0]);
00726 return true;
00727 }
00728
00729
00730
00731
00732
00733
00734
00735
00736
00737
00738
00739 bool
00740 TcaRouter::handle_tca_unbound_bundle(Bundle* bundle)
00741 {
00742 log_debug("TcaRouter::handle_tca_unbound_bundle...");
00743
00744 int n_matches = fwd_to_matching_r(bundle, NULL, FWD_UDR_IFNECESSARY);
00745
00746 if (n_matches == 0)
00747 {
00748 if (role_ == TCA_ROUTER)
00749 {
00750
00751
00752 log_err("TcaRouter: Error. TCA_ROUTER has no route to dest %s",
00753 bundle->dest_.c_str());
00754 return false;
00755 }
00756 else if (role_ == TCA_GATEWAY)
00757 {
00758
00759
00760
00761
00762 std::string payload = "unb:";
00763 payload += bundle->dest_.str();
00764 post_bundle(BL, admin_app_, payload);
00765 }
00766 }
00767 return true;
00768 }
00769
00770
00771
00772 bool
00773 TcaRouter::is_local_source(Bundle* b)
00774 {
00775 TcaEndpointID src(b->source_);
00776 return src.get_hostid() == admin_app_.get_hostid();
00777 }
00778
00779
00780 TcaRouter::ForwardingRule
00781 TcaRouter::get_forwarding_rule(Bundle* b)
00782 {
00783
00784 if (b->dest_.scheme_str() != "tca") return FWD_UDR_ALWAYS;
00785
00786 TcaEndpointID dest(b->dest_);
00787
00788 if (dest.ssp() == "//registry")
00789 {
00790
00791
00792 if (b->source_.str() == admin_app_.str()) return FWD_UDR_EXCLUSIVELY;
00793 else return FWD_NEVER;
00794 }
00795
00796 else if (dest.app() == "admin.coa")
00797 {
00798
00799
00800
00801 return FWD_UDR_NEVER;
00802 }
00803
00804 else if (dest.ssp().substr(0,11) == "//anonymous")
00805 {
00806
00807
00808
00809
00810 if (is_local_source(b)) return FWD_UDR_NEVER;
00811 else return FWD_NEVER;
00812 }
00813
00814 else if (dest.ssp() == "//localhost/bundlelayer")
00815 {
00816
00817 return FWD_NEVER;
00818 }
00819
00820
00821
00822 else
00823 {
00824 if (dest.host() == admin_app_.host())
00825 {
00826
00827
00828 return FWD_NEVER;
00829 }
00830 else
00831 {
00832
00833
00834 return FWD_UDR_IFNECESSARY;
00835 }
00836 }
00837 }
00838
00839
00840
00841
00842
00843
00844 Link*
00845 TcaRouter::create_link(const std::string& link_addr)
00846 {
00847
00848
00849
00850
00851
00852 EndpointID link_eid(link_addr);
00853 std::string clayer_name = link_eid.scheme_str();
00854 const std::string& ssp = link_eid.ssp();
00855 std::string host = ssp.substr(2, ssp.length());
00856
00857 ContactManager* p_man = BundleDaemon::instance()->contactmgr();
00858
00859
00860 Link* p_link = p_man->find_link(host.c_str());
00861 if (p_link != NULL) return p_link;
00862
00863 ConvergenceLayer* cl = ConvergenceLayer::find_clayer(clayer_name.c_str());
00864 if (!cl) {
00865 log_err("TcaRouter: create_link failed: invalid convergence layer"
00866 " '%s'", clayer_name.c_str());
00867 return NULL;
00868 }
00869
00870 p_link = Link::create_link(host, Link::ONDEMAND, cl, host.c_str(), 0, NULL);
00871 if (!p_link) return NULL;
00872
00873
00874
00875 BundleDaemon::instance()->contactmgr()->add_link(p_link);
00876 return p_link;
00877
00878 }
00879
00880
00881 RouteEntry*
00882 TcaRouter::create_route(const std::string& pattern, Link* p_link)
00883 {
00884
00885 log_debug("TcaRouter::create_route: pattern=%s, p_link=%d",
00886 pattern.c_str(), int(p_link));
00887
00888 RouteEntry* p_entry = new RouteEntry(pattern, p_link);
00889 p_entry->action_ = ForwardingInfo::COPY_ACTION;
00890
00891 route_table_->add_entry(p_entry);
00892
00893 return p_entry;
00894 }
00895
00896
00897 bool
00898 TcaRouter::create_route(const std::string& pattern,
00899 const std::string& link_addr)
00900 {
00901
00902 Link* p_link = create_link(link_addr);
00903 if (!p_link)
00904 {
00905 log_err("TcaRouter::create_route: create_link failed");
00906 return false;
00907 }
00908
00909
00910 if (!create_route(pattern, p_link))
00911 {
00912 log_err("TcaRouter::create_route: create_route failed");
00913 return false;
00914 }
00915
00916 return true;
00917 }
00918
00919
00920 bool
00921 TcaRouter::post_bundle(const EndpointID& src, const EndpointID& dest,
00922 const std::string& payload)
00923 {
00924
00925 log_debug("TcaRouter::post_bundle: [%s] -> [%s] : '%s'\n",
00926 src.c_str(), dest.c_str(), payload.c_str());
00927
00928
00929 Bundle* b = new Bundle();
00930
00931
00932 if (src.length() == 0)
00933 b->source_ = EndpointID("tca://localhost/bundlelayer");
00934 else
00935 b->source_ = src;
00936
00937 b->dest_ = dest;
00938 b->custodian_ = BundleDaemon::instance()->local_eid();
00939 b->replyto_ = BundleDaemon::instance()->local_eid();
00940
00941 b->payload_.set_data(payload);
00942
00943
00944
00945 b->expiration_ = 3600;
00946
00947
00948
00949
00950 BundleReceivedEvent* p_event = new BundleReceivedEvent(b, EVENTSRC_ADMIN);
00951 BundleDaemon::instance()->post(p_event);
00952
00953 return true;
00954 }
00955
00956
00957
00958 bool
00959 TcaRouter::push_wrapped_bundle(const std::string& code,
00960 const EndpointID& src,
00961 const EndpointID& dest,
00962 const std::string& bsp)
00963 {
00964 std::string payload = code;
00965 payload += ":";
00966 payload += src.str();
00967 payload += "\t";
00968 payload += dest.str();
00969 payload += "\t";
00970 payload += bsp;
00971 return post_bundle(BL, admin_app_, payload);
00972 }
00973
00974
00975
00976
00977 }