00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017 #ifndef _PROPHET_TLV_CREATOR_H_
00018 #define _PROPHET_TLV_CREATOR_H_
00019
00020 #include "Table.h"
00021 #include "BundleCore.h"
00022 #include "BundleList.h"
00023 #include "Dictionary.h"
00024 #include "RIBDTLV.h"
00025 #include "RIBTLV.h"
00026 #include "OfferTLV.h"
00027 #include "BundleTLVEntryList.h"
00028 #include "BundleOffer.h"
00029 #include "Oracle.h"
00030 #include <string>
00031
00032 namespace prophet
00033 {
00034
00035 struct TLVCreator
00036 {
00037 static RIBDTLV* ribd(BundleCore* core,
00038 const Table* nodes,
00039 const std::string& sender,
00040 const std::string& receiver)
00041 {
00042
00043 if (core == NULL || nodes == NULL) return NULL;
00044
00045 Dictionary ribd(sender,receiver);
00046 for (Table::const_iterator i = nodes->begin(); i != nodes->end(); i++)
00047 {
00048
00049 std::string dest = i->first;
00050 std::string eid = core->get_route(dest);
00051
00052 if (ribd.insert(eid) == Dictionary::INVALID_SID &&
00053 ribd.find(eid) == Dictionary::INVALID_SID) return NULL;
00054 }
00055
00056 ribd.dump(core,__FILE__,__LINE__);
00057 return new RIBDTLV(ribd);
00058 }
00059
00060 static RIBTLV* rib(Oracle* oracle,
00061 const Dictionary& ribd,
00062 bool relay_node,
00063 bool accept_custody,
00064 bool internet_gw = false)
00065 {
00066
00067 if (oracle == NULL) return NULL;
00068
00069 const Table* nodes = oracle->nodes();
00070 std::string sender = ribd.find(0);
00071 std::string receiver = ribd.find(1);
00072
00073 RIBNodeList list;
00074 for (Table::const_iterator i = nodes->begin(); i != nodes->end(); i++)
00075 {
00076 const std::string eid = i->first;
00077 if (eid == sender || eid == receiver) continue;
00078 const Node* n = i->second;
00079 u_int16_t sid = ribd.find(eid);
00080 if (sid == Dictionary::INVALID_SID)
00081 return NULL;
00082 oracle->core()->print_log("rib",BundleCore::LOG_DEBUG,
00083 "%s (%u) -> %.2f",eid.c_str(),sid,n->p_value());
00084 list.push_back(new RIBNode(n,sid));
00085 }
00086
00087 ribd.dump(oracle->core(),__FILE__,__LINE__);
00088 return new RIBTLV(list,relay_node,accept_custody,internet_gw);
00089 }
00090
00091 static OfferTLV* offer(Oracle* oracle,
00092 const Link* nexthop,
00093 const Dictionary& ribd,
00094 const Table& remote)
00095 {
00096
00097 if (oracle == NULL) return NULL;
00098
00099
00100 FwdStrategyComp* comp = FwdStrategy::strategy(
00101 oracle->params()->fs(),
00102 oracle->nodes(),
00103 &remote);
00104
00105
00106 Decider* d = Decider::decider(
00107 oracle->params()->fs(),
00108 nexthop,
00109 oracle->core(),
00110 oracle->nodes(),
00111 &remote,
00112 oracle->stats(),
00113 oracle->params()->max_forward(),
00114 oracle->params()->relay_node());
00115
00116
00117 BundleOffer offer(oracle->core(),oracle->core()->bundles(),comp,d);
00118
00119
00120
00121
00122 PointerList<Ack> acklist;
00123 AckList acks;
00124 AckList* link_acks = const_cast<Link*>(nexthop)->acks();
00125
00126 oracle->acks()->clone(acklist);
00127 for(PointerList<Ack>::iterator i = acklist.begin();
00128 i != acklist.end(); i++)
00129 {
00130
00131 if (link_acks->insert(*i))
00132 acks.insert(*i);
00133 }
00134
00135 BundleOfferList list = offer.get_bundle_offer(ribd,&acks);
00136
00137 if (list.empty())
00138 oracle->core()->print_log("offer",BundleCore::LOG_DEBUG,
00139 "empty bundle offer");
00140 else
00141 {
00142 for (BundleOfferList::const_iterator i = list.begin();
00143 i != list.end(); i++)
00144 {
00145 oracle->core()->print_log("offer",BundleCore::LOG_DEBUG,
00146 "%u %u %u %s%s%s",
00147 (*i)->creation_ts(),
00148 (*i)->seqno(),
00149 (*i)->sid(),
00150 (*i)->custody() ? "C" : "-",
00151 (*i)->accept() ? "A" : "-",
00152 (*i)->ack() ? "K" : "-");
00153 }
00154 }
00155
00156 return new OfferTLV(list);
00157 }
00158
00159 static ResponseTLV* response(Oracle* oracle,
00160 const BundleOfferList& offers,
00161 BundleResponseList& list,
00162 const Dictionary& ribd)
00163 {
00164
00165 if (oracle == NULL) return NULL;
00166
00167 ribd.dump(oracle->core(),__FILE__,__LINE__);
00168
00169 for (BundleOfferList::const_iterator i = offers.begin();
00170 i != offers.end(); i++)
00171 {
00172
00173 u_int32_t cts = (*i)->creation_ts();
00174 u_int32_t seq = (*i)->seqno();
00175 u_int16_t sid = (*i)->sid();
00176 std::string eid = ribd.find(sid);
00177
00178
00179 const Bundle* b = oracle->core()->find(
00180 oracle->core()->bundles(),eid,cts,seq);
00181 if ((*i)->ack())
00182 {
00183 oracle->core()->print_log("response",BundleCore::LOG_DEBUG,
00184 "ACK %s %u:%u",eid.c_str(),cts,seq);
00185
00186 if (b != NULL)
00187 oracle->ack(b);
00188 else
00189 oracle->acks()->insert(eid,cts,seq);
00190
00191
00192
00193
00194 }
00195 else
00196
00197
00198 if (b == NULL)
00199 {
00200
00201 if (oracle->acks()->is_ackd(eid,cts,seq))
00202 {
00203 oracle->core()->print_log("response",BundleCore::LOG_DEBUG,
00204 "not requesting ACK'd bundle: %s %u %u",
00205 eid.c_str(),cts,seq);
00206 continue;
00207 }
00208
00209
00210
00211 bool custody = (*i)->custody() &&
00212 oracle->core()->custody_accepted();
00213 if (list.add_response(cts,seq,sid,custody))
00214 {
00215 const BundleResponseEntry* bre = list.back();
00216 oracle->core()->print_log("response",BundleCore::LOG_DEBUG,
00217 "%s (%u) %u %u",eid.c_str(),bre->sid(),
00218 bre->creation_ts(),bre->seqno());
00219 }
00220 }
00221 }
00222
00223 return new ResponseTLV(list);
00224 }
00225
00226 };
00227
00228 };
00229
00230 #endif // _PROPHET_TLV_CREATOR_H_