BluetoothDiscovery.cc

Go to the documentation of this file.
00001 /*
00002  *    Copyright 2006 Baylor University
00003  * 
00004  *    Licensed under the Apache License, Version 2.0 (the "License");
00005  *    you may not use this file except in compliance with the License.
00006  *    You may obtain a copy of the License at
00007  * 
00008  *        http://www.apache.org/licenses/LICENSE-2.0
00009  * 
00010  *    Unless required by applicable law or agreed to in writing, software
00011  *    distributed under the License is distributed on an "AS IS" BASIS,
00012  *    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
00013  *    See the License for the specific language governing permissions and
00014  *    limitations under the License.
00015  */
00016 
00017 #include <config.h>
00018 
00019 #ifdef OASYS_BLUETOOTH_ENABLED
00020 
00021 #include <oasys/util/Random.h>
00022 #include <oasys/bluez/Bluetooth.h>
00023 #include <oasys/bluez/BluetoothSDP.h>
00024 #include <oasys/bluez/BluetoothInquiry.h>
00025 #include <oasys/util/OptParser.h>
00026 #include "bundling/BundleDaemon.h"
00027 
00028 #include "BluetoothAnnounce.h"
00029 #include "BluetoothDiscovery.h"
00030 
00031 namespace dtn {
00032 
00033 void
00034 BluetoothDiscovery::shutdown()
00035 {
00036     shutdown_ = true;
00037     notifier_.notify();
00038 }
00039 
00040 BluetoothDiscovery::BluetoothDiscovery(const std::string& name)
00041     : Discovery(name,"bt"),
00042       oasys::Thread("BluetoothDiscovery"),
00043       notifier_("/dtn/discovery/bt")
00044 {
00045     oasys::Bluetooth::hci_get_bdaddr(&local_addr_);
00046     shutdown_ = false;
00047 }
00048 
00049 bool
00050 BluetoothDiscovery::configure(int argc, const char* argv[])
00051 {
00052     if (oasys::Thread::started())
00053     {
00054         log_warn("reconfiguration of BluetoothDiscovery not supported");
00055         return false;
00056     }
00057 
00058     oasys::OptParser p;
00059     const char* invalid;
00060     p.addopt(new oasys::BdAddrOpt("local_addr",&local_addr_));
00061     if (! p.parse(argc,argv,&invalid))
00062     {
00063         log_err("bad option: %s",invalid);
00064         return false;
00065     }
00066 
00067     local_.assign(bd2str(local_addr_));
00068 
00069     start();
00070     return true;
00071 }
00072 
00073 void
00074 BluetoothDiscovery::run()
00075 {
00076     oasys::BluetoothInquiry inquiry;
00077     while (! shutdown_)
00078     {
00079         u_int interval = INT_MAX;
00080         // grab the minimum interval from registered CL's
00081         for (iterator i = list_.begin(); i != list_.end(); i++)
00082         {
00083             BluetoothAnnounce* announce = dynamic_cast<BluetoothAnnounce*>(*i);
00084             if (announce->interval_remaining() < interval)
00085             {
00086                 interval = announce->interval_remaining();
00087             }
00088         }
00089         // randomize the sleep time:
00090         // the point is that two nodes with zero prior knowledge of each other
00091         // need to be able to discover each other in a reasonably short time.
00092         // if common practice is that all set their poll_interval to 1 or 30
00093         // or x then there's the chance of synchronization or syncopation such
00094         // that discovery doesn't happen.
00095         
00096         if (interval > 0) 
00097         {
00098             u_int sleep_time = oasys::Random::rand(interval);
00099             log_debug("sleep time %d",sleep_time);
00100 
00101             notifier_.wait(NULL,sleep_time);
00102         }
00103 
00104         if (shutdown_) break;
00105 
00106         // initiate Bluetooth inquiry on local Bluetooth chipset
00107         // this call blocks until inquiry is complete (10+ sec)
00108         int nr = inquiry.inquire();
00109 
00110         if (shutdown_) break;
00111 
00112         // Polling instead of beaconing means that the act of polling
00113         // satisfies everyone's interval, so reset them all
00114         for (iterator i = list_.begin(); i != list_.end(); i++)
00115         {
00116             BluetoothAnnounce* announce = dynamic_cast<BluetoothAnnounce*>(*i);
00117             announce->reset_interval();
00118         }
00119 
00120         if (nr < 0) continue; // nobody's around
00121 
00122         // iterate over discovered neighbors
00123         bdaddr_t remote;
00124         while (inquiry.next(remote) != -1)
00125         {
00126 
00127             // query for DTN to remote host's SDP daemon
00128             oasys::BluetoothServiceDiscoveryClient sdpclient;
00129             if (sdpclient.is_dtn_router(remote))
00130             {
00131                 std::string nexthop(bd2str(remote));
00132                 EndpointID eid = sdpclient.remote_eid();
00133                 log_info("discovered DTN peer %s at %s channel %d",eid.c_str(),
00134                          nexthop.c_str(),sdpclient.channel());
00135                 handle_neighbor_discovered("bt",nexthop,eid); 
00136             }
00137 
00138             if (shutdown_) break;
00139         }
00140     }
00141 }
00142 
00143 }  // dtn
00144 
00145 #endif // OASYS_BLUETOOTH_ENABLED

Generated on Sat Sep 8 08:36:15 2007 for DTN Reference Implementation by  doxygen 1.5.3