ProphetEncounter.h

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 #ifndef _DTN_PROPHET_ENCOUNTER_
00018 #define _DTN_PROPHET_ENCOUNTER_
00019 
00020 #include <oasys/debug/Log.h>
00021 #include <oasys/thread/MsgQueue.h>
00022 #include <oasys/util/Time.h>
00023 #include "naming/EndpointID.h"
00024 #include "contacts/Link.h"
00025 #include <sys/types.h> 
00026 
00027 #include "routing/Prophet.h"
00028 #include "routing/ProphetNode.h"
00029 #include "routing/ProphetLists.h"
00030 #include "routing/ProphetTLV.h"
00031 
00032 #include "bundling/BundleList.h"
00033 #include "bundling/BundleActions.h"
00034 
00039 namespace dtn {
00040 
00041 class ProphetOracle {
00042 public:
00043     virtual ~ProphetOracle() {}
00044     virtual ProphetParams*      params() = 0;
00045     virtual ProphetBundleQueue* bundles() = 0;
00046     virtual ProphetTable*       nodes() = 0;
00047     virtual BundleActions*      actions() = 0;
00048     virtual ProphetAckList*     acks() = 0;
00049     virtual ProphetStats*       stats() = 0;
00050 };
00051 
00069 class ProphetEncounter : public oasys::Thread,
00070                          public oasys::Logger
00071 {
00072 public:
00073 
00085     typedef enum {
00086         PEMSG_INVALID = 0,
00087         PEMSG_PROPHET_TLV_RECEIVED,
00088         PEMSG_HELLO_INTERVAL_CHANGED,
00089         PEMSG_NEIGHBOR_GONE,
00090     } pemsg_t;
00091 
00092     const char* pemsg_to_str(pemsg_t type) {
00093         switch(type) {
00094         case PEMSG_INVALID:              return "PEMSG_INVALID";
00095         case PEMSG_PROPHET_TLV_RECEIVED: return "PEMSG_PROPHET_TLV_RECEIVED";
00096         case PEMSG_HELLO_INTERVAL_CHANGED: return "PEMSG_HELLO_INTERVAL_CHANGED";
00097         case PEMSG_NEIGHBOR_GONE:        return "PEMSG_NEIGHBOR_GONE";
00098         default:                         PANIC("bogus pemsg_t");
00099         }
00100     }
00101 
00102     struct PEMsg {
00103         PEMsg()
00104             : type_(PEMSG_INVALID),
00105               tlv_(NULL) {}
00106         PEMsg(pemsg_t type,ProphetTLV* tlv = NULL)
00107             : type_(type), tlv_(tlv) {}
00108 
00109         pemsg_t type_;
00110         ProphetTLV* tlv_;
00111     };
00112 
00117     ProphetEncounter(Link* nexthop,
00118                      ProphetOracle* oracle);
00119 
00120 private:
00124     ProphetEncounter(const ProphetEncounter& pe)
00125     :
00126         oasys::Thread("ProphetEncounter"),
00127         oasys::Logger("ProphetEncounter",pe.logpath_),
00128         cmdqueue_("/dtn/route/prophet/encounter"),
00129         to_be_fwd_("ProphetEncounter to be forwarded") {}
00130 
00131 public:
00132     virtual ~ProphetEncounter();
00133 
00134     typedef enum {
00135         UNDEFINED = 0,
00136         WAIT_NB,    
00137         SYNSENT,    
00138         SYNRCVD,    
00139         ESTAB,      
00140         WAIT_DICT,  
00141         WAIT_RIB,   
00142         OFFER,      
00143         CREATE_DR,  
00144         SEND_DR,    
00145         REQUEST,    
00146         WAIT_INFO   
00147     } prophet_state_t;
00148 
00149     static const char* state_to_str(prophet_state_t st) {
00150         switch(st) {
00151 #define CASE(_state) case _state: return # _state
00152         CASE(WAIT_NB);
00153         CASE(SYNSENT);
00154         CASE(SYNRCVD);
00155         CASE(ESTAB);
00156         CASE(WAIT_DICT);
00157         CASE(WAIT_RIB);
00158         CASE(OFFER);
00159         CASE(CREATE_DR);
00160         CASE(SEND_DR);
00161         CASE(REQUEST);
00162         CASE(WAIT_INFO);
00163 #undef CASE
00164         default:        PANIC("Unknown State");
00165         }
00166     }
00167 
00172     void receive_tlv(ProphetTLV*);
00173 
00178     u_int16_t remote_instance() const { return remote_instance_; }
00179 
00184     u_int16_t local_instance()  const { return local_instance_; }
00185 
00186     const EndpointID& remote_eid() const { return next_hop_->remote_eid(); }
00187 
00188     bool operator< (const ProphetEncounter& p) const;
00189     bool operator< (u_int16_t instance) const;
00190 
00191     Link* next_hop() const {return next_hop_;}
00192 
00204     void reset_link();
00205 
00209     void neighbor_gone();
00210 
00216     void flush_pending() { fwd_to_nexthop(NULL); }
00217 
00218     void dump_state(oasys::StringBuffer* buf);
00219     void handle_bundle_received(Bundle*);
00220     void hello_interval_changed() {
00221         log_notice("hello_interval_changed");
00222         cmdqueue_.push_back(PEMsg(PEMSG_HELLO_INTERVAL_CHANGED));
00223     }
00224 protected:
00225 
00230     void run();
00231 
00239     void update_peer_verifier(u_int16_t instance) {
00240         remote_instance_ = instance;
00241         remote_addr_ = next_hop_->nexthop();
00242     }
00243 
00247     void process_command();
00248 
00252     void handle_prophet_tlv(ProphetTLV* pt);
00253 
00257     bool handle_hello_tlv(HelloTLV* hello,ProphetTLV* pt);
00258 
00262     bool handle_ribd_tlv(RIBDTLV* ribd,ProphetTLV* pt);
00263 
00267     bool handle_rib_tlv(RIBTLV* rib,ProphetTLV* pt);
00268 
00272     bool handle_bundle_tlv(BundleTLV* btlv,ProphetTLV* pt);
00273 
00277     bool handle_bad_protocol(u_int32_t tid);
00278 
00282     void handle_neighbor_gone();
00283 
00287     void handle_poll_timeout();
00288 
00294     void switch_info_role();
00295 
00300     void reset_ribd();
00301 
00305     void handle_hello_interval_changed();
00306 
00310     void send_dictionary();
00311 
00315     void send_bundle_offer();
00316 
00321 
00322     void enqueue_hello(Prophet::hello_hf_t hf,
00323             u_int32_t tid = 0,
00324             Prophet::header_result_t result = Prophet::NoSuccessAck);
00325     void enqueue_ribd(const ProphetDictionary& ribd,
00326             u_int32_t tid = 0,
00327             Prophet::header_result_t result = Prophet::NoSuccessAck);
00328     void enqueue_rib(const RIBTLV::List& nodes,
00329             u_int32_t tid = 0,
00330             Prophet::header_result_t result = Prophet::NoSuccessAck);
00331     void enqueue_bundle_tlv(const BundleOfferList& list,
00332             u_int32_t tid = 0,
00333             Prophet::header_result_t result = Prophet::NoSuccessAck);
00335     
00339     ProphetTLV* outbound_tlv(u_int32_t tid,
00340                              Prophet::header_result_t result);
00341 
00345     bool send_prophet_tlv();
00346 
00350     bool should_fwd(Bundle* bundle);
00351 
00355     void fwd_to_nexthop(Bundle* bundle,bool add_front = false);
00356 
00361 
00362     void set_state(prophet_state_t);
00363     prophet_state_t get_state(const char* where);
00365 
00366     ProphetOracle* oracle_; 
00367     u_int16_t remote_instance_; 
00368     std::string remote_addr_; 
00369     u_int16_t local_instance_; 
00370     u_int32_t tid_; 
00371     u_int32_t timeout_; 
00372     u_int32_t ack_count_; 
00373     Link* next_hop_;  
00374     bool synsender_; 
00375     bool initiator_; 
00376     bool synsent_;  
00377     bool synrcvd_;  
00378     bool estab_;    
00379     bool dictsent_; 
00380     volatile bool neighbor_gone_; 
00381     prophet_state_t state_; 
00382     ProphetDictionary ribd_; 
00383     BundleOfferList offers_; 
00384     BundleOfferList requests_; 
00385     oasys::MsgQueue<PEMsg> cmdqueue_; 
00386     ProphetTable remote_nodes_; 
00387     BundleList to_be_fwd_; 
00388     Prophet::header_result_t result_; 
00389     oasys::Time data_sent_; 
00390     oasys::Time data_rcvd_; 
00391     ProphetTLV* outbound_tlv_; 
00392     oasys::SpinLock* state_lock_; 
00393     oasys::SpinLock* otlv_lock_; 
00394 }; // ProphetEncounter
00395 
00396 }; // dtn
00397 
00398 #endif // _DTN_PROPHET_ENCOUNTER_

Generated on Sat Sep 8 08:43:32 2007 for DTN Reference Implementation by  doxygen 1.5.3