1 /*---------------------------------------------------------------------------*
2   Project:  Horizon
3   File:     rdt_SenderImpl.h
4 
5   Copyright (C)2009-2012 Nintendo Co., Ltd.  All rights reserved.
6 
7   These coded instructions, statements, and computer programs contain
8   proprietary information of Nintendo of America Inc. and/or Nintendo
9   Company Ltd., and are protected by Federal copyright law.  They may
10   not be disclosed to third parties or copied or duplicated in any form,
11   in whole or in part, without the prior written consent of Nintendo.
12 
13   $Rev: 46347 $
14  *---------------------------------------------------------------------------*/
15 
16 #include "stdafx.h"
17 
18 #ifndef NN_LIBRARIES_RDT_CTR_RDT_SENDER_IMPL_H_
19 #define NN_LIBRARIES_RDT_CTR_RDT_SENDER_IMPL_H_
20 
21 #include "rdt_HostBase.h"
22 #include "rdt_SendBuffer.h"
23 #include "rdt_ResendQueue.h"
24 #include "rdt_Segment.h"
25 
26 namespace nn { namespace rdt { namespace CTR {
27 
28 // Forward declaration
29 class SenderStateBase;
30 
31 
32 /* Please see man pages for details
33 
34 */
35 class SenderImpl : public HostBase{
36 public:
37 /* Please see man pages for details
38 
39 */
40     SenderImpl(void) throw();
41 
42 /* Please see man pages for details
43 
44 */
45    virtual ~SenderImpl(void);
46 
47 /* Please see man pages for details
48 
49 */
50 #ifdef _WIN32
51     nn::Result Initialize(SOCKET sock, void *pSendBuf, u16 sendBufSize);
52 #elif defined(NN_PLATFORM_CTR)
53     nn::Result Initialize(u16 nodeId, u8 port, void *pSendBuf, u16 sendBufSize);
54 #endif
55 
56 /* Please see man pages for details
57 
58 */
59     void Finalize(void);
60 
61 /* Please see man pages for details
62 
63 
64 
65 */
66     nn::Result Open(void);
67 
68 /* Please see man pages for details
69 
70 
71 
72 */
73     nn::Result Close(void);
74 
75 /* Please see man pages for details
76 
77 
78 
79 
80 
81 */
82     nn::Result Send(const void *pBuf, size_t bufSize);
83 
84 /* Please see man pages for details
85 
86 
87 */
88     nn::Result Process(void);
89 
90 /* Please see man pages for details
91 
92 */
93     void Cancel(void);
94 
95 /* Please see man pages for details
96 
97 */
98     enum SenderState GetStatus(void) const;
99 
100 
101 /* Please see man pages for details
102 
103 */
new(size_t size,void * pBuf)104     static void* operator new(size_t size, void *pBuf) throw()
105     {
106         if(size!=sizeof(SenderImpl))
107         {
108             PANIC("Wrong size.\n");
109             return NULL;
110         }
111 
112         if(pBuf==NULL)
113         {
114             PANIC("NULL pointer is detected.\n");
115             return NULL;
116         }
117 
118         ALIGN_ASSERT(pBuf, 8);
119 
120         return pBuf;
121     }
122 
123     // 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.
124     //
125     // Found an explanation that supports the above, so left without defining delete.
126     // A Warning is given in the RealView compiler.
127     // Define delete, but do not call it.
128     // If you use SenderImp, you must explicitly call the destructor.
129 
130     // C++ Labyringth (http://www.fides.dti.ne.jp/~oka-t/cpplab-placement-new-2.html)
131     // If both this and operator delete (void *p) are defined, then operator delete (void *p) is called.
132     //
133     //
134     // This is probably a result of honoring compatibility with earlier specifications.
135 
delete(void * p)136     static void  operator delete (void *p) throw()
137     {
138         PANIC("Do not call this delete!  Please call destructor manually.\n");
139         (void)p;
140     }
141 
142 
143 /* Please see man pages for details
144 
145 */
146     void PrintDebugInfo(void) const;
147 
148 /* Please see man pages for details
149 
150 */
151     static void PrintProperty(void);
152 
153 /* Please see man pages for details
154 
155 */
156     static void Test(void);
157 
158 
159 private:
160 /* Please see man pages for details
161 
162 */
163     SenderImpl           (const SenderImpl&);
164 
165 /* Please see man pages for details
166 
167 */
168     SenderImpl& operator=(const SenderImpl&);
169 
170 
171     // Private function group.
172     void changeState(void);                // Calling this function causes a state transition.
173     void setNextState(SenderStateBase *p); // Set the next state.
174 
175     void putSegmentWithResend(const Segment &seg);
176 
177     // The received segment is passed to seg.
178     // The shared processes for the received segment are collected in this function.
179     //
180     void processReceivedSegment(const Segment &seg);
181 
182     // Runs a series of resend processes.
183     // TRUE is returned when the segment resend is performed.
184     // FALSE if it is not performed.
185     bool processResending(void);
186 
187     // Runs the cancel process.
188     void processCanceling(void);
189 
190     // When data collects in the send buffer, enough data is drawn out to fit in one segment and is then sent.
191     //
192     void sendData(void);
193 
194     // Create and send a segment containing a SYN request.
195     void sendSynSegment(void);
196 
197     // Create and send a segment containing a FIN request.
198     // This segment must be called when the send buffer is empty.
199     void sendFinSegment(void);
200 
201     // Is the send buffer empty?
isSendBufferEmpty(void)202     bool isSendBufferEmpty(void) const { return m_sendBuffer.IsEmpty(); }
203 
204     // Assumes that it is called when the Closed state is entered.
205     // Except for the members that maintain a state in the State pattern, all member variables are restored to the new state.
206     //
207     void clear(void);
208 
209     // Gets ISS (initial sequence number).
getInitialSequenceNumber(void)210     u32 getInitialSequenceNumber(void) const { return m_iss; }
211 
212     // Gets the oldest sequence number of the unconfirmed, received octet.
getUnacknowledgeNumber(void)213     u32 getUnacknowledgeNumber(void) const { return m_una; }
214 
215     // Sequence number of the octet to be sent next.
getNextSequenceNumber(void)216     u32 getNextSequenceNumber(void) const { return m_nxt; }
217 
218     // Is the ACK received remotely legitimate?
219     bool isValidAckNumber(u32 ack) const;
220 
221     // Member variables.
222     SendBuffer    m_sendBuffer;       // Send buffer
223     u16           m_remoteWindowSize; // Most recent information of the window size for which notification was made from the remote side.
224     bool          m_initialized;
225     u8            m_padding;          // Padding
226     u32           m_iss;              // Initial sequence number.
227     u32           m_una;              // Oldest of the sequence numbers that have arrived and are unconfirmed.
228     u32           m_nxt;              // Sequence number of the octet that should be sent next.
229     ResendQueue   m_resendQueue;      // Resend queue (requires 8-byte alignment).
230 
231     // State pattern implementation.
232     SenderStateBase *m_pState;
233     SenderStateBase *m_pNextState;
234     friend class SenderStateOpenRequested;
235     friend class SenderStateOpening;
236     friend class SenderStateOpened;
237     friend class SenderStateCloseRequested;
238     friend class SenderStateClosing;
239     friend class SenderStateClosed;
240 
241     // Debug variables.
242     u32           m_arrivals;    // Number of segments that have arrived.
243 
244     // Because the SenderImpl class is also dragged along in the ResendQueue alignment, padding is required here.
245     //
246     u8            m_padding2[4];
247 };
248 
249 }}} // namespace nn::rdt::CTR
250 
251 #endif  // end of NN_LIBRARIES_RDT_CTR_RDT_SENDER_IMPL_H_
252