|
1 /* -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */ |
|
2 /* |
|
3 * Copyright (c) 2004,2005,2006 INRIA |
|
4 * |
|
5 * This program is free software; you can redistribute it and/or modify |
|
6 * it under the terms of the GNU General Public License version 2 as |
|
7 * published by the Free Software Foundation; |
|
8 * |
|
9 * This program is distributed in the hope that it will be useful, |
|
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of |
|
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
|
12 * GNU General Public License for more details. |
|
13 * |
|
14 * You should have received a copy of the GNU General Public License |
|
15 * along with this program; if not, write to the Free Software |
|
16 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA |
|
17 * |
|
18 * Author: Federico Maguolo <maguolof@dei.unipd.it> |
|
19 */ |
|
20 |
|
21 #include "cara-wifi-manager.h" |
|
22 #include "ns3/assert.h" |
|
23 #include "ns3/log.h" |
|
24 #include "ns3/double.h" |
|
25 #include "ns3/uinteger.h" |
|
26 #include "ns3/simulator.h" |
|
27 |
|
28 NS_LOG_COMPONENT_DEFINE ("Cara"); |
|
29 |
|
30 |
|
31 namespace ns3 { |
|
32 |
|
33 struct CaraWifiRemoteStation : public WifiRemoteStation |
|
34 { |
|
35 uint32_t m_timer; |
|
36 uint32_t m_success; |
|
37 uint32_t m_failed; |
|
38 uint32_t m_rate; |
|
39 }; |
|
40 |
|
41 NS_OBJECT_ENSURE_REGISTERED(CaraWifiManager); |
|
42 |
|
43 TypeId |
|
44 CaraWifiManager::GetTypeId (void) |
|
45 { |
|
46 static TypeId tid = TypeId ("ns3::CaraWifiManager") |
|
47 .SetParent<WifiRemoteStationManager> () |
|
48 .AddConstructor<CaraWifiManager> () |
|
49 .AddAttribute ("ProbeThreshold", |
|
50 "The number of consecutive transmissions failure to activate the RTS probe.", |
|
51 UintegerValue (1), |
|
52 MakeUintegerAccessor (&CaraWifiManager::m_probeThreshold), |
|
53 MakeUintegerChecker<uint32_t> ()) |
|
54 .AddAttribute ("FailureThreshold", |
|
55 "The number of consecutive transmissions failure to decrease the rate.", |
|
56 UintegerValue (2), |
|
57 MakeUintegerAccessor (&CaraWifiManager::m_failureThreshold), |
|
58 MakeUintegerChecker<uint32_t> ()) |
|
59 .AddAttribute ("SuccessThreshold", |
|
60 "The minimum number of sucessfull transmissions to try a new rate.", |
|
61 UintegerValue (10), |
|
62 MakeUintegerAccessor (&CaraWifiManager::m_successThreshold), |
|
63 MakeUintegerChecker<uint32_t> ()) |
|
64 .AddAttribute ("Timeout", |
|
65 "The 'timer' in the CARA algorithm", |
|
66 UintegerValue (15), |
|
67 MakeUintegerAccessor (&CaraWifiManager::m_timerTimeout), |
|
68 MakeUintegerChecker<uint32_t> ()) |
|
69 ; |
|
70 return tid; |
|
71 } |
|
72 |
|
73 CaraWifiManager::CaraWifiManager () |
|
74 : WifiRemoteStationManager () |
|
75 {} |
|
76 CaraWifiManager::~CaraWifiManager () |
|
77 {} |
|
78 |
|
79 WifiRemoteStation * |
|
80 CaraWifiManager::DoCreateStation (void) const |
|
81 { |
|
82 CaraWifiRemoteStation *station = new CaraWifiRemoteStation (); |
|
83 station->m_rate = 0; |
|
84 station->m_success = 0; |
|
85 station->m_failed = 0; |
|
86 station->m_timer = 0; |
|
87 return station; |
|
88 } |
|
89 |
|
90 void |
|
91 CaraWifiManager::DoReportRtsFailed (WifiRemoteStation *st) |
|
92 {} |
|
93 |
|
94 void |
|
95 CaraWifiManager::DoReportDataFailed (WifiRemoteStation *st) |
|
96 { |
|
97 CaraWifiRemoteStation *station = (CaraWifiRemoteStation *) st; |
|
98 NS_LOG_FUNCTION (station); |
|
99 station->m_timer++; |
|
100 station->m_failed++; |
|
101 station->m_success = 0; |
|
102 if (station->m_failed >= m_failureThreshold) |
|
103 { |
|
104 NS_LOG_DEBUG ("self="<<station<<" dec rate"); |
|
105 if (station->m_rate != 0) |
|
106 { |
|
107 station->m_rate--; |
|
108 } |
|
109 station->m_failed = 0; |
|
110 station->m_timer = 0; |
|
111 } |
|
112 } |
|
113 void |
|
114 CaraWifiManager::DoReportRxOk (WifiRemoteStation *st, |
|
115 double rxSnr, WifiMode txMode) |
|
116 {} |
|
117 void |
|
118 CaraWifiManager::DoReportRtsOk (WifiRemoteStation *st, |
|
119 double ctsSnr, WifiMode ctsMode, double rtsSnr) |
|
120 { |
|
121 NS_LOG_DEBUG ("self="<<st<<" rts ok"); |
|
122 } |
|
123 void |
|
124 CaraWifiManager::DoReportDataOk (WifiRemoteStation *st, |
|
125 double ackSnr, WifiMode ackMode, double dataSnr) |
|
126 { |
|
127 CaraWifiRemoteStation *station = (CaraWifiRemoteStation *) st; |
|
128 station->m_timer++; |
|
129 station->m_success++; |
|
130 station->m_failed = 0; |
|
131 NS_LOG_DEBUG ("self="<<station<<" data ok success="<<station->m_success<<", timer="<<station->m_timer); |
|
132 if ((station->m_success == m_successThreshold || |
|
133 station->m_timer >= m_timerTimeout)) |
|
134 { |
|
135 if (station->m_rate < GetNSupported (station) - 1) |
|
136 { |
|
137 station->m_rate++; |
|
138 } |
|
139 NS_LOG_DEBUG ("self="<<station<<" inc rate=" << station->m_rate); |
|
140 station->m_timer = 0; |
|
141 station->m_success = 0; |
|
142 } |
|
143 } |
|
144 void |
|
145 CaraWifiManager::DoReportFinalRtsFailed (WifiRemoteStation *st) |
|
146 {} |
|
147 void |
|
148 CaraWifiManager::DoReportFinalDataFailed (WifiRemoteStation *st) |
|
149 {} |
|
150 |
|
151 WifiMode |
|
152 CaraWifiManager::DoGetDataMode (WifiRemoteStation *st, |
|
153 uint32_t size) |
|
154 { |
|
155 CaraWifiRemoteStation *station = (CaraWifiRemoteStation *) st; |
|
156 return GetSupported (station, station->m_rate); |
|
157 } |
|
158 WifiMode |
|
159 CaraWifiManager::DoGetRtsMode (WifiRemoteStation *st) |
|
160 { |
|
161 // XXX: we could/should implement the Arf algorithm for |
|
162 // RTS only by picking a single rate within the BasicRateSet. |
|
163 return GetSupported (st, 0); |
|
164 } |
|
165 |
|
166 bool |
|
167 CaraWifiManager::DoNeedRts (WifiRemoteStation *st, |
|
168 Ptr<const Packet> packet, bool normally) |
|
169 { |
|
170 CaraWifiRemoteStation *station = (CaraWifiRemoteStation *) st; |
|
171 return normally || station->m_failed >= m_probeThreshold; |
|
172 } |
|
173 |
|
174 bool |
|
175 CaraWifiManager::IsLowLatency (void) const |
|
176 { |
|
177 return true; |
|
178 } |
|
179 |
|
180 } // namespace ns3 |