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