1*5a1d355fSStephan Aßmus // PortChannel.cpp
2*5a1d355fSStephan Aßmus
3*5a1d355fSStephan Aßmus #include <new>
4*5a1d355fSStephan Aßmus #include <string.h>
5*5a1d355fSStephan Aßmus
6*5a1d355fSStephan Aßmus #include "PortChannel.h"
7*5a1d355fSStephan Aßmus #include "Utils.h"
8*5a1d355fSStephan Aßmus
9*5a1d355fSStephan Aßmus static const int32 kMaxPortMessageSize = 102400; // 100 KB
10*5a1d355fSStephan Aßmus static const int32 kDefaultBufferSize = 10240; // 10 KB
11*5a1d355fSStephan Aßmus
12*5a1d355fSStephan Aßmus // constructor
PortChannel()13*5a1d355fSStephan Aßmus PortChannel::PortChannel()
14*5a1d355fSStephan Aßmus : Channel(),
15*5a1d355fSStephan Aßmus fSendPort(-1),
16*5a1d355fSStephan Aßmus fReceivePort(-1),
17*5a1d355fSStephan Aßmus fBuffer(new(std::nothrow) uint8[kDefaultBufferSize]),
18*5a1d355fSStephan Aßmus fBufferSize(kDefaultBufferSize),
19*5a1d355fSStephan Aßmus fBufferOffset(0),
20*5a1d355fSStephan Aßmus fBufferContentSize(0)
21*5a1d355fSStephan Aßmus {
22*5a1d355fSStephan Aßmus fSendPort = create_port(10, "port connection send port");
23*5a1d355fSStephan Aßmus fReceivePort = create_port(10, "port connection receive port");
24*5a1d355fSStephan Aßmus }
25*5a1d355fSStephan Aßmus
26*5a1d355fSStephan Aßmus // constructor
PortChannel(const Info * info,bool inverse)27*5a1d355fSStephan Aßmus PortChannel::PortChannel(const Info* info, bool inverse)
28*5a1d355fSStephan Aßmus : Channel(),
29*5a1d355fSStephan Aßmus fSendPort(inverse ? info->receivePort : info->sendPort),
30*5a1d355fSStephan Aßmus fReceivePort(inverse ? info->sendPort : info->receivePort),
31*5a1d355fSStephan Aßmus fBuffer(new(std::nothrow) uint8[kDefaultBufferSize]),
32*5a1d355fSStephan Aßmus fBufferSize(kDefaultBufferSize),
33*5a1d355fSStephan Aßmus fBufferOffset(0),
34*5a1d355fSStephan Aßmus fBufferContentSize(0)
35*5a1d355fSStephan Aßmus {
36*5a1d355fSStephan Aßmus }
37*5a1d355fSStephan Aßmus
38*5a1d355fSStephan Aßmus // constructor
PortChannel(port_id sendPort,port_id receivePort)39*5a1d355fSStephan Aßmus PortChannel::PortChannel(port_id sendPort, port_id receivePort)
40*5a1d355fSStephan Aßmus : Channel(),
41*5a1d355fSStephan Aßmus fSendPort(sendPort),
42*5a1d355fSStephan Aßmus fReceivePort(receivePort),
43*5a1d355fSStephan Aßmus fBuffer(new(std::nothrow) uint8[kDefaultBufferSize]),
44*5a1d355fSStephan Aßmus fBufferSize(kDefaultBufferSize),
45*5a1d355fSStephan Aßmus fBufferOffset(0),
46*5a1d355fSStephan Aßmus fBufferContentSize(0)
47*5a1d355fSStephan Aßmus {
48*5a1d355fSStephan Aßmus }
49*5a1d355fSStephan Aßmus
50*5a1d355fSStephan Aßmus // destructor
~PortChannel()51*5a1d355fSStephan Aßmus PortChannel::~PortChannel()
52*5a1d355fSStephan Aßmus {
53*5a1d355fSStephan Aßmus delete[] fBuffer;
54*5a1d355fSStephan Aßmus }
55*5a1d355fSStephan Aßmus
56*5a1d355fSStephan Aßmus // InitCheck
57*5a1d355fSStephan Aßmus status_t
InitCheck() const58*5a1d355fSStephan Aßmus PortChannel::InitCheck() const
59*5a1d355fSStephan Aßmus {
60*5a1d355fSStephan Aßmus if (fSendPort < 0)
61*5a1d355fSStephan Aßmus return fSendPort;
62*5a1d355fSStephan Aßmus if (fReceivePort < 0)
63*5a1d355fSStephan Aßmus return fReceivePort;
64*5a1d355fSStephan Aßmus if (!fBuffer)
65*5a1d355fSStephan Aßmus return B_NO_MEMORY;
66*5a1d355fSStephan Aßmus return B_OK;
67*5a1d355fSStephan Aßmus }
68*5a1d355fSStephan Aßmus
69*5a1d355fSStephan Aßmus // GetInfo
70*5a1d355fSStephan Aßmus void
GetInfo(Info * info) const71*5a1d355fSStephan Aßmus PortChannel::GetInfo(Info* info) const
72*5a1d355fSStephan Aßmus {
73*5a1d355fSStephan Aßmus if (info) {
74*5a1d355fSStephan Aßmus info->sendPort = fSendPort;
75*5a1d355fSStephan Aßmus info->receivePort = fReceivePort;
76*5a1d355fSStephan Aßmus }
77*5a1d355fSStephan Aßmus }
78*5a1d355fSStephan Aßmus
79*5a1d355fSStephan Aßmus // Close
80*5a1d355fSStephan Aßmus void
Close()81*5a1d355fSStephan Aßmus PortChannel::Close()
82*5a1d355fSStephan Aßmus {
83*5a1d355fSStephan Aßmus if (fSendPort >= 0) {
84*5a1d355fSStephan Aßmus delete_port(fSendPort);
85*5a1d355fSStephan Aßmus fSendPort = -1;
86*5a1d355fSStephan Aßmus }
87*5a1d355fSStephan Aßmus if (fReceivePort >= 0) {
88*5a1d355fSStephan Aßmus delete_port(fReceivePort);
89*5a1d355fSStephan Aßmus fReceivePort = -1;
90*5a1d355fSStephan Aßmus }
91*5a1d355fSStephan Aßmus }
92*5a1d355fSStephan Aßmus
93*5a1d355fSStephan Aßmus // Send
94*5a1d355fSStephan Aßmus status_t
Send(const void * _buffer,int32 size)95*5a1d355fSStephan Aßmus PortChannel::Send(const void* _buffer, int32 size)
96*5a1d355fSStephan Aßmus {
97*5a1d355fSStephan Aßmus if (size == 0)
98*5a1d355fSStephan Aßmus return B_OK;
99*5a1d355fSStephan Aßmus if (!_buffer || size < 0)
100*5a1d355fSStephan Aßmus return B_BAD_VALUE;
101*5a1d355fSStephan Aßmus const uint8* buffer = static_cast<const uint8*>(_buffer);
102*5a1d355fSStephan Aßmus while (size > 0) {
103*5a1d355fSStephan Aßmus int32 sendSize = min(size, fBufferSize);
104*5a1d355fSStephan Aßmus status_t error = write_port(fSendPort, 0, buffer, size);
105*5a1d355fSStephan Aßmus if (error != B_OK)
106*5a1d355fSStephan Aßmus return error;
107*5a1d355fSStephan Aßmus size -= sendSize;
108*5a1d355fSStephan Aßmus buffer += sendSize;
109*5a1d355fSStephan Aßmus }
110*5a1d355fSStephan Aßmus return B_OK;
111*5a1d355fSStephan Aßmus }
112*5a1d355fSStephan Aßmus
113*5a1d355fSStephan Aßmus // Receive
114*5a1d355fSStephan Aßmus status_t
Receive(void * _buffer,int32 size)115*5a1d355fSStephan Aßmus PortChannel::Receive(void* _buffer, int32 size)
116*5a1d355fSStephan Aßmus {
117*5a1d355fSStephan Aßmus if (size == 0)
118*5a1d355fSStephan Aßmus return B_OK;
119*5a1d355fSStephan Aßmus if (!_buffer || size < 0)
120*5a1d355fSStephan Aßmus return B_BAD_VALUE;
121*5a1d355fSStephan Aßmus uint8* buffer = static_cast<uint8*>(_buffer);
122*5a1d355fSStephan Aßmus while (size > 0) {
123*5a1d355fSStephan Aßmus if (fBufferContentSize > 0) {
124*5a1d355fSStephan Aßmus // there's something in our buffer: just read from there
125*5a1d355fSStephan Aßmus int32 bytesRead = min(size, fBufferContentSize);
126*5a1d355fSStephan Aßmus memcpy(buffer, fBuffer + fBufferOffset, bytesRead);
127*5a1d355fSStephan Aßmus fBufferOffset += bytesRead;
128*5a1d355fSStephan Aßmus fBufferContentSize -= bytesRead;
129*5a1d355fSStephan Aßmus size -= bytesRead;
130*5a1d355fSStephan Aßmus buffer += bytesRead;
131*5a1d355fSStephan Aßmus } else {
132*5a1d355fSStephan Aßmus // nothing left in the buffer: we read from the port
133*5a1d355fSStephan Aßmus if (size > fBufferSize) {
134*5a1d355fSStephan Aßmus // we shall read more than what would fit into our buffer, so
135*5a1d355fSStephan Aßmus // we can directly read into the user buffer
136*5a1d355fSStephan Aßmus ssize_t bytesRead = read_port(fReceivePort, 0, buffer, size);
137*5a1d355fSStephan Aßmus if (bytesRead < 0)
138*5a1d355fSStephan Aßmus return bytesRead;
139*5a1d355fSStephan Aßmus size -= bytesRead;
140*5a1d355fSStephan Aßmus buffer += bytesRead;
141*5a1d355fSStephan Aßmus } else {
142*5a1d355fSStephan Aßmus // we read into our buffer
143*5a1d355fSStephan Aßmus ssize_t bytesRead = read_port(fReceivePort, 0, fBuffer,
144*5a1d355fSStephan Aßmus fBufferSize);
145*5a1d355fSStephan Aßmus if (bytesRead < 0)
146*5a1d355fSStephan Aßmus return bytesRead;
147*5a1d355fSStephan Aßmus fBufferOffset = 0;
148*5a1d355fSStephan Aßmus fBufferContentSize = bytesRead;
149*5a1d355fSStephan Aßmus }
150*5a1d355fSStephan Aßmus }
151*5a1d355fSStephan Aßmus }
152*5a1d355fSStephan Aßmus return B_OK;
153*5a1d355fSStephan Aßmus }
154*5a1d355fSStephan Aßmus
155