1// PortConnectionListener.cpp
2
3#include "PortConnectionListener.h"
4
5#include <new>
6
7#include <stdio.h>
8
9#include <AutoDeleter.h>
10
11#include "PortConnection.h"
12
13using namespace PortConnectionDefs;
14
15// constructor
16PortConnectionListener::PortConnectionListener()
17	: ConnectionListener(),
18	  fPort(-1)
19{
20}
21
22// destructor
23PortConnectionListener::~PortConnectionListener()
24{
25	if (fPort >= 0)
26		delete_port(fPort);
27}
28
29// Init
30status_t
31PortConnectionListener::Init(const char* parameters)
32{
33	fPort = create_port(5, kPortConnectionPortName);
34	if (fPort < 0)
35		return fPort;
36	return B_OK;
37}
38
39// Listen
40status_t
41PortConnectionListener::Listen(Connection** _connection)
42{
43	if (!_connection || fPort < 0)
44		return B_BAD_VALUE;
45	PortChannel* channel = NULL;
46	int32 upStreamChannels = 0;
47	int32 downStreamChannels = 0;
48	do {
49		// receive a connect request
50		ConnectRequest request;
51		ssize_t bytesRead = read_port(fPort, 0, &request,
52			sizeof(ConnectRequest));
53		if (bytesRead < 0)
54			return bytesRead;
55		if (bytesRead != sizeof(ConnectRequest))
56			continue;
57		// check the protocol version
58		if (request.protocolVersion != kProtocolVersion)
59			continue;
60		// check number of up and down stream channels
61		upStreamChannels = request.upStreamChannels;
62		downStreamChannels = request.downStreamChannels;
63		if (upStreamChannels < kMinUpStreamChannels)
64			upStreamChannels = kMinUpStreamChannels;
65		else if (upStreamChannels > kMaxUpStreamChannels)
66			upStreamChannels = kMaxUpStreamChannels;
67		if (downStreamChannels < kMinDownStreamChannels)
68			downStreamChannels = kMinDownStreamChannels;
69		else if (downStreamChannels > kMaxDownStreamChannels)
70			downStreamChannels = kMaxDownStreamChannels;
71		// create the initial channel
72		channel = new(std::nothrow) PortChannel(&request.channelInfo, true);
73		if (!channel)
74			return B_NO_MEMORY;
75		if (channel->InitCheck() != B_OK) {
76			delete channel;
77			channel = NULL;
78		}
79	} while (!channel);
80	// create the connection
81	PortConnection* connection = new(std::nothrow) PortConnection;
82	if (!connection) {
83		delete channel;
84		return B_NO_MEMORY;
85	}
86	status_t error = connection->Init(channel, upStreamChannels,
87		downStreamChannels);
88	if (error != B_OK) {
89		delete connection;
90		return error;
91	}
92	*_connection = connection;
93	return B_OK;
94}
95
96// StopListening
97void
98PortConnectionListener::StopListening()
99{
100	delete_port(fPort);
101	fPort = -1;
102}
103
104// FinishInitialization
105status_t
106PortConnectionListener::FinishInitialization(Connection* _connection,
107	SecurityContext* securityContext, User** user)
108{
109	PortConnection* connection = dynamic_cast<PortConnection*>(_connection);
110	if (!connection)
111		return B_BAD_VALUE;
112	*user = NULL;
113	return connection->FinishInitialization();
114}
115
116