00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017 #ifdef HAVE_CONFIG_H
00018 # include <dtn-config.h>
00019 #endif
00020
00021 #include <oasys/util/Options.h>
00022 #include <oasys/util/StringBuffer.h>
00023 #include "Announce.h"
00024 #include "BluetoothDiscovery.h"
00025 #include "BonjourDiscovery.h"
00026 #include "Discovery.h"
00027 #include "IPDiscovery.h"
00028 #include "contacts/ContactManager.h"
00029 #include "bundling/BundleDaemon.h"
00030
00031 namespace dtn {
00032
00033
00034 Discovery::Discovery(const std::string& name,
00035 const std::string& af)
00036 : oasys::Logger("Discovery","/dtn/discovery/%s",af.c_str()),
00037 name_(name), af_(af)
00038 {
00039 }
00040
00041
00042 Discovery*
00043 Discovery::create_discovery(const std::string& name,
00044 const std::string& af,
00045 int argc, const char* argv[],
00046 const char** error)
00047 {
00048 Discovery* disc = NULL;
00049 if (af == "ip")
00050 {
00051 disc = new IPDiscovery(name);
00052 }
00053 #ifdef OASYS_BONJOUR_ENABLED
00054 else if (af == "bonjour")
00055 {
00056 disc = new BonjourDiscovery(name);
00057 }
00058 #endif
00059 #ifdef OASYS_BLUETOOTH_ENABLED
00060 else if (af == "bt")
00061 {
00062 disc = new BluetoothDiscovery(name);
00063 }
00064 #endif
00065 else
00066 {
00067
00068 *error = "unknown address family";
00069 return NULL;
00070 }
00071
00072 if (! disc->configure(argc,argv))
00073 {
00074 delete disc;
00075 return NULL;
00076 }
00077
00078 return disc;
00079 }
00080
00081
00082 Discovery::~Discovery()
00083 {
00084 for (iterator i = list_.begin(); i != list_.end(); i++)
00085 {
00086 delete (*i);
00087 }
00088 }
00089
00090
00091 void
00092 Discovery::dump(oasys::StringBuffer* buf)
00093 {
00094 buf->appendf("%s af %s: %zu announce %s\n",
00095 name_.c_str(),af_.c_str(),list_.size(),to_addr_.c_str());
00096 for (iterator i = list_.begin(); i != list_.end(); i++)
00097 {
00098 buf->appendf("\tannounce %s type %s advertising %s every %d sec\n",
00099 (*i)->name().c_str(),
00100 (*i)->type().c_str(),
00101 (*i)->local_addr().c_str(),
00102 (*i)->interval()/1000);
00103 }
00104 }
00105
00106
00107 bool
00108 Discovery::announce(const char* name, int argc, const char* argv[])
00109 {
00110 iterator iter;
00111 if (find(name,&iter))
00112 {
00113 log_err("discovery for %s already exists",name);
00114 return false;
00115 }
00116
00117 if (argc < 1)
00118 {
00119 log_err("cl type not specified");
00120 return false;
00121 }
00122
00123 const char* cltype = argv[0];
00124 ConvergenceLayer* cl = ConvergenceLayer::find_clayer(cltype);
00125 if (cl == NULL)
00126 {
00127 log_err("invalid convergence layer type (%s)",cltype);
00128 return false;
00129 }
00130
00131 Announce* announce = Announce::create_announce(name,cl,argc,argv);
00132 if (announce == NULL)
00133 {
00134 log_err("no announce implemented for %s convergence layer",cltype);
00135 return false;
00136 }
00137
00138 list_.push_back(announce);
00139
00140 handle_announce();
00141
00142 return true;
00143 }
00144
00145
00146 bool
00147 Discovery::remove(const char* name)
00148 {
00149 iterator iter;
00150
00151 if (! find(name,&iter))
00152 {
00153 log_err("error removing announce %s: no such object",name);
00154 return false;
00155 }
00156
00157 Announce *announce = *iter;
00158 list_.erase(iter);
00159 delete announce;
00160 return true;
00161 }
00162
00163
00164 bool
00165 Discovery::find(const char* name, Discovery::iterator* iter)
00166 {
00167 Announce* announce;
00168 for (*iter = list_.begin(); *iter != list_.end(); (*iter)++)
00169 {
00170 announce = **iter;
00171 if (announce->name() == name)
00172 {
00173 return true;
00174 }
00175 }
00176 return false;
00177 }
00178
00179
00180 void
00181 Discovery::handle_neighbor_discovered(const std::string& cl_type,
00182 const std::string& cl_addr,
00183 const EndpointID& remote_eid)
00184 {
00185 ContactManager* cm = BundleDaemon::instance()->contactmgr();
00186
00187 ConvergenceLayer* cl = ConvergenceLayer::find_clayer(cl_type.c_str());
00188 if (cl == NULL) {
00189 log_err("handle_neighbor_discovered: "
00190 "unknown convergence layer type '%s'", cl_type.c_str());
00191 return;
00192 }
00193
00194
00195 LinkRef link("Announce::handle_neighbor_discovered");
00196 link = cm->find_link_to(cl, "", remote_eid);
00197
00198 if (link == NULL) {
00199 link = cm->new_opportunistic_link(cl, cl_addr, remote_eid);
00200 if (link == NULL) {
00201 log_debug("Discovery::handle_neighbor_discovered: "
00202 "failed to create opportunistic link");
00203 return;
00204 }
00205 }
00206
00207 ASSERT(link != NULL);
00208
00209 if (!link->isavailable())
00210 {
00211
00212 BundleDaemon::post(
00213 new LinkStateChangeRequest(link, Link::AVAILABLE,
00214 ContactEvent::DISCOVERY)
00215 );
00216 }
00217 }
00218
00219 }