1 // -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- |
1 /* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */ |
2 // |
2 /* |
3 // Copyright (c) 2006 Georgia Tech Research Corporation |
3 * Copyright (c) 2005,2006 INRIA |
4 // All rights reserved. |
4 * All rights reserved. |
5 // |
5 * |
6 // This program is free software; you can redistribute it and/or modify |
6 * This program is free software; you can redistribute it and/or modify |
7 // it under the terms of the GNU General Public License version 2 as |
7 * it under the terms of the GNU General Public License version 2 as |
8 // published by the Free Software Foundation; |
8 * published by the Free Software Foundation; |
9 // |
9 * |
10 // This program is distributed in the hope that it will be useful, |
10 * This program is distributed in the hope that it will be useful, |
11 // but WITHOUT ANY WARRANTY; without even the implied warranty of |
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of |
12 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
13 // GNU General Public License for more details. |
13 * GNU General Public License for more details. |
14 // |
14 * |
15 // You should have received a copy of the GNU General Public License |
15 * You should have received a copy of the GNU General Public License |
16 // along with this program; if not, write to the Free Software |
16 * along with this program; if not, write to the Free Software |
17 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA |
17 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA |
18 // |
18 * |
19 // Author: George F. Riley<riley@ece.gatech.edu> |
19 * Author: Mathieu Lacage <mathieu.lacage@sophia.inria.fr> |
20 // |
20 */ |
21 |
21 |
22 // Implementation of a point-to-point network device |
22 #include <iostream> |
23 // George F. Riley, Georgia Tech, Spring 2007 |
23 #include <cassert> |
24 |
24 #include "ns3/debug.h" |
25 #include "ns3/empty-trace-resolver.h" |
25 #include "ns3/queue.h" |
|
26 #include "ns3/composite-trace-resolver.h" |
26 #include "p2p-net-device.h" |
27 #include "p2p-net-device.h" |
27 #include "p2p-channel.h" |
28 #include "p2p-channel.h" |
|
29 #include "p2p-phy.h" |
|
30 |
|
31 NS_DEBUG_COMPONENT_DEFINE ("SerialNetDevice"); |
28 |
32 |
29 namespace ns3 { |
33 namespace ns3 { |
30 |
34 |
31 P2PNetDevice::P2PNetDevice (Node *node, MacAddress const &addr) |
35 |
32 : NetDevice (node, addr), |
36 SerialNetDevice::SerialNetDevice(Node* node) : |
33 m_rate (1000000) |
37 NetDevice(node, MacAddress("00:00:00:00:00:00")) |
34 { |
38 { |
35 SetMtu (2300); |
39 NS_DEBUG ("SerialNetDevice::SerialNetDevice (" << node << ")"); |
|
40 |
|
41 // BUGBUG FIXME |
|
42 // |
|
43 // You _must_ support broadcast to get any sort of packet from the ARP layer. |
36 EnableBroadcast (MacAddress ("ff:ff:ff:ff:ff:ff")); |
44 EnableBroadcast (MacAddress ("ff:ff:ff:ff:ff:ff")); |
|
45 EnableMulticast(); |
|
46 EnablePointToPoint(); |
|
47 SetMtu(512); // bytes |
|
48 |
|
49 m_phy = new SerialPhy(node, this); |
37 } |
50 } |
38 |
51 |
39 P2PNetDevice::~P2PNetDevice() |
52 SerialNetDevice::~SerialNetDevice() |
40 { // Inform channel that we are destroyed |
53 { |
41 m_channel->RemoveNetDevice(this); |
54 NS_DEBUG ("SerialNetDevice::~SerialNetDevice ()"); |
|
55 delete m_phy; |
42 } |
56 } |
43 |
57 |
44 void |
58 |
45 P2PNetDevice::SetRate (double rate) |
59 bool |
|
60 SerialNetDevice::SendTo (Packet& p, const MacAddress& dest) |
46 { |
61 { |
47 m_rate = rate; |
62 NS_DEBUG ("SerialNetDevice::SendTo (" << &p << ", " << &dest << ")"); |
|
63 |
|
64 assert (IsLinkUp ()); |
|
65 |
|
66 #ifdef NOTYET |
|
67 struct NetDevicePacketDestAddress tag; |
|
68 tag.address = address; |
|
69 p.AddTag (tag); |
|
70 #endif |
|
71 if (m_queue->Enqueue(p) ) |
|
72 { |
|
73 NotifyDataAvailable (); |
|
74 return true; |
|
75 } |
|
76 return false; |
48 } |
77 } |
49 |
78 |
50 void |
79 TraceResolver * |
51 P2PNetDevice::Connect (P2PChannel *channel) |
80 SerialNetDevice::DoCreateTraceResolver (TraceContext const &context) |
52 { |
81 { |
53 m_channel = channel; |
82 CompositeTraceResolver *resolver = new CompositeTraceResolver (context); |
54 NotifyLinkUp (); |
83 resolver->Add ("queue", |
|
84 MakeCallback (&Queue::CreateTraceResolver, m_queue), |
|
85 SerialNetDevice::QUEUE); |
|
86 resolver->Add ("rx", |
|
87 m_rxTrace, |
|
88 SerialNetDevice::RX); |
|
89 return resolver; |
55 } |
90 } |
56 |
91 |
57 bool |
92 bool |
58 P2PNetDevice::SendTo (Packet& p, const MacAddress&) |
93 SerialNetDevice::Attach (SerialChannel* ch) |
59 { |
94 { |
60 m_channel->Send (this, p, m_rate); |
95 NS_DEBUG ("SerialNetDevice::Attach (" << &ch << ")"); |
|
96 |
|
97 m_channel = ch; |
|
98 m_phy->Attach (m_channel); |
|
99 /* |
|
100 * For now, this device is up whenever a channel is attached to it. |
|
101 * In fact, it should become up only when the second device |
|
102 * is attached to the channel. So, there should be a way for |
|
103 * a SerialChannel to notify both of its attached devices |
|
104 * that the channel is 'complete', hence that the devices are |
|
105 * up, hence that they can call NotifyLinkUp. |
|
106 */ |
|
107 NotifyLinkUp (); |
61 return true; |
108 return true; |
62 } |
109 } |
63 |
110 |
64 TraceResolver * |
111 void |
65 P2PNetDevice::DoCreateTraceResolver (TraceContext const &context) |
112 SerialNetDevice::AddQueue (Queue* q) |
66 { |
113 { |
67 return new EmptyTraceResolver (context); |
114 NS_DEBUG ("SerialNetDevice::AddQueue (" << q << ")"); |
|
115 |
|
116 m_queue = q; |
68 } |
117 } |
69 |
118 |
70 void |
119 void |
71 P2PNetDevice::Receive(Packet p) |
120 SerialNetDevice::Receive (Packet& p) |
72 { |
121 { |
|
122 // ignore return value for now. |
|
123 NS_DEBUG ("SerialNetDevice::Receive (" << &p << ")"); |
|
124 |
|
125 m_rxTrace (p); |
73 ForwardUp (p); |
126 ForwardUp (p); |
74 } |
127 } |
75 |
128 |
76 void |
129 void |
77 P2PNetDevice::TxComplete (void) |
130 SerialNetDevice::NotifyDataAvailable(void) |
78 {} |
131 { |
|
132 NS_DEBUG ("SerialNetDevice::NotifyDataAvailable ()"); |
79 |
133 |
80 }//namespace ns3 |
134 Packet p; |
|
135 bool found = GetQueue ()->Dequeue (p); |
|
136 if (found) |
|
137 { |
|
138 #ifdef NOTYET |
|
139 struct NetDevicePacketDestAddress tag; |
|
140 p.PeekTag (tag); |
|
141 // send packet to address tag.address |
|
142 #endif |
|
143 NS_DEBUG ("SerialNetDevice::NotifyDataAvailable (): Dequeued"); |
|
144 m_phy->Send(p); |
|
145 } |
|
146 } |
|
147 |
|
148 Queue* |
|
149 SerialNetDevice::GetQueue(void) const |
|
150 { |
|
151 return m_queue; |
|
152 } |
|
153 |
|
154 SerialChannel* |
|
155 SerialNetDevice::GetChannel(void) const |
|
156 { |
|
157 return m_channel; |
|
158 } |
|
159 |
|
160 } // namespace ns3 |