/*---------------------------------------------------------------------------* Project: Horizon File: rdt_SenderImpl.h Copyright (C)2009-2012 Nintendo Co., Ltd. All rights reserved. These coded instructions, statements, and computer programs contain proprietary information of Nintendo of America Inc. and/or Nintendo Company Ltd., and are protected by Federal copyright law. They may not be disclosed to third parties or copied or duplicated in any form, in whole or in part, without the prior written consent of Nintendo. $Rev: 46347 $ *---------------------------------------------------------------------------*/ #include "stdafx.h" #ifndef NN_LIBRARIES_RDT_CTR_RDT_SENDER_IMPL_H_ #define NN_LIBRARIES_RDT_CTR_RDT_SENDER_IMPL_H_ #include "rdt_HostBase.h" #include "rdt_SendBuffer.h" #include "rdt_ResendQueue.h" #include "rdt_Segment.h" namespace nn { namespace rdt { namespace CTR { // Forward declaration class SenderStateBase; /* Please see man pages for details */ class SenderImpl : public HostBase{ public: /* Please see man pages for details */ SenderImpl(void) throw(); /* Please see man pages for details */ virtual ~SenderImpl(void); /* Please see man pages for details */ #ifdef _WIN32 nn::Result Initialize(SOCKET sock, void *pSendBuf, u16 sendBufSize); #elif defined(NN_PLATFORM_CTR) nn::Result Initialize(u16 nodeId, u8 port, void *pSendBuf, u16 sendBufSize); #endif /* Please see man pages for details */ void Finalize(void); /* Please see man pages for details */ nn::Result Open(void); /* Please see man pages for details */ nn::Result Close(void); /* Please see man pages for details */ nn::Result Send(const void *pBuf, size_t bufSize); /* Please see man pages for details */ nn::Result Process(void); /* Please see man pages for details */ void Cancel(void); /* Please see man pages for details */ enum SenderState GetStatus(void) const; /* Please see man pages for details */ static void* operator new(size_t size, void *pBuf) throw() { if(size!=sizeof(SenderImpl)) { PANIC("Wrong size.\n"); return NULL; } if(pBuf==NULL) { PANIC("NULL pointer is detected.\n"); return NULL; } ALIGN_ASSERT(pBuf, 8); return pBuf; } // Although a placement delete was coded as if called as in delete(m_pImpl, m_workBuf), for some reason, it ran as if a global delete(void *p) was called. // // Found an explanation that supports the above, so left without defining delete. // A Warning is given in the RealView compiler. // Define delete, but do not call it. // If you use SenderImp, you must explicitly call the destructor. // C++ Labyringth (http://www.fides.dti.ne.jp/~oka-t/cpplab-placement-new-2.html) // If both this and operator delete (void *p) are defined, then operator delete (void *p) is called. // // // This is probably a result of honoring compatibility with earlier specifications. static void operator delete (void *p) throw() { PANIC("Do not call this delete! Please call destructor manually.\n"); (void)p; } /* Please see man pages for details */ void PrintDebugInfo(void) const; /* Please see man pages for details */ static void PrintProperty(void); /* Please see man pages for details */ static void Test(void); private: /* Please see man pages for details */ SenderImpl (const SenderImpl&); /* Please see man pages for details */ SenderImpl& operator=(const SenderImpl&); // Private function group. void changeState(void); // Calling this function causes a state transition. void setNextState(SenderStateBase *p); // Set the next state. void putSegmentWithResend(const Segment &seg); // The received segment is passed to seg. // The shared processes for the received segment are collected in this function. // void processReceivedSegment(const Segment &seg); // Runs a series of resend processes. // TRUE is returned when the segment resend is performed. // FALSE if it is not performed. bool processResending(void); // Runs the cancel process. void processCanceling(void); // When data collects in the send buffer, enough data is drawn out to fit in one segment and is then sent. // void sendData(void); // Create and send a segment containing a SYN request. void sendSynSegment(void); // Create and send a segment containing a FIN request. // This segment must be called when the send buffer is empty. void sendFinSegment(void); // Is the send buffer empty? bool isSendBufferEmpty(void) const { return m_sendBuffer.IsEmpty(); } // Assumes that it is called when the Closed state is entered. // Except for the members that maintain a state in the State pattern, all member variables are restored to the new state. // void clear(void); // Gets ISS (initial sequence number). u32 getInitialSequenceNumber(void) const { return m_iss; } // Gets the oldest sequence number of the unconfirmed, received octet. u32 getUnacknowledgeNumber(void) const { return m_una; } // Sequence number of the octet to be sent next. u32 getNextSequenceNumber(void) const { return m_nxt; } // Is the ACK received remotely legitimate? bool isValidAckNumber(u32 ack) const; // Member variables. SendBuffer m_sendBuffer; // Send buffer u16 m_remoteWindowSize; // Most recent information of the window size for which notification was made from the remote side. bool m_initialized; u8 m_padding; // Padding u32 m_iss; // Initial sequence number. u32 m_una; // Oldest of the sequence numbers that have arrived and are unconfirmed. u32 m_nxt; // Sequence number of the octet that should be sent next. ResendQueue m_resendQueue; // Resend queue (requires 8-byte alignment). // State pattern implementation. SenderStateBase *m_pState; SenderStateBase *m_pNextState; friend class SenderStateOpenRequested; friend class SenderStateOpening; friend class SenderStateOpened; friend class SenderStateCloseRequested; friend class SenderStateClosing; friend class SenderStateClosed; // Debug variables. u32 m_arrivals; // Number of segments that have arrived. // Because the SenderImpl class is also dragged along in the ResendQueue alignment, padding is required here. // u8 m_padding2[4]; }; }}} // namespace nn::rdt::CTR #endif // end of NN_LIBRARIES_RDT_CTR_RDT_SENDER_IMPL_H_