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 #ifndef __imep_h__
00040 #define __imep_h__
00041
00042 #include <stdarg.h>
00043 #include <sys/types.h>
00044
00045 #include <config.h>
00046 #include <agent.h>
00047 #include <drop-tail.h>
00048 #include <trace.h>
00049
00050 #include "lib/bsd-list.h"
00051 #include <rtproto/rtproto.h>
00052 #include <imep/rxmit_queue.h>
00053 #include <imep/dest_queue.h>
00054 #include <imep/imep_stats.h>
00055 #include <imep/imep_spec.h>
00056
00057
00058
00059
00060 #define IMEP_HDR_LEN 512
00061
00062 #define BEACON_HDR_LEN (IP_HDR_LEN + sizeof(struct hdr_imep))
00063
00064 #define HELLO_HDR_LEN (IP_HDR_LEN + sizeof(struct hdr_imep) + \
00065 offsetof(struct imep_hello_block, hb_hello_list[0]) )
00066
00067 #define ACK_HDR_LEN (IP_HDR_LEN + sizeof(struct hdr_imep) + \
00068 offsetof(struct imep_ack_block, ab_ack_list[0] ) )
00069
00070 #define INT32_T(X) *((int32_t*) &(X))
00071 #define U_INT16_T(X) *((u_int16_t*) &(X))
00072 #define U_INT32_T(X) *((u_int32_t*) &(X))
00073
00074
00075
00076
00077 class imepAgent;
00078
00079 enum imepTimerType {
00080 BEACON_TIMER = 0x01,
00081 CONTROL_TIMER = 0x02,
00082 REXMIT_TIMER = 0x03,
00083 INCOMING_TIMER = 0x04
00084 };
00085
00086 class imepTimer : public Handler {
00087 public:
00088 imepTimer(imepAgent* a, imepTimerType t) : busy_(0), agent(a), type_(t) {}
00089 void handle(Event*);
00090 void start(double time);
00091 void cancel();
00092 int busy() { return busy_; }
00093 double timeLeft();
00094 private:
00095 Event intr;
00096 int busy_;
00097 imepAgent *agent;
00098 imepTimerType type_;
00099 };
00100
00101
00102
00103
00104 class imepLink {
00105 friend class imepAgent;
00106 public:
00107 imepLink(nsaddr_t index) : index_(index), last_echo_(-BEACON_PERIOD) {}
00108
00109 nsaddr_t& index() { return index_; }
00110 u_int32_t& status() { return status_;}
00111 u_int8_t& lastSeq() { return last_seq_;}
00112 u_int8_t& lastSeqValid() { return last_seq_;}
00113 double& in_expire() { return in_expire_; }
00114 double& out_expire() { return out_expire_; }
00115 double& lastEcho() { return last_echo_; }
00116
00117 protected:
00118 LIST_ENTRY(imepLink) link;
00119
00120 private:
00121 nsaddr_t index_;
00122 u_int32_t status_;
00123 double in_expire_;
00124 double out_expire_;
00125 double last_echo_;
00126 u_int8_t last_seq_;
00127 bool last_seq_valid;
00128 };
00129
00130
00131
00132
00133 class imepAgent : public Agent {
00134 friend class imepTimer;
00135 public:
00136 imepAgent(nsaddr_t index);
00137
00138 void recv(Packet *p, Handler *h);
00139 int command(int argc, const char*const* argv);
00140
00141
00142
00143
00144 void imepRegister(rtAgent *rt);
00145
00146 void imepGetLinkStatus(nsaddr_t index, u_int32_t& status);
00147 void imepSetLinkInStatus(nsaddr_t index);
00148 void imepSetLinkOutStatus(nsaddr_t index);
00149 void imepSetLinkBiStatus(nsaddr_t index);
00150 void imepSetLinkDownStatus(nsaddr_t index);
00151
00152 void imepPacketUndeliverable(Packet *p);
00153
00154
00155
00156 void imepGetBiLinks(int*& nblist, int& nbcnt);
00157
00158
00159
00160 ImepStat stats;
00161
00162 protected:
00163 void Terminate();
00164
00165
00166
00167 void handlerTimer(imepTimerType t);
00168
00169 private:
00170 imepTimer beaconTimer;
00171 imepTimer controlTimer;
00172 imepTimer rexmitTimer;
00173 imepTimer incomingTimer;
00174
00175 void handlerBeaconTimer(void);
00176 void handlerControlTimer(void);
00177 void handlerReXmitTimer(void);
00178 void handlerIncomingTimer(void);
00179
00180
00181
00182
00183
00184
00185
00186 void recv_incoming(Packet *p);
00187 void recv_outgoing(Packet *p);
00188
00189 void imep_beacon_input(Packet *p);
00190 void imep_ack_input(Packet *p);
00191 void imep_hello_input(Packet *p);
00192 void imep_object_input(Packet *p);
00193 void imep_object_process(Packet *p);
00194 void imep_ack_object(Packet *p);
00195
00196 void imep_input(Packet *p);
00197 void imep_output(Packet *p);
00198
00199 void sendBeacon(void);
00200 void sendHello(nsaddr_t index);
00201 void sendAck(nsaddr_t index, u_int32_t seqno);
00202
00203
00204
00205
00206 imepLink* findLink(nsaddr_t index);
00207
00208 void purgeLink(void);
00209
00210
00211 void purgeReXmitQ(nsaddr_t index);
00212
00213
00214 Packet* findObjectSequence(u_int8_t seqno);
00215
00216
00217 void removeObjectResponse(Packet *p, nsaddr_t index);
00218
00219
00220 struct imep_ack_block* findAckBlock(Packet *p);
00221 struct imep_hello_block* findHelloBlock(Packet *p);
00222 struct imep_object_block* findObjectBlock(Packet *p);
00223 struct imep_response* findResponseList(Packet *p);
00224
00225 void aggregateAckBlock(Packet *p);
00226 void aggregateHelloBlock(Packet *p);
00227 void aggregateObjectBlock(Packet *p);
00228 void createResponseList(Packet *p);
00229 int getResponseListSize();
00230
00231 void scheduleReXmit(Packet *p);
00232 void scheduleIncoming(Packet *p, u_int32_t s);
00233
00234 u_int8_t nextSequence() {
00235 controlSequence++;
00236 return (controlSequence & 0xFF);
00237 }
00238
00239 inline int initialized() {
00240 return recvtarget_ && sendtarget_ && rtagent_ && logtarget_;
00241 }
00242
00243 void imep_dump_header(Packet *p);
00244 public:
00245 void trace(char* fmt, ...);
00246 private:
00247
00248 void log_neighbor_list(void);
00249 char* dumpResponseList(Packet *p);
00250
00251
00252
00253
00254 void toraCreateHeader(Packet *p, char* dst, int length);
00255 void toraExtractHeader(Packet *p, char* dst);
00256 int toraHeaderLength(struct hdr_tora* t);
00257
00258
00259
00260 nsaddr_t ipaddr;
00261
00262
00263 u_int32_t controlSequence;
00264
00265 NsObject *recvtarget_;
00266
00267
00268 NsObject *sendtarget_;
00269
00270
00271 rtAgent *rtagent_;
00272
00273
00274 Trace *logtarget_;
00275
00276
00277
00278
00279 LIST_HEAD(_dummy_imepLinkList,imepLink) imepLinkHead;
00280
00281
00282
00283
00284 PacketQueue ackQueue;
00285 PacketQueue helloQueue;
00286 PacketQueue objectQueue;
00287
00288
00289
00290 ReXmitQ rexmitq;
00291
00292
00293
00294 dstQueue incomingQ;
00295 };
00296
00297 #endif