1d9e4b4ceSRene Gollent/*
268893948SRene Gollent * Copyright 2016-2017, Rene Gollent, rene@gollent.com.
3d9e4b4ceSRene Gollent * Distributed under the terms of the MIT License.
4d9e4b4ceSRene Gollent */
5d9e4b4ceSRene Gollent#include "TargetHostInterfaceRoster.h"
6d9e4b4ceSRene Gollent
7d9e4b4ceSRene Gollent#include <new>
8d9e4b4ceSRene Gollent
9d9e4b4ceSRene Gollent#include <AutoDeleter.h>
107dde731fSRene Gollent#include <AutoLocker.h>
11d9e4b4ceSRene Gollent
12d9e4b4ceSRene Gollent#include "LocalTargetHostInterfaceInfo.h"
13692fe555SRene Gollent#include "NetworkTargetHostInterfaceInfo.h"
14d9e4b4ceSRene Gollent#include "TargetHostInterfaceInfo.h"
15d9e4b4ceSRene Gollent
16d9e4b4ceSRene Gollent
17d9e4b4ceSRene Gollent/*static*/ TargetHostInterfaceRoster*
18d9e4b4ceSRene Gollent	TargetHostInterfaceRoster::sDefaultInstance = NULL;
19d9e4b4ceSRene Gollent
20d9e4b4ceSRene Gollent
21d9e4b4ceSRene GollentTargetHostInterfaceRoster::TargetHostInterfaceRoster()
22d9e4b4ceSRene Gollent	:
238527cd4dSRene Gollent	TargetHostInterface::Listener(),
24d9e4b4ceSRene Gollent	fLock(),
258527cd4dSRene Gollent	fRunningTeamDebuggers(0),
26d9e4b4ceSRene Gollent	fInterfaceInfos(20, false),
27aed5c39dSRene Gollent	fActiveInterfaces(20, false),
28aed5c39dSRene Gollent	fListener(NULL)
29d9e4b4ceSRene Gollent{
30d9e4b4ceSRene Gollent}
31d9e4b4ceSRene Gollent
32d9e4b4ceSRene Gollent
33d9e4b4ceSRene GollentTargetHostInterfaceRoster::~TargetHostInterfaceRoster()
34d9e4b4ceSRene Gollent{
35c0936b5aSRene Gollent	for (int32 i = 0; TargetHostInterfaceInfo* info
36c0936b5aSRene Gollent			= fInterfaceInfos.ItemAt(i); i++) {
37c0936b5aSRene Gollent		info->ReleaseReference();
38c0936b5aSRene Gollent	}
39c0936b5aSRene Gollent
40c0936b5aSRene Gollent	for (int32 i = 0; TargetHostInterface* interface
41c0936b5aSRene Gollent			= fActiveInterfaces.ItemAt(i); i++) {
42c0936b5aSRene Gollent		if (interface->Lock())
43c0936b5aSRene Gollent			interface->Quit();
44c0936b5aSRene Gollent	}
45d9e4b4ceSRene Gollent}
46d9e4b4ceSRene Gollent
47d9e4b4ceSRene Gollent
48d9e4b4ceSRene Gollent/*static*/ TargetHostInterfaceRoster*
49d9e4b4ceSRene GollentTargetHostInterfaceRoster::Default()
50d9e4b4ceSRene Gollent{
51d9e4b4ceSRene Gollent	return sDefaultInstance;
52d9e4b4ceSRene Gollent}
53d9e4b4ceSRene Gollent
54d9e4b4ceSRene Gollent
55d9e4b4ceSRene Gollent/*static*/ status_t
56aed5c39dSRene GollentTargetHostInterfaceRoster::CreateDefault(Listener* listener)
57d9e4b4ceSRene Gollent{
58d9e4b4ceSRene Gollent	if (sDefaultInstance != NULL)
59d9e4b4ceSRene Gollent		return B_OK;
60d9e4b4ceSRene Gollent
61d9e4b4ceSRene Gollent	TargetHostInterfaceRoster* roster
62d9e4b4ceSRene Gollent		= new(std::nothrow) TargetHostInterfaceRoster;
63d9e4b4ceSRene Gollent	if (roster == NULL)
64d9e4b4ceSRene Gollent		return B_NO_MEMORY;
65d9e4b4ceSRene Gollent	ObjectDeleter<TargetHostInterfaceRoster> rosterDeleter(roster);
66d9e4b4ceSRene Gollent
67aed5c39dSRene Gollent	status_t error = roster->Init(listener);
68d9e4b4ceSRene Gollent	if (error != B_OK)
69d9e4b4ceSRene Gollent		return error;
70d9e4b4ceSRene Gollent
71d9e4b4ceSRene Gollent	error = roster->RegisterInterfaceInfos();
72d9e4b4ceSRene Gollent	if (error != B_OK)
73d9e4b4ceSRene Gollent		return error;
74d9e4b4ceSRene Gollent
75d9e4b4ceSRene Gollent	sDefaultInstance = rosterDeleter.Detach();
76d9e4b4ceSRene Gollent	return B_OK;
77d9e4b4ceSRene Gollent}
78d9e4b4ceSRene Gollent
79d9e4b4ceSRene Gollent
80d9e4b4ceSRene Gollent/*static*/ void
81d9e4b4ceSRene GollentTargetHostInterfaceRoster::DeleteDefault()
82d9e4b4ceSRene Gollent{
83d9e4b4ceSRene Gollent	TargetHostInterfaceRoster* roster = sDefaultInstance;
84d9e4b4ceSRene Gollent	sDefaultInstance = NULL;
85d9e4b4ceSRene Gollent	delete roster;
86d9e4b4ceSRene Gollent}
87d9e4b4ceSRene Gollent
88d9e4b4ceSRene Gollent
89d9e4b4ceSRene Gollentstatus_t
90aed5c39dSRene GollentTargetHostInterfaceRoster::Init(Listener* listener)
91d9e4b4ceSRene Gollent{
92aed5c39dSRene Gollent	fListener = listener;
93d9e4b4ceSRene Gollent	return fLock.InitCheck();
94d9e4b4ceSRene Gollent}
95d9e4b4ceSRene Gollent
96d9e4b4ceSRene Gollent
97d9e4b4ceSRene Gollentstatus_t
98d9e4b4ceSRene GollentTargetHostInterfaceRoster::RegisterInterfaceInfos()
99d9e4b4ceSRene Gollent{
100d9e4b4ceSRene Gollent	TargetHostInterfaceInfo* info = NULL;
101d9e4b4ceSRene Gollent	BReference<TargetHostInterfaceInfo> interfaceReference;
102d9e4b4ceSRene Gollent
103d9e4b4ceSRene Gollent	#undef REGISTER_INTERFACE_INFO
104d9e4b4ceSRene Gollent	#define REGISTER_INTERFACE_INFO(type) \
105d9e4b4ceSRene Gollent		info = new(std::nothrow) type##TargetHostInterfaceInfo; \
106d9e4b4ceSRene Gollent		if (info == NULL) \
107d9e4b4ceSRene Gollent			return B_NO_MEMORY; \
108d9e4b4ceSRene Gollent		interfaceReference.SetTo(info, true); \
10968893948SRene Gollent		if (info->Init() != B_OK) \
11068893948SRene Gollent			return B_NO_MEMORY; \
111d9e4b4ceSRene Gollent		if (!fInterfaceInfos.AddItem(info)) \
112d9e4b4ceSRene Gollent			return B_NO_MEMORY; \
113d9e4b4ceSRene Gollent		interfaceReference.Detach();
114d9e4b4ceSRene Gollent
115d9e4b4ceSRene Gollent	REGISTER_INTERFACE_INFO(Local)
116692fe555SRene Gollent	REGISTER_INTERFACE_INFO(Network)
117d9e4b4ceSRene Gollent
118d9e4b4ceSRene Gollent	return B_OK;
119d9e4b4ceSRene Gollent}
1207dde731fSRene Gollent
1217dde731fSRene Gollent
1227dde731fSRene Gollentint32
1237dde731fSRene GollentTargetHostInterfaceRoster::CountInterfaceInfos() const
1247dde731fSRene Gollent{
1257dde731fSRene Gollent	return fInterfaceInfos.CountItems();
1267dde731fSRene Gollent}
1277dde731fSRene Gollent
1287dde731fSRene Gollent
1297dde731fSRene GollentTargetHostInterfaceInfo*
1307dde731fSRene GollentTargetHostInterfaceRoster::InterfaceInfoAt(int32 index) const
1317dde731fSRene Gollent{
1327dde731fSRene Gollent	return fInterfaceInfos.ItemAt(index);
1337dde731fSRene Gollent}
1347dde731fSRene Gollent
1357dde731fSRene Gollent
1367dde731fSRene Gollentstatus_t
1377dde731fSRene GollentTargetHostInterfaceRoster::CreateInterface(TargetHostInterfaceInfo* info,
1387dde731fSRene Gollent	Settings* settings, TargetHostInterface*& _interface)
1397dde731fSRene Gollent{
1407dde731fSRene Gollent	// TODO: this should eventually verify that an active interface with
1417dde731fSRene Gollent	// matching settings/type doesn't already exist, and if so, return that
1427dde731fSRene Gollent	// directly rather than instantiating a new one, since i.e. the interface
1437dde731fSRene Gollent	// for the local host only requires one instance.
1447dde731fSRene Gollent	AutoLocker<TargetHostInterfaceRoster> locker(this);
1457dde731fSRene Gollent	TargetHostInterface* interface;
1467dde731fSRene Gollent	status_t error = info->CreateInterface(settings, interface);
1477dde731fSRene Gollent	if (error != B_OK)
1487dde731fSRene Gollent		return error;
1497dde731fSRene Gollent
150a1afac4dSRene Gollent	error = interface->Run();
151a1afac4dSRene Gollent	if (error < B_OK || !fActiveInterfaces.AddItem(interface)) {
152a1afac4dSRene Gollent		delete interface;
1537dde731fSRene Gollent		return B_NO_MEMORY;
154a1afac4dSRene Gollent	}
1557dde731fSRene Gollent
1568527cd4dSRene Gollent	interface->AddListener(this);
1577dde731fSRene Gollent	_interface = interface;
1587dde731fSRene Gollent	return B_OK;
1597dde731fSRene Gollent}
1607dde731fSRene Gollent
1617dde731fSRene Gollent
1627dde731fSRene Gollentint32
1637dde731fSRene GollentTargetHostInterfaceRoster::CountActiveInterfaces() const
1647dde731fSRene Gollent{
1657dde731fSRene Gollent	return fActiveInterfaces.CountItems();
1667dde731fSRene Gollent}
1677dde731fSRene Gollent
1687dde731fSRene Gollent
1697dde731fSRene GollentTargetHostInterface*
1707dde731fSRene GollentTargetHostInterfaceRoster::ActiveInterfaceAt(int32 index) const
1717dde731fSRene Gollent{
1727dde731fSRene Gollent	return fActiveInterfaces.ItemAt(index);
1737dde731fSRene Gollent}
1747dde731fSRene Gollent
175a1afac4dSRene Gollent
1768527cd4dSRene Gollentvoid
1778527cd4dSRene GollentTargetHostInterfaceRoster::TeamDebuggerStarted(TeamDebugger* debugger)
178a1afac4dSRene Gollent{
1798527cd4dSRene Gollent	fRunningTeamDebuggers++;
180aed5c39dSRene Gollent	fListener->TeamDebuggerCountChanged(fRunningTeamDebuggers);
1818527cd4dSRene Gollent}
1828527cd4dSRene Gollent
1838527cd4dSRene Gollent
1848527cd4dSRene Gollentvoid
1858527cd4dSRene GollentTargetHostInterfaceRoster::TeamDebuggerQuit(TeamDebugger* debugger)
1868527cd4dSRene Gollent{
1878527cd4dSRene Gollent	fRunningTeamDebuggers--;
188aed5c39dSRene Gollent	fListener->TeamDebuggerCountChanged(fRunningTeamDebuggers);
1898527cd4dSRene Gollent}
1908527cd4dSRene Gollent
191a1afac4dSRene Gollent
1928527cd4dSRene Gollentvoid
1938527cd4dSRene GollentTargetHostInterfaceRoster::TargetHostInterfaceQuit(
1948527cd4dSRene Gollent	TargetHostInterface* interface)
1958527cd4dSRene Gollent{
1968527cd4dSRene Gollent	AutoLocker<TargetHostInterfaceRoster> locker(this);
1978527cd4dSRene Gollent	fActiveInterfaces.RemoveItem(interface);
198c0936b5aSRene Gollent
199a1afac4dSRene Gollent}
200aed5c39dSRene Gollent
201aed5c39dSRene Gollent
202aed5c39dSRene Gollent// #pragma mark - TargetHostInterfaceRoster::Listener
203aed5c39dSRene Gollent
204aed5c39dSRene Gollent
205aed5c39dSRene GollentTargetHostInterfaceRoster::Listener::~Listener()
206aed5c39dSRene Gollent{
207aed5c39dSRene Gollent}
208aed5c39dSRene Gollent
209aed5c39dSRene Gollent
210aed5c39dSRene Gollentvoid
211aed5c39dSRene GollentTargetHostInterfaceRoster::Listener::TeamDebuggerCountChanged(int32 count)
212aed5c39dSRene Gollent{
213aed5c39dSRene Gollent}
214