Page Menu
Home
Phorge
Search
Configure Global Search
Log In
Files
F123381
NetworkManager.cpp
No One
Temporary
Actions
Download File
Edit File
Delete File
View Transforms
Subscribe
Award Token
Size
11 KB
Referenced Files
None
Subscribers
None
NetworkManager.cpp
View Options
#include
<echo/Network/NetRedefinitions.h>
#include
<echo/Network/NetworkManager.h>
#include
<echo/Network/NetworkSystem.h>
#include
<echo/Network/Connection.h>
#include
<echo/Network/ConnectionDetails.h>
#include
<echo/Util/StringUtils.h>
#include
<echo/Kernel/Thread.h>
#include
<iostream>
#include
<cctype>
namespace
Echo
{
u8
NetworkManager
::
mAppHeaderID
[
APP_HEADER_ID_SIZE
];
NetworkManager
::
NetworkManager
()
{
#ifdef ECHO_BIG_ENDIAN
mAppHeaderID
[
0
]
=
'B'
;
#else
mAppHeaderID
[
0
]
=
'L'
;
#endif
mAppHeaderID
[
1
]
=
'E'
;
mAppHeaderID
[
2
]
=
'C'
;
mAppHeaderID
[
3
]
=
'H'
;
mAppHeaderID
[
4
]
=
'O'
;
mAppHeaderID
[
5
]
=
'N'
;
mAppHeaderID
[
6
]
=
'P'
;
mAppHeaderID
[
7
]
=
0
;
}
NetworkManager
::~
NetworkManager
()
{
UninstallAllSystems
();
}
void
NetworkManager
::
GetAppHeaderID
(
u8
*
holder
,
u8
size
)
{
if
(
holder
)
{
if
(
size
>
APP_HEADER_ID_SIZE
)
size
=
APP_HEADER_ID_SIZE
;
for
(
u8
b
=
0
;
b
<
size
;
b
++
)
holder
[
b
]
=
mAppHeaderID
[
b
];
}
}
void
NetworkManager
::
SetAppHeaderID
(
u8
*
holder
,
u8
size
)
{
if
(
holder
)
{
if
(
size
>
APP_HEADER_ID_SIZE
)
size
=
APP_HEADER_ID_SIZE
;
if
(
holder
[
0
]
!=
0
)
mAppHeaderID
[
0
]
=
holder
[
0
];
for
(
u8
b
=
1
;
b
<
size
;
b
++
)
mAppHeaderID
[
b
]
=
holder
[
b
];
}
}
bool
NetworkManager
::
Listen
(
IncomingConnectionListener
*
listener
,
const
std
::
string
&
connectionDetails
)
{
ConnectionDetails
detailsExploded
(
connectionDetails
);
shared_ptr
<
NetworkSystem
>
system
;
if
(
detailsExploded
.
HasSystem
())
{
system
=
GetInstalledSystem
(
detailsExploded
.
GetSystem
());
}
else
{
system
=
mDefaultSystem
;
}
if
(
!
system
)
return
false
;
return
system
->
Listen
(
listener
,
detailsExploded
);
}
shared_ptr
<
Connection
>
NetworkManager
::
Connect
(
const
std
::
string
&
connectionDetails
)
{
ConnectionDetails
detailsExploded
(
connectionDetails
);
shared_ptr
<
NetworkSystem
>
system
;
if
(
detailsExploded
.
HasSystem
())
{
system
=
GetInstalledSystem
(
detailsExploded
.
GetSystem
());
}
else
{
system
=
mDefaultSystem
;
}
if
(
!
system
)
return
shared_ptr
<
Connection
>
();
return
system
->
Connect
(
detailsExploded
);
}
bool
NetworkManager
::
InstallSystem
(
shared_ptr
<
NetworkSystem
>
networkSystem
,
bool
defaultSystem
/*=false */
)
{
if
(
!
networkSystem
)
{
std
::
cout
<<
"Error: NetworkManager::InstallSystem(): Null System."
<<
std
::
endl
;
return
false
;
}
std
::
map
<
std
::
string
,
shared_ptr
<
NetworkSystem
>
>::
iterator
it
=
mSystems
.
find
(
networkSystem
->
GetName
());
if
(
it
!=
mSystems
.
end
())
{
std
::
cout
<<
"Error: NetworkManager::InstallSystem(): System with name '"
<<
networkSystem
->
GetName
()
<<
"' already exists."
<<
std
::
endl
;
return
false
;
}
if
(
!
networkSystem
->
Initialise
())
{
std
::
cout
<<
"Error: NetworkManager::InstallSystem(): Network system '"
<<
networkSystem
->
GetName
()
<<
"' failed to initialise."
<<
std
::
endl
;
return
false
;
}
mSystems
[
networkSystem
->
GetName
()]
=
networkSystem
;
if
(
defaultSystem
||
!
mDefaultSystem
)
mDefaultSystem
=
networkSystem
;
return
true
;
}
bool
NetworkManager
::
UninstallSystem
(
const
std
::
string
&
name
)
{
std
::
map
<
std
::
string
,
shared_ptr
<
NetworkSystem
>
>::
iterator
it
=
mSystems
.
find
(
name
);
if
(
it
==
mSystems
.
end
())
{
std
::
cout
<<
"Error: NetworkManager::UninstallSystem(): System with name '"
<<
name
<<
"' not found."
<<
std
::
endl
;
return
false
;
}
it
->
second
->
DisconnectAll
();
//Update disconnect notification.
ProcessDroppedConnections
();
it
->
second
->
CleanUp
();
mSystems
.
erase
(
it
);
return
true
;
}
shared_ptr
<
NetworkSystem
>
NetworkManager
::
GetInstalledSystem
(
const
std
::
string
&
name
)
{
std
::
map
<
std
::
string
,
shared_ptr
<
NetworkSystem
>
>::
iterator
it
=
mSystems
.
find
(
name
);
if
(
it
==
mSystems
.
end
())
{
std
::
cout
<<
"Error: NetworkManager::GetInstalledSystem(): System with name '"
<<
name
<<
"' not found."
<<
std
::
endl
;
return
shared_ptr
<
NetworkSystem
>
();
}
return
it
->
second
;
}
void
NetworkManager
::
UninstallAllSystems
()
{
while
(
!
mSystems
.
empty
())
{
UninstallSystem
(
mSystems
.
begin
()
->
first
);
}
}
void
NetworkManager
::
ConnectionEstablished
(
shared_ptr
<
Connection
>
connection
)
{
mConnectionListsMutex
.
Lock
();
mConnectionsEstablished
.
push_back
(
connection
);
mConnectionListsMutex
.
Unlock
();
if
(
!
mNetworkEventListeners
.
empty
())
{
std
::
list
<
shared_ptr
<
NetworkEventListener
>
>::
iterator
it
=
mNetworkEventListeners
.
begin
();
std
::
list
<
shared_ptr
<
NetworkEventListener
>
>::
iterator
itEnd
=
mNetworkEventListeners
.
end
();
while
(
it
!=
itEnd
)
{
(
*
it
)
->
OnNetworkEvent
(
NetworkEventListener
::
NetworkEventTypes
::
ESTABLISHED
);
++
it
;
}
}
}
void
NetworkManager
::
ConnectionIncoming
(
shared_ptr
<
Connection
>
connection
,
IncomingConnectionListener
*
listener
)
{
mConnectionListsMutex
.
Lock
();
mConnectionsIncoming
.
push_back
(
std
::
make_pair
(
connection
,
listener
));
mConnectionListsMutex
.
Unlock
();
if
(
!
mNetworkEventListeners
.
empty
())
{
std
::
list
<
shared_ptr
<
NetworkEventListener
>
>::
iterator
it
=
mNetworkEventListeners
.
begin
();
std
::
list
<
shared_ptr
<
NetworkEventListener
>
>::
iterator
itEnd
=
mNetworkEventListeners
.
end
();
while
(
it
!=
itEnd
)
{
(
*
it
)
->
OnNetworkEvent
(
NetworkEventListener
::
NetworkEventTypes
::
INCOMING_CONNECTION
);
++
it
;
}
}
}
void
NetworkManager
::
ConnectionDropped
(
shared_ptr
<
Connection
>
connection
)
{
mConnectionListsMutex
.
Lock
();
mConnectionsDropped
.
push_back
(
connection
);
mConnectionListsMutex
.
Unlock
();
if
(
!
mNetworkEventListeners
.
empty
())
{
std
::
list
<
shared_ptr
<
NetworkEventListener
>
>::
iterator
it
=
mNetworkEventListeners
.
begin
();
std
::
list
<
shared_ptr
<
NetworkEventListener
>
>::
iterator
itEnd
=
mNetworkEventListeners
.
end
();
while
(
it
!=
itEnd
)
{
(
*
it
)
->
OnNetworkEvent
(
NetworkEventListener
::
NetworkEventTypes
::
DISCONNECTED
);
++
it
;
}
}
}
void
NetworkManager
::
ConnectionPacketReceived
(
shared_ptr
<
Connection
>
connection
)
{
mConnectionListsMutex
.
Lock
();
mConnectionsPendingRecvNotify
.
push_back
(
connection
);
mConnectionListsMutex
.
Unlock
();
if
(
!
mNetworkEventListeners
.
empty
())
{
std
::
list
<
shared_ptr
<
NetworkEventListener
>
>::
iterator
it
=
mNetworkEventListeners
.
begin
();
std
::
list
<
shared_ptr
<
NetworkEventListener
>
>::
iterator
itEnd
=
mNetworkEventListeners
.
end
();
while
(
it
!=
itEnd
)
{
(
*
it
)
->
OnNetworkEvent
(
NetworkEventListener
::
NetworkEventTypes
::
PACKET_RECEIVED
);
++
it
;
}
}
}
bool
NetworkManager
::
OnStart
()
{
std
::
map
<
std
::
string
,
shared_ptr
<
NetworkSystem
>
>::
iterator
it
=
mSystems
.
begin
();
std
::
map
<
std
::
string
,
shared_ptr
<
NetworkSystem
>
>::
iterator
itEnd
=
mSystems
.
end
();
while
(
it
!=
itEnd
)
{
if
(
!
it
->
second
->
Start
())
{
std
::
cout
<<
"Error: NetworkManager::Start(): System '"
<<
it
->
second
->
GetName
()
<<
"' failed to start."
<<
std
::
endl
;
}
++
it
;
}
return
true
;
}
void
NetworkManager
::
OnStop
()
{
std
::
map
<
std
::
string
,
shared_ptr
<
NetworkSystem
>
>::
iterator
it
=
mSystems
.
begin
();
std
::
map
<
std
::
string
,
shared_ptr
<
NetworkSystem
>
>::
iterator
itEnd
=
mSystems
.
end
();
while
(
it
!=
itEnd
)
{
it
->
second
->
DisconnectAll
();
//Update disconnect notification.
ProcessDroppedConnections
();
it
->
second
->
CleanUp
();
++
it
;
}
}
void
NetworkManager
::
Update
(
Seconds
lastFrametime
)
{
TaskGroup
::
Update
(
lastFrametime
);
ProcessEstablishedConnections
();
ProcessIncomingConnections
();
ProcessReceiveNotifications
();
ProcessDroppedConnections
();
}
void
NetworkManager
::
ProcessDroppedConnections
()
{
mConnectionListsMutex
.
Lock
();
if
(
!
mConnectionsDropped
.
empty
())
{
std
::
list
<
shared_ptr
<
Connection
>
>::
iterator
it
=
mConnectionsDropped
.
begin
();
std
::
list
<
shared_ptr
<
Connection
>
>::
iterator
itEnd
=
mConnectionsDropped
.
end
();
while
(
it
!=
itEnd
)
{
(
*
it
)
->
_dropped
();
++
it
;
}
mConnectionsDropped
.
clear
();
}
mConnectionListsMutex
.
Unlock
();
}
void
NetworkManager
::
ProcessEstablishedConnections
()
{
mConnectionListsMutex
.
Lock
();
if
(
!
mConnectionsEstablished
.
empty
())
{
std
::
list
<
shared_ptr
<
Connection
>
>::
iterator
it
=
mConnectionsEstablished
.
begin
();
std
::
list
<
shared_ptr
<
Connection
>
>::
iterator
itEnd
=
mConnectionsEstablished
.
end
();
while
(
it
!=
itEnd
)
{
(
*
it
)
->
_established
();
++
it
;
}
mConnectionsEstablished
.
clear
();
}
mConnectionListsMutex
.
Unlock
();
}
void
NetworkManager
::
ProcessIncomingConnections
()
{
mConnectionListsMutex
.
Lock
();
if
(
!
mConnectionsIncoming
.
empty
())
{
std
::
list
<
std
::
pair
<
shared_ptr
<
Connection
>
,
IncomingConnectionListener
*
>
>::
iterator
it
=
mConnectionsIncoming
.
begin
();
std
::
list
<
std
::
pair
<
shared_ptr
<
Connection
>
,
IncomingConnectionListener
*
>
>::
iterator
itEnd
=
mConnectionsIncoming
.
end
();
while
(
it
!=
itEnd
)
{
it
->
second
->
IncomingConnection
(
it
->
first
);
++
it
;
}
mConnectionsIncoming
.
clear
();
}
mConnectionListsMutex
.
Unlock
();
}
void
NetworkManager
::
ProcessReceiveNotifications
()
{
mConnectionListsMutex
.
Lock
();
if
(
!
mConnectionsPendingRecvNotify
.
empty
())
{
std
::
list
<
shared_ptr
<
Connection
>
>
processAgain
;
std
::
list
<
shared_ptr
<
Connection
>
>::
iterator
it
=
mConnectionsPendingRecvNotify
.
begin
();
std
::
list
<
shared_ptr
<
Connection
>
>::
iterator
itEnd
=
mConnectionsPendingRecvNotify
.
end
();
while
(
it
!=
itEnd
)
{
if
((
*
it
)
->
NotifyAnyReceivedPackets
())
{
processAgain
.
push_back
((
*
it
));
}
++
it
;
}
mConnectionsPendingRecvNotify
=
processAgain
;
}
mConnectionListsMutex
.
Unlock
();
}
u32
NetworkManager
::
GetAddrFromString
(
const
std
::
string
&
address
)
{
//#ifdef ECHO_PLATFORM_WINDOWS
struct
hostent
*
remoteHost
;
//=gethostbyname();
struct
in_addr
addr
;
// If the user input is an alpha name for the host, use gethostbyname()
// If not, get host by addr (assume IPv4)
if
(
isalpha
(
address
.
c_str
()[
0
]))
{
// host address is a name
//std::cout << "Calling gethostbyname with " << address << std::endl;
remoteHost
=
gethostbyname
(
address
.
c_str
());
addr
.
s_addr
=
inet_addr
(
remoteHost
->
h_addr_list
[
0
]);
}
else
{
//std::cout << "Calling gethostbyaddr with " << address << std::endl;
addr
.
s_addr
=
inet_addr
(
address
.
c_str
());
if
(
addr
.
s_addr
==
INADDR_NONE
)
{
std
::
cout
<<
"The IPv4 address entered must be a legal address"
<<
std
::
endl
;
return
0
;
}
else
remoteHost
=
gethostbyaddr
((
char
*
)
&
addr
,
4
,
AF_INET
);
}
if
(
remoteHost
==
NULL
)
{
//int dwError = WSAGetLastError();
//if (dwError != 0)
//{
// if (dwError == WSAHOST_NOT_FOUND)
// {
// std::cout << "Host not found\n" << std::endl;
// } else
// if (dwError == WSANO_DATA)
// {
// std::cout << "No data record found" << std::endl;
// } else
// {
// std::cout << "Function failed with error: " << dwError << std::endl;
// }
//}
}
else
{
//std::cout << "\tOfficial name: " << remoteHost->h_name << std::endl;
//std::cout << "\tAlternate names: " << remoteHost->h_aliases << std::endl;
//std::cout << "\tAddress type: ";
//switch (remoteHost->h_addrtype)
//{
//case AF_INET:
// std::cout << "\tAF_INET" << std::endl;
// break;
//case AF_INET6:
// std::cout << "\tAF_INET6" << std::endl;
// break;
//case AF_NETBIOS:
// std::cout << "\tAF_NETBIOS" << std::endl;
// break;
//default:
// std::cout << "\t" << remoteHost->h_addrtype << std::endl;
// break;
//}
}
return
addr
.
s_addr
;
//#endif
// return 0;
}
void
NetworkManager
::
AddNetworkEventListener
(
shared_ptr
<
NetworkEventListener
>
listener
)
{
mNetworkEventListeners
.
push_back
(
listener
);
}
void
NetworkManager
::
RemoveNetworkEventListener
(
shared_ptr
<
NetworkEventListener
>
listener
)
{
mNetworkEventListeners
.
remove
(
listener
);
}
void
NetworkManager
::
ClearAllEventListeners
()
{
mNetworkEventListeners
.
clear
();
}
}
File Metadata
Details
Attached
Mime Type
text/x-c++
Expires
Wed, Jan 15, 8:17 PM (2 h, 28 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
71753
Default Alt Text
NetworkManager.cpp (11 KB)
Attached To
Mode
rEE Echo 3
Attached
Detach File
Event Timeline
Log In to Comment