|
1 |
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */ |
2 |
/* |
3 |
* This program is free software; you can redistribute it and/or modify |
4 |
* it under the terms of the GNU General Public License version 2 as |
5 |
* published by the Free Software Foundation; |
6 |
* |
7 |
* This program is distributed in the hope that it will be useful, |
8 |
* but WITHOUT ANY WARRANTY; without even the implied warranty of |
9 |
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
10 |
* GNU General Public License for more details. |
11 |
* |
12 |
* You should have received a copy of the GNU General Public License |
13 |
* along with this program; if not, write to the Free Software |
14 |
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA |
15 |
* |
16 |
* Author: Junling Bu <linlinjavaer@gmail.com> |
17 |
*/ |
18 |
|
19 |
#ifndef WSMP_SOCKET_H |
20 |
#define WSMP_SOCKET_H |
21 |
|
22 |
#include "ns3/node.h" |
23 |
|
24 |
namespace ns3 { |
25 |
|
26 |
#define PSID_LENGTH_MASK_ONE 0x7f |
27 |
#define PSID_LENGTH_MASK_TWO 0xbf |
28 |
#define PSID_LENGTH_MASK_THREE 0xdf |
29 |
#define PSID_LENGTH_MASK_FOUR 0xef |
30 |
|
31 |
/** |
32 |
* The range of PSID is |
33 |
* 1. 0x00 ~ 0x7f |
34 |
* 2. 0x8000 ~ 0xbfff |
35 |
* 3. 0xc00000 ~ 0xdfffff |
36 |
* 4. 0xe0000000 ~ 0xefffffff |
37 |
* Other number will be taken as invalid. |
38 |
* See IEEE 1609.3 section 8.1.3 and Annex H "PSID examples" |
39 |
* |
40 |
* Usage: |
41 |
* Psid validPsid1 = Psid(0x01); |
42 |
* Psid validPsid2 = Psid(0x80, 0x01); |
43 |
* Psid validPsid3 = Psid(0xc0, 0x00, 0x01); |
44 |
* Psid validPsid4 = Psid(0xef, 0x00, 0x00, 0x01); |
45 |
* Psid invalidPsid1 = Psid(); // this is an invalid PSID which cannot be used for transmit. |
46 |
* Psid invalidPsid2 = Psid(0x81); // this is an invalid PSID which cannot be used for transmit. |
47 |
* |
48 |
* A special "null" Psid is invalid, but here is used internally by class WsmpProtocol. |
49 |
* Users should not use the "null" Psid for transmit. |
50 |
*/ |
51 |
|
52 |
class Psid { |
53 |
public: |
54 |
Psid (); |
55 |
Psid (uint8_t data0); |
56 |
Psid (uint8_t data0, uint8_t data1); |
57 |
Psid (uint8_t data0, uint8_t data1, uint8_t data2); |
58 |
Psid (uint8_t data0, uint8_t data1, uint8_t data2, uint8_t data3); |
59 |
Psid (uint8_t * data, uint8_t length); |
60 |
|
61 |
bool IsValid (void) const; |
62 |
|
63 |
bool IsNull (void) const; |
64 |
|
65 |
bool IsEqualTo (const Psid & psid) const; |
66 |
|
67 |
const uint8_t * GetData (void) const; |
68 |
uint8_t GetLength (void) const; |
69 |
|
70 |
private: |
71 |
void Assert (void); |
72 |
|
73 |
friend std::ostream& operator<< (std::ostream& os, const Psid & psid); |
74 |
friend bool operator == (const Psid &a, const Psid &b); |
75 |
friend bool operator != (const Psid &a, const Psid &b); |
76 |
|
77 |
uint8_t m_data[4]; |
78 |
uint8_t m_length; |
79 |
}; |
80 |
|
81 |
std::ostream& operator<< (std::ostream& os, const Psid & psid); |
82 |
bool operator == (const Psid &a, const Psid &b); |
83 |
bool operator != (const Psid &a, const Psid &b); |
84 |
|
85 |
/** |
86 |
* WSMP Normal, see 5.5, 7.3.2 |
87 |
* WSMP Safety supplement, see Annex F |
88 |
* WSMP Identify supplement, see IEEE 1609.1 |
89 |
* |
90 |
*/ |
91 |
enum WsmpElementId { |
92 |
WSMP_N, |
93 |
WSMP_S, |
94 |
WSMP_I, |
95 |
WSMP_UNKNOW, |
96 |
}; |
97 |
|
98 |
class WsmpInfo { |
99 |
public: |
100 |
WsmpInfo () |
101 |
: m_channel (0), |
102 |
m_channelExtension (false), |
103 |
m_datarate (0), |
104 |
m_datarateExtension (false), |
105 |
m_power (0), |
106 |
m_powerExtension (false), |
107 |
m_id (WSMP_N), |
108 |
m_priority (7) |
109 |
{ |
110 |
|
111 |
} |
112 |
|
113 |
void SetChannelNumber (uint8_t channel, bool extensonEnabled) |
114 |
{ |
115 |
m_channel = channel; |
116 |
m_channelExtension = extensonEnabled; |
117 |
} |
118 |
|
119 |
uint8_t GetChannelNumber (void) |
120 |
{ |
121 |
return m_channel; |
122 |
} |
123 |
|
124 |
bool IsChannelNumberExtension (void) |
125 |
{ |
126 |
return m_channelExtension; |
127 |
} |
128 |
|
129 |
void SetDataRate (uint8_t datarate, bool extensionEnabled) |
130 |
{ |
131 |
m_datarate = datarate; |
132 |
m_datarateExtension = extensionEnabled; |
133 |
} |
134 |
|
135 |
uint8_t GetDataRate (void) |
136 |
{ |
137 |
return m_datarate; |
138 |
} |
139 |
|
140 |
bool IsDatatRateExtension (void) |
141 |
{ |
142 |
return m_datarateExtension; |
143 |
} |
144 |
|
145 |
void SetTxPower (uint8_t power, bool extensionEnabled) |
146 |
{ |
147 |
m_power = power; |
148 |
m_powerExtension = extensionEnabled; |
149 |
} |
150 |
|
151 |
uint8_t GetTxPower (void) |
152 |
{ |
153 |
return m_power; |
154 |
} |
155 |
|
156 |
bool IsTxPowerExtension (void) |
157 |
{ |
158 |
return m_powerExtension; |
159 |
} |
160 |
|
161 |
void SetElementId (WsmpElementId id) |
162 |
{ |
163 |
m_id = id; |
164 |
} |
165 |
|
166 |
WsmpElementId GetElementId (void) |
167 |
{ |
168 |
return m_id; |
169 |
} |
170 |
|
171 |
void SetUserPriority (uint8_t priority) |
172 |
{ |
173 |
m_priority = priority; |
174 |
} |
175 |
|
176 |
uint8_t GetUserPriority (void) |
177 |
{ |
178 |
return m_priority; |
179 |
} |
180 |
|
181 |
private: |
182 |
uint8_t m_channel; |
183 |
bool m_channelExtension; |
184 |
uint8_t m_datarate; |
185 |
bool m_datarateExtension; |
186 |
uint8_t m_power; |
187 |
bool m_powerExtension; |
188 |
WsmpElementId m_id; |
189 |
uint8_t m_priority; |
190 |
}; |
191 |
|
192 |
/** |
193 |
* \brief A low-level Socket API |
194 |
* \ingroup wave |
195 |
* |
196 |
* WsmpSocket API is similar with BSD Socket API, but still differs from BSD Socket API, |
197 |
* thus this class does not inherit directly from ns3::Socket class. |
198 |
* |
199 |
* To satisfy users who are familiar with UDP, here also providers connectionless methods. |
200 |
* - For transmit: Connect, Send, Close |
201 |
* - For receipt: Bind, Recv, Close. |
202 |
* |
203 |
* Usage: |
204 |
* TypeId tid = TypeId::LookupByName ("ns3::WsmpSocketFactory"); |
205 |
* |
206 |
* Ptr<WsmpSocket> recv = WsmpSocket::CreateSocket (c.Get (0), tid); |
207 |
* Psid psid = Psid(0x80, 0x01); |
208 |
* recv->Bind (psid); |
209 |
* recv->SetRecvCallback (MakeCallback (&ReceivePacket)); |
210 |
* |
211 |
* Ptr<WsmpSocket> source = WsmpSocket::CreateSocket (c.Get (1), tid); |
212 |
* source->Connect (Mac48Address::GetBroadcast(), psid); |
213 |
* Simulator::Schedule(Seconds (1.0), &SendPacket, source); |
214 |
*/ |
215 |
class WsmpSocket : public Object { |
216 |
public: |
217 |
/** |
218 |
* \brief Get the type ID. |
219 |
* \return the object TypeId |
220 |
*/ |
221 |
static TypeId GetTypeId (void); |
222 |
WsmpSocket(); |
223 |
virtual ~WsmpSocket(); |
224 |
|
225 |
/** |
226 |
* This method wraps the creation of sockets that is performed |
227 |
* on a given node by a WsmpSocketFactory specified by TypeId. |
228 |
* |
229 |
* \return A smart pointer to a newly created socket. |
230 |
* |
231 |
* \param node The node on which to create the socket |
232 |
* \param tid The TypeId of a WsmpSocketFactory class to use |
233 |
*/ |
234 |
static Ptr<WsmpSocket> CreateSocket (Ptr<Node> node, TypeId tid); |
235 |
|
236 |
/** |
237 |
* \brief Notify application when new data is available to be read. |
238 |
* \param callback This callback is intended to notify a socket that would |
239 |
* have been blocked in a blocking socket model that data is available to be read. |
240 |
*/ |
241 |
void SetRecvCallback (Callback<void, Ptr<WsmpSocket> > callback); |
242 |
|
243 |
/** |
244 |
* \brief Allocate a local endpoint for this socket. |
245 |
* \returns 0 on success, -1 on failure. |
246 |
* |
247 |
* Note: This WsmpSocket::Bind() behavior is different from Socket::Bind(). |
248 |
* Socket::Bind() will randomly select a unused Port for Recv, |
249 |
* while WsmpSocket::Bind() will only bind a special "null" Psid, so that |
250 |
* any incoming WSMP packet will notify the RecvCallback. |
251 |
*/ |
252 |
virtual int Bind (void) = 0; |
253 |
/** |
254 |
* \brief Allocate a local endpoint for this socket. |
255 |
* \param psid the psid to try to allocate |
256 |
* \returns 0 on success, -1 on failure. |
257 |
*/ |
258 |
virtual int Bind (const Psid &psid) = 0; |
259 |
|
260 |
/** |
261 |
* \brief Initiate a connection to all of remote hosts |
262 |
* \param psid Psid of remote. |
263 |
* \returns 0 on success, -1 on error (in which case errno is set). |
264 |
* |
265 |
* Note: Although it is named "connect", the WSMP protocol is only a |
266 |
* connectionless service, thus this method is just a convenient and |
267 |
* helpful function for Send (Packet) method. |
268 |
*/ |
269 |
virtual int Connect (const Psid &psid) = 0; |
270 |
/** |
271 |
* \brief Initiate a connection to a remote host |
272 |
* \param peer the peer address |
273 |
* \param psid the psid in the WSMP header of this packet |
274 |
* \returns 0 on success, -1 on error (in which case errno is set). |
275 |
* |
276 |
* Note: Although it is named "connect", the WSMP protocol is only a |
277 |
* connectionless service, thus this method is just a convenient and |
278 |
* helpful function for Send (Packet) method. |
279 |
*/ |
280 |
virtual int Connect (const Address &peer, const Psid &psid) = 0; |
281 |
/** |
282 |
* \brief Initiate a connection to a remote host |
283 |
* \param peer the peer address |
284 |
* \param psid the psid in the WSMP header of this packet |
285 |
* \param info the transmit and extension information of this packet |
286 |
* \returns 0 on success, -1 on error (in which case errno is set). |
287 |
* |
288 |
* Note: Although it is named "connect", the WSMP protocol is only a |
289 |
* connectionless service, thus this method is just a convenient and |
290 |
* helpful function for Send (Packet) method. |
291 |
*/ |
292 |
virtual int Connect (const Address &peer, const Psid &psid, const WsmpInfo &info) = 0; |
293 |
|
294 |
/** |
295 |
* \brief Send data (or dummy data) to the remote host |
296 |
* |
297 |
* \param packet ns3::Packet to send |
298 |
* \returns the number of bytes accepted for transmission if no error |
299 |
* occurs, and negative otherwise. |
300 |
*/ |
301 |
virtual int Send (Ptr<Packet> packet) = 0; |
302 |
/** |
303 |
* \brief Send data (or dummy data) to the remote host |
304 |
* |
305 |
* \param packet ns3::Packet to send |
306 |
* \param peer the peer address |
307 |
* \param psid the psid in the WSMP header of this packet |
308 |
* \param info the transmit and extension information of this packet |
309 |
* \returns the number of bytes accepted for transmission if no error |
310 |
* occurs, and negative otherwise. |
311 |
* |
312 |
* Note: Although WsmpInfo parameter can determine the transmit channel number, |
313 |
* Users should assign channel access for request channel by using WaveNetDevice::StartSch, |
314 |
* otherwise the created WaveNetDevice only assigns default continuous CCH channel access. |
315 |
*/ |
316 |
virtual int SendTo (Ptr<Packet> packet, const Address & peer, const Psid & psid, const WsmpInfo & info) = 0; |
317 |
|
318 |
/** |
319 |
* \brief Read a single packet from the socket |
320 |
* |
321 |
* \returns Ptr<Packet> of the next in-sequence packet. Returns |
322 |
* 0 if the socket cannot return a next in-sequence packet. |
323 |
*/ |
324 |
virtual Ptr<Packet> Recv (void) = 0; |
325 |
/** |
326 |
* \brief Recv data from the remote host |
327 |
* |
328 |
* \param address the peer address |
329 |
* \param psid the psid in the WMSP header of coming packet |
330 |
* \param info the extension information in the WSMP header of coming packet |
331 |
* \returns Ptr<Packet> of the next in-sequence packet. Returns |
332 |
* 0 if the socket cannot return a next in-sequence packet. |
333 |
*/ |
334 |
virtual Ptr<Packet> RecvFrom (Address & address, Psid & psid, WsmpInfo & info) = 0; |
335 |
|
336 |
/** |
337 |
* \returns The number of bytes which can be sent in a single Send call. |
338 |
*/ |
339 |
virtual uint32_t GetTxAvailable (void) const = 0; |
340 |
/** |
341 |
* Return number of bytes which can be returned from one or |
342 |
* multiple calls to Recv. |
343 |
* Must be possible to call this method from the Recv callback. |
344 |
* |
345 |
* \returns the number of bytes which can be returned from one or |
346 |
* multiple Recv calls. |
347 |
*/ |
348 |
virtual uint32_t GetRxAvailable (void) const = 0; |
349 |
|
350 |
/** |
351 |
* \brief Close a socket. |
352 |
* \returns zero on success, -1 on failure. |
353 |
* |
354 |
* After the Close call, the socket is no longer valid, and cannot |
355 |
* safely be used for subsequent operations. |
356 |
*/ |
357 |
virtual int Close (void) = 0; |
358 |
|
359 |
protected: |
360 |
/** |
361 |
* \brief Notify through the callback (if set) that some data have been received. |
362 |
*/ |
363 |
void NotifyDataRecv (void); |
364 |
|
365 |
private: |
366 |
Callback<void, Ptr<WsmpSocket> > m_receivedData; |
367 |
}; |
368 |
|
369 |
} // namespace ns3 |
370 |
|
371 |
#endif /* WSMP_SOCKET_H */ |