Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
94 changes: 94 additions & 0 deletions lib/libkiwi/ap/kiwiAPServer.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,94 @@
#include <libkiwi.h>

namespace kiwi {
namespace ap {

/**
* @brief Constructor
*
* @param pParser Message parser
* @param port Local port
*/
Server::Server(IMessageParser* pParser, u16 port)
: mpSocket(nullptr), mPort(0), mpConnection(nullptr), mpParser(pParser) {

K_ASSERT_PTR(mpParser);

mpSocket = new SyncSocket(SO_PF_INET, SO_SOCK_DGRAM);
K_ASSERT_PTR(mpSocket);
mpSocket->SetBlocking(false);

// Variable packets only enforce an upper size bound
IPacketFactory* pPacketFactory =
new VariablePacketFactory<MAX_PACKET_SIZE>();
K_ASSERT_PTR(pPacketFactory);

mpConnection = new NetServer(mpSocket, pPacketFactory);
K_ASSERT_PTR(mpConnection);

// Bind to any available local address
SockAddr4 addr(port);
bool success = mpConnection->Bind(addr);
ASSERT_EX(success, "Can't bind server socket on port %d", addr.port);
mPort = addr.port;

mpConnection->SetRecvCallback(PacketCallback, this);

// Save server address
mpSocket->GetHostAddr(mServerAddr);
mServerAddr.port = mPort;
}

/**
* @brief Destructor
*/
Server::~Server() {
delete mpConnection;
mpConnection = nullptr;

delete mpSocket;
mpSocket = nullptr;

delete mpParser;
mpParser = nullptr;
}

/**
* @brief Packet receive callback
*
* @param pPacket Incoming packet
* @param pArg Callback user argument
*/
void Server::PacketCallback(PacketBase* pPacket, void* pArg) {
K_ASSERT_PTR(pPacket);
K_ASSERT_PTR(pArg);

// Callback argument is this object
Server* p = static_cast<Server*>(pArg);
K_ASSERT_PTR(p->mpParser);

IMessage* pMessage =
p->mpParser->Parse(pPacket->GetContent(), pPacket->GetContentSize());

if (pMessage == nullptr) {
return;
}

// Notify listeners
K_FOREACH (it, p->mListenerList) {
K_ASSERT_PTR(*it);
(*it)->OnReceiveMessage(pMessage);
}

// Listener responses
K_FOREACH (it, p->mListenerList) {
K_ASSERT_PTR(*it);
(*it)->OnRespondMessage(pMessage, p->mpConnection);
}

// Release message memory
delete pMessage;
}

} // namespace ap
} // namespace kiwi
132 changes: 132 additions & 0 deletions lib/libkiwi/ap/kiwiAPServer.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,132 @@
#ifndef LIBKIWI_AP_AP_SERVER_H
#define LIBKIWI_AP_AP_SERVER_H
#include <libkiwi/k_types.h>
#include <libkiwi/net/kiwiPortRegistry.h>
#include <libkiwi/prim/kiwiList.h>
#include <libkiwi/prim/kiwiOptional.h>
#include <libkiwi/support/kiwiLibSO.h>

namespace kiwi {
//! @addtogroup libkiwi_fun
//! @{

// Forward declarations
class NetServer;
class PacketBase;
class SockAddrAny;
class SyncSocket;

namespace ap {
//! @addtogroup libkiwi_fun
//! @{

// Forward declarations
class IMessageListener;
class IMessageParser;

/**
* @brief Archipelago server
*/
class Server {
public:
/**
* @brief Constructor
*
* @param pParser Message parser (owned by this server)
* @param port Local port
*/
Server(IMessageParser* pParser, u16 port = port::AP_COMM);

/**
* @brief Destructor
*/
virtual ~Server();

/**
* @brief Registers a new message listener
*
* @param pListener Message listener
*/
void RegistListener(IMessageListener* pListener) {
K_ASSERT_PTR(pListener);
mListenerList.PushBack(pListener);
}

/**
* @brief Removes a message listener
*
* @param pListener Message listener
*/
void RemoveListener(IMessageListener* pListener) {
mListenerList.Remove(pListener);
}

/**
* @brief Gets the local address of the server
*/
const SockAddr4& GetServerAddr() const {
return mServerAddr;
}

/**
* @brief Gets the connection peer address
*/
const SockAddrAny& GetPeerAddr() const {
return mPeerAddr;
}

/**
* @brief Sets the connection peer address
*
* @param rAddr Peer address
*/
void SetPeerAddr(const SockAddrAny& rAddr) {
K_ASSERT(rAddr.IsValid());
mPeerAddr = rAddr;
}

/**
* @brief Clears the connection peer address
*/
void ResetPeerAddr() {
mPeerAddr = SockAddrAny();
}

private:
//! Maximum datagram packet size from the PC client
static const u32 MAX_PACKET_SIZE = 512;

private:
/**
* @brief Packet receive callback
*
* @param pPacket Incoming packet
* @param pArg Callback user argument
*/
static void PacketCallback(PacketBase* pPacket, void* pArg);

private:
//! Server socket
SyncSocket* mpSocket;
//! Server socket port
u16 mPort;
//! Server connection
NetServer* mpConnection;

//! Server socket address
SockAddr4 mServerAddr;
//! Client socket address
SockAddrAny mPeerAddr;

//! Message parser (owning view)
IMessageParser* mpParser;
//! Registered message listeners
TList<IMessageListener*> mListenerList;
};

//! @}
} // namespace ap
//! @}
} // namespace kiwi

#endif
33 changes: 33 additions & 0 deletions lib/libkiwi/ap/kiwiIAPMessage.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
#ifndef LIBKIWI_AP_I_AP_MESSAGE_H
#define LIBKIWI_AP_I_AP_MESSAGE_H
#include <libkiwi/k_types.h>

namespace kiwi {
//! @addtogroup libkiwi_fun
//! @{
namespace ap {
//! @addtogroup libkiwi_fun
//! @{

/**
* @brief Archipelago message interface
*/
class IMessage {
public:
/**
* @brief Destructor
*/
virtual ~IMessage() {}

/**
* @brief Gets the type of this message
*/
virtual u32 GetType() const = 0;
};

//! @}
} // namespace ap
//! @}
} // namespace kiwi

#endif
51 changes: 51 additions & 0 deletions lib/libkiwi/ap/kiwiIAPMessageListener.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
#ifndef LIBKIWI_AP_I_AP_MESSAGE_LISTENER_H
#define LIBKIWI_AP_I_AP_MESSAGE_LISTENER_H
#include <libkiwi/k_types.h>

namespace kiwi {
//! @addtogroup libkiwi_fun
//! @{

// Forward declarations
class NetConnection;

namespace ap {
//! @addtogroup libkiwi_fun
//! @{

// Forward declarations
class IMessage;

/**
* @brief Archipelago message listener interface
*/
class IMessageListener {
public:
/**
* @brief Destructor
*/
virtual ~IMessageListener() {}

/**
* @brief Callback for receiving a network message
*
* @param pMessage Network message
*/
virtual void OnReceiveMessage(IMessage* pMessage) = 0;

/**
* @brief Callback for responding to a network message
*
* @param pMessage Network message
* @param pConnection Network connection
*/
virtual void OnRespondMessage(IMessage* pMessage,
NetConnection* pConnection) = 0;
};

//! @}
} // namespace ap
//! @}
} // namespace kiwi

#endif
34 changes: 34 additions & 0 deletions lib/libkiwi/ap/kiwiIAPMessageParser.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
#ifndef LIBKIWI_AP_I_AP_MESSAGE_PARSER_H
#define LIBKIWI_AP_I_AP_MESSAGE_PARSER_H
#include <libkiwi/k_types.h>

namespace kiwi {
//! @addtogroup libkiwi_fun
//! @{
namespace ap {
//! @addtogroup libkiwi_fun
//! @{

// Forward declarations
class IMessage;

/**
* @brief Archipelago message parser interface
*/
class IMessageParser {
public:
/**
* @brief Attempts to parse a network message
*
* @param pData Raw message data
* @param size Message data size
*/
virtual IMessage* Parse(const void* pData, u32 size) = 0;
};

//! @}
} // namespace ap
//! @}
} // namespace kiwi

#endif
4 changes: 4 additions & 0 deletions lib/libkiwi/libkiwi.h
Original file line number Diff line number Diff line change
@@ -1,6 +1,10 @@
#ifndef LIBKIWI_LIBRARY_H
#define LIBKIWI_LIBRARY_H

#include <libkiwi/ap/kiwiAPServer.h>
#include <libkiwi/ap/kiwiIAPMessage.h>
#include <libkiwi/ap/kiwiIAPMessageListener.h>
#include <libkiwi/ap/kiwiIAPMessageParser.h>
#include <libkiwi/core/kiwiColor.h>
#include <libkiwi/core/kiwiConsoleOut.h>
#include <libkiwi/core/kiwiController.h>
Expand Down
2 changes: 1 addition & 1 deletion lib/libkiwi/net/kiwiNetClient.h
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ namespace kiwi {
/**
* @brief Network client
*/
class NetClient : public detail::NetConnection {
class NetClient : public NetConnection {
public:
/**
* @brief Constructor
Expand Down
Loading
Loading