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 #ifndef __PANA_RETRANSMISSION_H__
00035 #define __PANA_RETRANSMISSION_H__
00036
00037 #include <iostream>
00038 #include <list>
00039 #include "ace/OS.h"
00040 #include "pana_config_manager.h"
00041
00042
00043
00044
00045
00046
00047
00048
00049
00050
00051
00052
00053
00054
00055
00056
00057
00058
00059
00060
00061
00062
00063
00064
00065
00066
00067
00068
00069
00070
00071 class PANA_RtQueue;
00072 class PANA_RtQueueData
00073 {
00074 friend class PANA_RtQueue;
00075 public:
00076 PANA_RtQueueData() : m_Timeout(0),
00077 m_Duration(0),
00078 m_Count(0) { }
00079 virtual ~PANA_RtQueueData() { }
00080 int Timeout() { return m_Timeout; }
00081 virtual PANA_RtQueueData *clone() = 0;
00082 virtual PANA_RtQueueData &operator=(PANA_RtQueueData &d) {
00083 m_Timeout = d.m_Timeout;
00084 m_Duration = d.m_Duration;
00085 m_Count = d.m_Count;
00086 return *this;
00087 }
00088
00089 protected:
00090 unsigned int m_Timeout;
00091 unsigned int m_Duration;
00092 unsigned int m_Count;
00093 };
00094
00095 class PANA_RtQueueNullData : public PANA_RtQueueData
00096 {
00097 public:
00098 PANA_RtQueueData *clone() {
00099 return (new PANA_RtQueueNullData(*this));
00100 }
00101 };
00102
00103 class PANA_RtQueueMsgBlockData : public PANA_RtQueueData
00104 {
00105 public:
00106 PANA_RtQueueMsgBlockData(AAAMessageBlock *blk) :
00107 m_MsgBlock(NULL) {
00108 if (blk) {
00109 m_MsgBlock = AAAMessageBlock::Acquire(ACE_UINT32(blk->size()));
00110 m_MsgBlock->copy(blk->base(), blk->size());
00111 }
00112 }
00113 virtual ~PANA_RtQueueMsgBlockData() {
00114 if (m_MsgBlock) {
00115 m_MsgBlock->Release();
00116 }
00117 }
00118 AAAMessageBlock *MsgBlock() { return m_MsgBlock; }
00119 PANA_RtQueueData *clone() {
00120 PANA_RtQueueData *c = new PANA_RtQueueMsgBlockData(m_MsgBlock);
00121 *c = *this;
00122
00123 return (c);
00124 }
00125 protected:
00126 AAAMessageBlock *m_MsgBlock;
00127 };
00128
00129 class PANA_RtQueueMsgBlockDataWithRcode : public PANA_RtQueueMsgBlockData
00130 {
00131 public:
00132 PANA_RtQueueMsgBlockDataWithRcode(AAAMessageBlock *blk,
00133 ACE_UINT32 rCode) :
00134 PANA_RtQueueMsgBlockData(blk), m_Rcode(rCode) { }
00135 virtual ~PANA_RtQueueMsgBlockDataWithRcode() { }
00136 ACE_UINT32 RCode() { return m_Rcode; }
00137 PANA_RtQueueData *clone() {
00138 PANA_RtQueueData *c = new PANA_RtQueueMsgBlockDataWithRcode
00139 (m_MsgBlock, m_Rcode);
00140 *c = *this;
00141 return (c);
00142 }
00143 protected:
00144 ACE_UINT32 m_Rcode;
00145 };
00146
00147 typedef std::list<PANA_RtQueueData*> PANA_RtQueueDataList;
00148
00149 class PANA_RtQueue : public PANA_RtQueueDataList
00150 {
00151 public:
00152 PANA_RtQueue(int Qsize = 1) : m_MaxQueueCount(Qsize) { }
00153 bool Schedule(PANA_RtQueueData &d) {
00154 if (size() >= m_MaxQueueCount) {
00155 return (false);
00156 }
00157
00158
00159
00160
00161
00162 unsigned int newRt = PANA_CONFIG_GENERAL().rt_.irt_ +
00163 int(RAND()*float(PANA_CONFIG_GENERAL().rt_.irt_));
00164
00165
00166
00167
00168
00169
00170
00171
00172
00173
00174 if (newRt > PANA_CONFIG_GENERAL().rt_.mrt_) {
00175 newRt = PANA_CONFIG_GENERAL().rt_.mrt_ +
00176 int(RAND()*float(PANA_CONFIG_GENERAL().rt_.mrt_));
00177 return false;
00178 }
00179
00180 d.m_Timeout = newRt;
00181 d.m_Duration = newRt;
00182 d.m_Count = 1;
00183 push_back(d.clone());
00184 return (true);
00185 }
00186 bool ReSchedule(PANA_RtQueueData *&d) {
00187 if (empty()) {
00188 return (false);
00189 }
00190
00191 PANA_RtQueueData *data = front();
00192 pop_front();
00193
00194
00195
00196
00197
00198
00199
00200 unsigned int newRt = 2*data->m_Timeout +
00201 int(RAND()*float(data->m_Timeout));
00202
00203
00204
00205
00206
00207
00208
00209
00210
00211
00212 if (newRt > PANA_CONFIG_GENERAL().rt_.mrt_) {
00213 newRt = PANA_CONFIG_GENERAL().rt_.mrt_ +
00214 int(RAND()*float(PANA_CONFIG_GENERAL().rt_.mrt_));
00215 }
00216
00217
00218
00219
00220
00221
00222
00223
00224
00225
00226
00227
00228
00229
00230
00231
00232
00233
00234
00235
00236 if ((PANA_CONFIG_GENERAL().rt_.mrc_ > 0) &&
00237 (data->m_Count >= PANA_CONFIG_GENERAL().rt_.mrc_)) {
00238 delete data;
00239 return (false);
00240 }
00241
00242 if ((PANA_CONFIG_GENERAL().rt_.mrd_ > 0) &&
00243 ((data->m_Duration + newRt) > PANA_CONFIG_GENERAL().rt_.mrd_)) {
00244 delete data;
00245 return (false);
00246 }
00247
00248 data->m_Timeout = newRt;
00249 data->m_Duration += newRt;
00250 data->m_Count ++;
00251 push_back(data);
00252 d = data;
00253 return (true);
00254 }
00255 void ClearFront() {
00256 if (! empty()) {
00257 PANA_RtQueueData *data = front();
00258 pop_front();
00259 delete data;
00260 }
00261 }
00262 void Clear() {
00263 while (! empty()) {
00264 ClearFront();
00265 }
00266 }
00267
00268 private:
00269 inline float RAND() {
00270
00271
00272
00273
00274
00275
00276
00277
00278
00279
00280
00281
00282 return float(-0.1 + 0.2*float(ACE_OS::rand()/(RAND_MAX+1.0)));
00283 }
00284
00285 unsigned int m_MaxQueueCount;
00286 };
00287
00288 #endif // __PANA_RETRANSMISSION_H__