|
15 | 15 | * along with this program. If not, see <http://www.gnu.org/licenses/>.
|
16 | 16 | */
|
17 | 17 |
|
| 18 | +#include <FreeNOS/System.h> |
18 | 19 | #include <ByteOrder.h>
|
19 | 20 | #include <Randomizer.h>
|
20 | 21 | #include "Ethernet.h"
|
@@ -79,24 +80,74 @@ FileSystem::Result UDPSocket::write(IOBuffer & buffer,
|
79 | 80 | {
|
80 | 81 | DEBUG("");
|
81 | 82 |
|
82 |
| - // Receive socket information first? |
83 |
| - if (!m_info.port) |
84 |
| - { |
85 |
| - buffer.read(&m_info, sizeof(m_info)); |
| 83 | + // Read socket info and action |
| 84 | + NetworkClient::SocketInfo dest; |
| 85 | + buffer.read(&dest, sizeof(dest)); |
86 | 86 |
|
87 |
| - if (m_info.port == 0) |
| 87 | + // Handle the socket operation |
| 88 | + switch (dest.action) |
| 89 | + { |
| 90 | + case NetworkClient::Listen: |
88 | 91 | {
|
89 |
| - Randomizer rand; |
90 |
| - m_info.port = rand.next() % 65535; |
| 92 | + MemoryBlock::copy(&m_info, &dest, sizeof(m_info)); |
| 93 | + |
| 94 | + if (m_info.port == 0) |
| 95 | + { |
| 96 | + Randomizer rand; |
| 97 | + m_info.port = rand.next() % 65535; |
| 98 | + } |
| 99 | + |
| 100 | + DEBUG("addr =" << m_info.address << " port = " << m_info.port); |
| 101 | + return m_udp->bind(this, m_info.port); |
91 | 102 | }
|
92 | 103 |
|
93 |
| - DEBUG("addr =" << m_info.address << " port = " << m_info.port); |
| 104 | + case NetworkClient::SendSingle: |
| 105 | + return m_udp->sendPacket(&m_info, &dest, buffer, size - sizeof(dest), sizeof(dest)); |
94 | 106 |
|
95 |
| - return m_udp->bind(this, m_info.port); |
96 |
| - } |
97 |
| - else |
98 |
| - { |
99 |
| - return m_udp->sendPacket(&m_info, buffer, size); |
| 107 | + case NetworkClient::SendMultiple: |
| 108 | + { |
| 109 | + NetworkClient::PacketInfo packetInfo; |
| 110 | + FileSystemMessage msg; |
| 111 | + IOBuffer io; |
| 112 | + Size packetOffset = 0; |
| 113 | + |
| 114 | + // Read the first packet info to find the base address for all packets. |
| 115 | + // |
| 116 | + // Note that it is assumed here that all packet buffers |
| 117 | + // originate from the same base address and that each new packet |
| 118 | + // starts after NetworkQueue::PayloadBufferSize bytes. |
| 119 | + buffer.read(&packetInfo, sizeof(packetInfo), sizeof(dest)); |
| 120 | + |
| 121 | + // Prepare dummy filesystem message for the I/O buffer |
| 122 | + msg.from = buffer.getMessage()->from; |
| 123 | + msg.action = FileSystem::WriteFile; |
| 124 | + msg.buffer = (char *)packetInfo.address; |
| 125 | + msg.size = NetworkQueue::MaxPackets * PAGESIZE; |
| 126 | + io.setMessage(&msg); |
| 127 | + |
| 128 | + // read the array of PacketInfo structs that describe |
| 129 | + // all the packets that need to be transferred |
| 130 | + for (Size i = sizeof(dest); i < size; i += sizeof(NetworkClient::PacketInfo)) |
| 131 | + { |
| 132 | + buffer.read(&packetInfo, sizeof(packetInfo), i); |
| 133 | + DEBUG("packet[" << ((i - sizeof(dest)) / sizeof(NetworkClient::PacketInfo)) << |
| 134 | + "] size = " << packetInfo.size << " offset = " << packetOffset); |
| 135 | + |
| 136 | + const FileSystem::Result r = m_udp->sendPacket(&m_info, &dest, io, packetInfo.size, packetOffset); |
| 137 | + if (r != FileSystem::Success) |
| 138 | + { |
| 139 | + ERROR("failed to send packet: result = " << (int) r); |
| 140 | + return r; |
| 141 | + } |
| 142 | + |
| 143 | + packetOffset += NetworkQueue::PayloadBufferSize; |
| 144 | + } |
| 145 | + |
| 146 | + return FileSystem::Success; |
| 147 | + } |
| 148 | + |
| 149 | + default: |
| 150 | + return FileSystem::NotSupported; |
100 | 151 | }
|
101 | 152 | }
|
102 | 153 |
|
|
0 commit comments