Page Menu
Home
Phorge
Search
Configure Global Search
Log In
Files
F123492
Connection.h
No One
Temporary
Actions
Download File
Edit File
Delete File
View Transforms
Subscribe
Award Token
Size
17 KB
Referenced Files
None
Subscribers
None
Connection.h
View Options
#ifndef _CONNECTION_H_
#define _CONNECTION_H_
#include
<echo/Types.h>
#include
<echo/Network/ConnectionDetails.h>
#include
<list>
#include
<vector>
#include
<map>
#include
<echo/Kernel/Mutex.h>
#include
<echo/Chrono/CountDownTimer.h>
#include
<boost/function.hpp>
#include
<boost/lexical_cast.hpp>
#include
<boost/bind.hpp>
namespace
Echo
{
class
DataPacket
;
class
DataPacketHeader
;
class
Connection
;
class
ConnectionOwner
;
class
NetworkManager
;
class
Connection
:
public
enable_shared_from_this
<
Connection
>
{
public
:
struct
States
{
enum
_
{
DISCONNECTED
,
CONNECTING
,
CONNECTED
};
};
typedef
States
::
_
State
;
/**
* PacketCallback
* @param first parameter is the connection.
* @param second parameter is the incoming DataPacket.
*/
typedef
boost
::
function
<
void
(
shared_ptr
<
Connection
>
,
shared_ptr
<
DataPacket
>
)
>
PacketCallback
;
static
boost
::
arg
<
1
>
ConnectionPlaceholder
;
static
boost
::
arg
<
2
>
DataPacketPlaceholder
;
/**
* LabelledPacketCallback
* @param first parameter is the connection.
* @param second parameter is the data packet that contained the labelled data.
* @param third is a pointer to the data in the data packet starting at the first byte after the label.
* @param fourth the length of the data in bytes from the (the DataPacket data size minus the label+meta info size).
*/
typedef
boost
::
function
<
void
(
shared_ptr
<
Connection
>
,
shared_ptr
<
DataPacket
>
,
const
u8
*
,
Size
)
>
LabelledPacketCallback
;
static
boost
::
arg
<
2
>
PacketContentsPlaceholder
;
/**
* DisconnectCallback
* @param first parameter is the connection.
*/
typedef
boost
::
function
<
void
(
shared_ptr
<
Connection
>
)
>
DisconnectCallback
;
/**
* ConnectCallback
* @param first parameter is the connection.
*/
typedef
boost
::
function
<
void
(
shared_ptr
<
Connection
>
)
>
ConnectCallback
;
//These packets are used internally for control
struct
PacketTypes
{
enum
Value
{
LABELLED_PACKET
=
0xFFFFFFFF
,
REMOTE_DETAILS
=
0xFEFEFEFE
,
// Remote details packet, sent internally to determine
// communication details with the remote host, such as
// protocol version and endian format. The ID needs to
// read the same in big and little endian.
MINIMUM_RESERVED_PACKET_ID
=
0xF0000000
// Packets IDs after this value are reserved
};
};
typedef
PacketTypes
::
Value
PacketType
;
struct
PacketPoolResizeActions
{
enum
Value
{
RESIZE_ENTIRE_POOL
=
1
,
//Re-allocates enough memory for the
//pool size.
AFFECT_PACKET_COUNT_ONLY
=
2
,
//Attempts to avoid a reallocation
//and instead just affect the number
//of available packets.
};
};
typedef
PacketPoolResizeActions
::
Value
PacketPoolResizeAction
;
static
void
SetPlatformBigEndian
(
bool
isBigEndian
)
{
mPlatformBigEndian
=
isBigEndian
;}
static
bool
IsPlatformBigEndian
()
{
return
mPlatformBigEndian
;}
NetworkManager
&
GetNetworkManager
()
{
return
mNetworkManager
;}
bool
Connect
();
bool
Disconnect
();
void
SetOwner
(
ConnectionOwner
*
owner
);
ConnectionOwner
*
GetOwner
()
const
{
return
mOwner
;}
std
::
string
GetFriendlyIdentifier
();
shared_ptr
<
DataPacket
>
NewDataPacket
();
shared_ptr
<
DataPacket
>
NewDataPacket
(
u32
packetTypeID
,
u32
size
);
shared_ptr
<
DataPacket
>
NewDataPacket
(
std
::
string
label
,
u32
size
);
//Returns true if there are still packets queued to notify
bool
NotifyAnyReceivedPackets
();
size_t
GetNumReceviedPackets
()
const
{
return
mReceviedPackets
.
size
();}
/**
* Send a DataPacket
* @param packet the packet
* @param prioritise If true the packet will be sent before of any packets currently queued.
*/
void
SendDataPacket
(
shared_ptr
<
DataPacket
>
packet
,
bool
prioritise
=
false
);
/**
* Helper method to send data.
* This method builds a DataPacket for you.
* @param data The data
* @param dataSize The number of bytes to send
* @param packetID The packet ID to send the data as.
* @param prioritise If true the packet will be sent before of any packets currently queued.
*/
void
SendData
(
const
u8
*
data
,
u32
dataSize
,
u32
packetID
,
bool
prioritise
=
false
);
/**
* Helper method to send a string.
* @param message the message to send.
* @param packetID the packet ID to send the message as.
* @param prioritise If true the packet will be sent before of any packets currently queued.
*/
void
SendMessage
(
const
std
::
string
&
message
,
u32
packetID
,
bool
prioritise
=
false
);
/**
* Send a control packet.
* A control packet has an ID and no data. Control packets are designed to be
* used for notification.
* @param packetTypeID the ID of the packet you want to send.
* @param prioritise If true the packet will be sent before of any packets currently queued.
*/
void
SendControlPacket
(
u32
packetTypeID
,
bool
prioritise
=
false
);
/**
* Helper method to send a labelled DataPacket.
* @param prioritise If true the packet will be sent before of any packets currently queued.
*/
void
SendLabelledPacket
(
const
std
::
string
&
label
,
const
u8
*
data
,
u32
dataSize
,
bool
prioritise
=
false
);
/**
* Helper method to send a labeled DataPacket.
* @param prioritise If true the packet will be sent before of any packets currently queued.
*/
template
<
typename
T
>
void
SendLabelledPacket
(
const
std
::
string
&
label
,
const
T
&
content
,
bool
prioritise
=
false
)
{
//TODO: try and catch.
std
::
string
contentAsString
=
boost
::
lexical_cast
<
std
::
string
>
(
content
);
SendLabelledPacket
(
label
,
reinterpret_cast
<
const
u8
*>
(
contentAsString
.
c_str
()),
contentAsString
.
length
(),
prioritise
);
}
/**
* Helper method to send a labeled DataPacket with a string as the content.
* @param prioritise If true the packet will be sent before of any packets currently queued.
*/
void
SendLabelledPacket
(
const
std
::
string
&
label
,
const
std
::
string
&
content
,
bool
prioritise
=
false
);
/**
* Helper method to send a labeled DataPacket with multiple strings as the content.
* @param prioritise If true the packet will be sent before of any packets currently queued.
*/
void
SendLabelledPacket
(
const
std
::
string
&
label
,
const
std
::
vector
<
std
::
string
>&
content
,
bool
prioritise
=
false
);
/**
* Attempts to receive data.
* Data received will be used to build DataPacket objects. When a full packet
* is received it will be added to the list of received packets. The number of
* packets available will be returned.
* This method will call _recv() then pass the return value into
* _HandleRecvError(). If _HandleRecvError() returns false and the _recv()
* return value is less than 0 then that value will be returned from this method,
* otherwise -1 will used to indicate an error. Positive return values from this
* method indicate the number of packets available.
* @note You do not normally need to call this method manually. The NetworkSystem
* managing the connection will call it and deal with firing callbacks.
* @note Error codes are system specific, which is why the handle methods are used.
* @return less than 0 on error, otherwise the number of complete packets available.
*/
int
Receive
();
/**
* Attempts to send data.
* This method will call _send() then pass the return value into _HandleWriteError().
* @note You do not normally need to call this method manually.
* @note Error codes are system specific, which is why the handle methods are used.
*/
void
Write
(
bool
reenable
);
/**
* Used to change the state of the connection flag.
* @note This is used by network systems and should not be used in attempt to connect
* or disconnect. Use the dedicated methods for that which will perform the desired
* action.
* @parm state The new state, if it is not connected the can send flag is set to false.
*/
void
SetState
(
State
state
);
bool
IsConnected
()
const
{
return
(
mState
==
States
::
CONNECTED
);}
/**
* Get whether the connection is in a connecting state or not.
*/
bool
GetConnecting
()
const
{
return
(
mState
==
States
::
CONNECTING
);}
const
ConnectionDetails
&
GetConnectionDetails
()
const
{
return
mConnectionDetails
;
}
void
SetConnectionDetails
(
const
ConnectionDetails
&
val
)
{
mConnectionDetails
=
val
;
}
/**
* Register a Packet Callback method for a labelled packet.
* Callbacks can be registered for incoming packets which will be called when the
* incoming packet is identified as a labelled packet.
* @param label The label in which to match a labelled incoming packet.
* @param callback The callback to call if the label matches the packet label.
*/
void
RegisterLabelledPacketCallback
(
const
std
::
string
&
label
,
LabelledPacketCallback
callback
);
/**
* Register a Packet Callback method for a packet.
* Callbacks can be registered for incoming packets which will be called when the
* incoming packet has the specified ID. This allows you to register callbacks for
* packets with different ids and not have to handle the use of the packet in
* ReceivedPacket.
* @note Some packet IDs are reserved, see PacketTypes for more information.
* @param packetID The id in which to match with the id of an incoming packet.
* @param callback The callback to call if the id matches the packet id.
*/
void
RegisterPacketCallback
(
u32
packetID
,
PacketCallback
callback
);
/**
* Register a "Connect" Callback method with an identifier.
* @note The callback will only be called if the callback is registered before the connection event.
* @note To remove the callback you need to reference the identifier. This is because boost functions cannot be compared.
* @param identifier The identifier in which to reference the registration.
* @param callback The callback to call when the connection connects.
*/
void
RegisterConnectCallback
(
const
std
::
string
&
identifier
,
ConnectCallback
callback
);
/**
* Register a "Disconnect" Callback method with an identifier.
* @note To remove the callback you need to reference the identifier. This is because boost functions cannot be compared.
* @param identifier The identifier in which to reference the registration.
* @param callback The callback to call when the connection connects.
*/
void
RegisterDisconnectCallback
(
const
std
::
string
&
identifier
,
DisconnectCallback
callback
);
/**
* Clear all labelled packet callbacks with corresponding label.
* @param label
*/
void
ClearLabelledPacketCallbacks
(
const
std
::
string
&
label
);
/**
* Clear all labelled packet callbacks.
*/
void
ClearAllLabelledPacketCallbacks
();
/**
* Clear all packet callbacks for corresponding packet ID.
* @param packetID
*/
void
ClearPacketIDCallbacks
(
u32
packetID
);
/**
* Clear all packet id callbacks that were registered with RegisterPacketCallback(u32,PacketCallback)
*/
void
ClearAllPacketIDCallbacks
();
/**
* Clear all labelled and packet ID callbacks.
*/
void
ClearAllPacketCallbacks
();
/**
* Clear connect callbacks corresponding to identifier.
* @param identifier
*/
void
ClearConnectCallbacks
(
const
std
::
string
&
identifier
);
/**
* Clear all of the connect callbacks.
*/
void
ClearAllConnectCallbacks
();
/**
* Clear disconnect callbacks corresponding to identifier.
* @param identifier
*/
void
ClearDisconnectCallbacks
(
const
std
::
string
&
identifier
);
/**
* Clear all of the disconnect callbacks.
* @param attemptReconnet
*/
void
ClearAllDisconnectCallbacks
();
/**
* Clear all callbacks.
*/
inline
void
ClearAllCallbacks
()
{
ClearAllPacketCallbacks
();
ClearAllConnectCallbacks
();
ClearAllDisconnectCallbacks
();
}
void
SetAutoAttemptReconnect
(
bool
attemptReconnet
){
mAutoAttemptReconnect
=
attemptReconnet
;}
bool
GetAutoAttemptReconnect
()
const
{
return
mAutoAttemptReconnect
;}
/**
* Set the auto reconnect time.
* @note The Connection will configure a CountDownTimer to process the reconnect. CountDownTimers
* are Tasks so they are updated during Kernel updates. This means that if an ExecutionModel that
* does not update regularly is in use (such as the NetworkExecutionModel) the auto reconnect time
* may turn out to be longer than what is configured in the Connection.
* @param seconds how long to wait before attempting to reconnect if the connection has disconnected.
*/
void
SetAutoAttemptReconnectTime
(
Seconds
seconds
);
/**
* This method will be called internally or by a network system to disconnect the connection.
* If the connection is connected then this method at the very minimum should:
* - Set the connection into the disconnected state using SetConnected(false) then;
* - call mManager.UpdateConnect(shared_from_this()) to notify the manager to process
* the dropped connection.
* @return true if the connection changed state to disconnect otherwise false the connection
* is already disconnected or if something prevents the connection from disconnecting.
*/
virtual
bool
_Disconnect
()
=
0
;
/**
* Check whether or not the remote host is big endian.
* @return true if the remote host is big endian, otherwise false to indicate little endian.
*/
bool
IsRemoteBigEndian
()
const
{
return
mIsRemoteBigEndian
;}
protected
:
static
bool
mPlatformBigEndian
;
NetworkManager
&
mNetworkManager
;
//Only the NetworkManager can clean up a connection
friend
class
NetworkManager
;
Connection
(
NetworkManager
&
manager
);
virtual
~
Connection
();
/**
* Called by NetworkManager after receiving remote details.
*/
void
SetRemoteBigEndian
(
bool
isBigEndian
)
{
mIsRemoteBigEndian
=
isBigEndian
;}
/**
* Process the remote details packet after initial connection.
*/
void
OnRemoteDetails
(
shared_ptr
<
Connection
>
connection
,
shared_ptr
<
DataPacket
>
dataPacket
);
void
SendHostDetails
();
shared_ptr
<
DataPacket
>
mHeaderPacket
;
shared_ptr
<
DataPacket
>
mCurrentPacket
;
ConnectionOwner
*
mOwner
;
static
const
u32
DATAPACKET_TEMPBUFFER_SIZE
=
16384
;
u8
mTempBuffer
[
DATAPACKET_TEMPBUFFER_SIZE
];
State
mState
;
bool
mCanSend
;
bool
mAutoAttemptReconnect
;
/// If true will attempt to automatically reconnect if the connection drops.
bool
mManualDisconnect
;
/// Used to determine whether we should automatically reconnect.
Mutex
mQueuedPacketsMutex
;
Mutex
mReceviedPacketsMutex
;
std
::
list
<
shared_ptr
<
DataPacket
>
>
mQueuedPackets
;
std
::
list
<
shared_ptr
<
DataPacket
>
>
mReceviedPackets
;
s32
mQueuedData
;
//Count of queued Data only packets
bool
mHeaderSent
;
//Flag: concerned with mQueuedPackets
bool
mIsRemoteBigEndian
;
/**
* Normally the implementation is just a wrapper around a send method.
* The method should be non-blocking.
* @return the number of bytes that have been sent or if there was an error,
* an error code less than 0.
*/
virtual
int
_send
(
const
u8
*
buf
,
int
len
,
int
flags
)
=
0
;
/**
* Normally the implementation is just a wrapper around a receive method.
* The method should be non-blocking.
* @return the number of bytes that have been recevied or if there was an error,
* an error code less than 0.
*/
virtual
int
_recv
(
u8
*
buf
,
int
len
,
int
flags
)
=
0
;
/**
* Handle errors from the call to _recv().
* The implementation should call _Disconnect() if there was an error that results
* in the connection becoming disconnected.
*/
virtual
bool
_HandleRecvError
(
int
code
)
=
0
;
/**
* Handle errors from the call to _send().
* The implementation should call _Disconnect() if there was an error that results
* in the connection becoming disconnected.
*/
virtual
bool
_HandleWriteError
(
int
code
)
=
0
;
virtual
void
_notifyOwner
(
shared_ptr
<
DataPacket
>
packet
);
/**
* Called to process dropped connections and notify the connection owner.
* @note This method is called by the NetworkManager.
*/
virtual
void
_dropped
();
/**
* Called to process dropped connections and notify the connection owner.
* @note This method is called by the NetworkManager when a connection is established.
*/
virtual
void
_established
();
/**
* Called to start a connection attempt.
* @return false if there were problems, otherwise true.
*/
virtual
bool
_Connect
()
=
0
;
ConnectionDetails
mConnectionDetails
;
CountDownTimer
mReconnectTimer
;
static
const
u32
mUnreasonableDataSize
;
//Data size we consider to be unreasonable.
private
:
std
::
map
<
u32
,
std
::
vector
<
PacketCallback
>
>
mPacketCallbacks
;
std
::
map
<
std
::
string
,
std
::
vector
<
LabelledPacketCallback
>
>
mLabelledPacketCallbacks
;
std
::
map
<
std
::
string
,
std
::
vector
<
ConnectCallback
>
>
mConnectCallbacks
;
std
::
map
<
std
::
string
,
std
::
vector
<
DisconnectCallback
>
>
mDisconnectCallbacks
;
void
ProcessReceivedPacket
(
shared_ptr
<
DataPacket
>
packet
);
void
ProcessLabelledPacket
(
shared_ptr
<
Connection
>
connection
,
shared_ptr
<
DataPacket
>
packet
);
};
}
#endif
File Metadata
Details
Attached
Mime Type
text/x-c++
Expires
Thu, Jan 16, 1:14 AM (7 h, 12 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
72116
Default Alt Text
Connection.h (17 KB)
Attached To
Mode
rEE Echo 3
Attached
Detach File
Event Timeline
Log In to Comment