Page MenuHomePhorge

NetworkManager.cpp
No OneTemporary

Size
11 KB
Referenced Files
None
Subscribers
None

NetworkManager.cpp

#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

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)

Event Timeline