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