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_RDT_SENDERIMPL_H_
19 #define NN_RDT_SENDERIMPL_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 placement delete has been written, if it is called the same as delete(m_pImpl, m_workBuf), it seems that the global delete(void *p) is called for some reason.
124     //
125     // Found some descriptions to reinforce the above explanation on the Web, so decided not to define the delete and leave it alone.
126     // However, a Warning is given in the RealView compiler with this.
127     // As a result, decided to at least define it. But do not call it.
128     // If you use SenderImpl call the destructor explicitly.
129 
130     // C++ Labyringth (http://www.fides.dti.ne.jp/~oka-t/cpplab-placement-new-2.html)
131     // If both are defined using "operator delete( void *p )", "operator delete( void *p )" is called. This is described in the C++ standards doc, but not very clearly.
132     //
133     //
134     //  Maybe compatibility with the old spec is being emphasized.
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 executes 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     // Executes the series of resend processes.
183     // Returns true when the segment is resent.
184     // Returns false when it is not resent.
185     bool processResending(void);
186 
187     // Executes the cancel process.
188     void processCanceling(void);
189 
190     // If the send buffer is full, the amount of data that can fit in one segment is removed and sent.
191     //
192     void sendData(void);
193 
194     // Create and send segment including the SYN request.
195     void sendSynSegment(void);
196 
197     // Create and send segment including the FIN request.
198     // This function must be called with the send buffer in an empty condition.
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 system enters the Closed state.
205     // Excluding members maintaining a state for the State pattern, each member variable is restored to a 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 octet for which arrival is unconfirmed
getUnacknowledgeNumber(void)213     u32 getUnacknowledgeNumber(void) const { return m_una; }
214 
215     // Sequence number of the octet to send next
getNextSequenceNumber(void)216     u32 getNextSequenceNumber(void) const { return m_nxt; }
217 
218     // Is the ACK received from the remote site valid?
219     bool isValidAckNumber(u32 ack) const;
220 
221     // Member variable group.
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 sequence number of the sequence numbers for which arrival is not confirmed
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     // Applies State pattern.
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;    // Segment arrival count
243 
244     // Padding may be required here because the SenderImpl class is shifted by the ResendQueue alignment
245     //
246     u8            m_padding2[4];
247 };
248 
249 }}} // namespace nn::rdt::CTR
250 
251 #endif  // end of NN_RDT_SENDERIMPL_H_
252