1 /*---------------------------------------------------------------------------*
2   Project:  Horizon
3   File:     rdt_SenderImpl.cpp
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 #include "rdt_SenderImpl.h"
19 
20 #include <nn/rdt/CTR/rdt_define.h>
21 #include <nn/rdt/CTR/rdt_Result.h>
22 
23 #include "rdt_Stopwatch.h"
24 
25 #include "Test.h"
26 
27 
28 namespace
29 {
30 
31 }  // End of anonymous namespace
32 
33 
34 namespace nn { namespace rdt { namespace CTR {
35 
36 
37 // Base class for "state."
38 class SenderStateBase{
39 public:
~SenderStateBase(void)40     virtual ~SenderStateBase(void){}
41 
42     virtual void initialize(SenderImpl *pSender); // Called when this state begins
43     virtual void finalize  (SenderImpl *pSender); // Called when this state ends
44     void update    (SenderImpl *pSender);
45     virtual void updatePrologue   (SenderImpl *pSender);
46     virtual void updateCore       (SenderImpl *pSender);
47     virtual void updateEpilogue   (SenderImpl *pSender);
48     virtual enum SenderState getStatus(void) const = 0;
49 
50 protected:
SenderStateBase(void)51     SenderStateBase(void){}
52 };
53 
54 
initialize(SenderImpl * pSender)55 void SenderStateBase::initialize(SenderImpl *pSender)
56 {
57     (void)pSender;
58 }
59 
60 
finalize(SenderImpl * pSender)61 void SenderStateBase::finalize(SenderImpl *pSender)
62 {
63     (void)pSender;
64 }
65 
66 
updatePrologue(SenderImpl * pSender)67 void SenderStateBase::updatePrologue(SenderImpl *pSender)
68 {
69     (void)pSender;
70 }
71 
72 
updateCore(SenderImpl * pSender)73 void SenderStateBase::updateCore(SenderImpl *pSender)
74 {
75     (void)pSender;
76 }
77 
78 
updateEpilogue(SenderImpl * pSender)79 void SenderStateBase::updateEpilogue(SenderImpl *pSender)
80 {
81     (void)pSender;
82 }
83 
84 
update(SenderImpl * pSender)85 void SenderStateBase::update(SenderImpl *pSender)
86 {
87     updatePrologue(pSender);
88     updateCore(pSender);
89     updateEpilogue(pSender);
90 }
91 
92 
93 class SenderStateOpenRequested : public SenderStateBase{
94 public:
95     static SenderStateBase* getInstance(void);
96 
97     virtual void updateCore(SenderImpl *pSender);
98     virtual enum SenderState getStatus(void) const;
99 
100 protected:
SenderStateOpenRequested(void)101     SenderStateOpenRequested(void){}
102 };
103 
104 
105 class SenderStateOpening : public SenderStateBase{
106 public:
107     static SenderStateBase* getInstance(void);
108 
109     virtual void updateCore(SenderImpl *pSender);
110     virtual enum SenderState getStatus(void) const;
111 
112 protected:
SenderStateOpening(void)113     SenderStateOpening(void){}
114 };
115 
116 
117 class SenderStateOpened : public SenderStateBase{
118 public:
119     static SenderStateBase* getInstance(void);
120 
121     virtual void updateCore(SenderImpl *pSender);
122     virtual enum SenderState getStatus(void) const;
123 
124 protected:
SenderStateOpened(void)125     SenderStateOpened(void){}
126 };
127 
128 
129 class SenderStateCloseRequested : public SenderStateBase{
130 public:
131     static SenderStateBase* getInstance(void);
132 
133     virtual void updateCore(SenderImpl *pSender);
134     virtual enum SenderState getStatus(void) const;
135 
136 protected:
SenderStateCloseRequested(void)137     SenderStateCloseRequested(void){}
138 };
139 
140 
141 class SenderStateClosing : public SenderStateBase{
142 public:
143     static SenderStateBase* getInstance(void);
144 
145     virtual void updateCore(SenderImpl *pSender);
146     virtual enum SenderState getStatus(void) const;
147 
148 protected:
SenderStateClosing(void)149     SenderStateClosing(void){}
150 };
151 
152 
153 class SenderStateClosed : public SenderStateBase{
154 public:
155     static SenderStateBase* getInstance(void);
156 
157     virtual void initialize(SenderImpl *pSender);
158     virtual void updateCore(SenderImpl *pSender);
159     virtual enum SenderState getStatus(void) const;
160 
161 protected:
SenderStateClosed(void)162     SenderStateClosed(void){}
163 };
164 
165 
166 // Below is the implementation of the State derived class.
getInstance(void)167 SenderStateBase* SenderStateClosed::getInstance(void)
168 {
169     static SenderStateClosed s_instance;
170     return &s_instance;
171 }
172 
173 
getStatus(void) const174 enum SenderState SenderStateClosed::getStatus(void) const
175 {
176     return SENDER_STATE_CLOSED;
177 }
178 
179 
initialize(SenderImpl * pSender)180 void SenderStateClosed::initialize(SenderImpl *pSender)
181 {
182     ASSERT(pSender!=NULL);
183 
184     pSender->clear();
185 }
186 
187 
updateCore(SenderImpl * pSender)188 void SenderStateClosed::updateCore(SenderImpl *pSender)
189 {
190     ASSERT(pSender!=NULL);
191 
192     // Respond with RST to segments without RST that were received during CLOSED state
193     Segment seg;
194     if(pSender->pullSegment(&seg).IsSuccess() && !seg.IsRst())
195     {
196 #if 0
197         LOG("The Sender is in a CLOSED state, but because the segment was received, responds with RST. \n");
198         LOG("The received segment contains \n.");
199         seg.PrintDebugInfo();
200         LOG("   \n");
201         const u32 SEQ = 0;
202         pSender->sendRstSegment(SEQ);
203 #else
204         LOG("Sender is in CLOSED state, but received segment.  Ignored.\n");
205 #endif
206     }
207 }
208 
209 
getInstance(void)210 SenderStateBase* SenderStateOpenRequested::getInstance(void)
211 {
212     static SenderStateOpenRequested s_instance;
213     return &s_instance;
214 }
215 
216 
getStatus(void) const217 enum SenderState SenderStateOpenRequested::getStatus(void) const
218 {
219     return SENDER_STATE_OPEN_REQUESTED;
220 }
221 
222 
updateCore(SenderImpl * pSender)223 void SenderStateOpenRequested::updateCore(SenderImpl *pSender)
224 {
225     // Send connection request segment
226     pSender->sendSynSegment();
227 
228     // Go to the next state.
229     pSender->setNextState(SenderStateOpening::getInstance());
230 }
231 
232 
getInstance(void)233 SenderStateBase* SenderStateOpening::getInstance(void)
234 {
235     static SenderStateOpening s_instance;
236     return &s_instance;
237 }
238 
239 
getStatus(void) const240 enum SenderState SenderStateOpening::getStatus(void) const
241 {
242     return SENDER_STATE_OPENING;
243 }
244 
245 
updateCore(SenderImpl * pSender)246 void SenderStateOpening::updateCore(SenderImpl *pSender)
247 {
248     ASSERT(pSender!=NULL);
249 
250     // Check content of the received segment.
251     Segment seg;
252     if(pSender->pullSegment(&seg).IsSuccess())
253     {
254         pSender->processReceivedSegment(seg);
255 
256         if(seg.IsRst())
257         {
258             // Check if the RST is for this SYN. If not, discard segment.
259             if(seg.IsAck() && seg.GetAckNumber()==pSender->getInitialSequenceNumber()+1)
260             {
261                 // Treat as though the SYN was refused. To CLOSED.
262                 LOG("SYN rejected.  CLOSED... ack of segment = %u\n", seg.GetAckNumber());
263                 pSender->setNextState(SenderStateClosed::getInstance());
264                 pSender->errorHandling(ResultResetReceived());
265                 return;
266             }
267             else
268             {
269                 LOG("Ignored RST segment.\n");
270             }
271         }
272         else if(seg.IsAck())
273         {
274             if(seg.GetAckNumber()==pSender->getInitialSequenceNumber()+1)
275             {
276                 // Transition to next state because an ACK was received for the SYN.
277                 pSender->setNextState(SenderStateOpened::getInstance());
278             }
279             else
280             {
281                 LOG("ack : %u\n", seg.GetAckNumber());
282                 LOG("una : %u\n", pSender->getUnacknowledgeNumber());
283                 LOG("nxt : %u\n", pSender->getNextSequenceNumber());
284                 LOG("It seems that it isn't ACK for SYN.  Ignored\n");
285             }
286         }
287     }
288 
289     // Resend process.
290     pSender->processResending();
291 }
292 
293 
getInstance(void)294 SenderStateBase* SenderStateOpened::getInstance(void)
295 {
296     static SenderStateOpened s_instance;
297     return &s_instance;
298 }
299 
300 
getStatus(void) const301 enum SenderState SenderStateOpened::getStatus(void) const
302 {
303     return SENDER_STATE_OPENED;
304 }
305 
306 
updateCore(SenderImpl * pSender)307 void SenderStateOpened::updateCore(SenderImpl *pSender)
308 {
309     ASSERT(pSender!=NULL);
310 
311     // Check content of the received segment.
312     Segment seg;
313     if(pSender->pullSegment(&seg).IsSuccess())
314     {
315         pSender->processReceivedSegment(seg);
316 
317         if(seg.IsRst())
318         {
319             // Because it was RST, goes to CLOSED.
320             pSender->setNextState(SenderStateClosed::getInstance());
321             pSender->errorHandling(ResultResetReceived());
322             return;
323         }
324     }
325 
326     bool bSent = false;  // Set to TRUE if the send process has been executed.
327 
328     // Resend process.
329     bSent = pSender->processResending();
330 
331     // A chance for data transmission if the send process has not occurred even once.
332     if(!bSent)
333     {
334         if(!pSender->isSendBufferEmpty())
335         {
336             pSender->sendData();
337             bSent = true;
338         }
339     }
340 }
341 
342 
getInstance(void)343 SenderStateBase* SenderStateCloseRequested::getInstance(void)
344 {
345     static SenderStateCloseRequested s_instance;
346     return &s_instance;
347 }
348 
349 
getStatus(void) const350 enum SenderState SenderStateCloseRequested::getStatus(void) const
351 {
352     return SENDER_STATE_CLOSE_REQUESTED;
353 }
354 
355 
updateCore(SenderImpl * pSender)356 void SenderStateCloseRequested::updateCore(SenderImpl *pSender)
357 {
358     ASSERT(pSender!=NULL);
359 
360     // Check content of the received segment. Around this is the same as the Opened state.
361     Segment seg;
362     if(pSender->pullSegment(&seg).IsSuccess())
363     {
364         pSender->processReceivedSegment(seg);
365 
366         if(seg.IsRst())
367         {
368             // Because it was RST, goes to CLOSED.
369             pSender->setNextState(SenderStateClosed::getInstance());
370             pSender->errorHandling(ResultResetReceived());
371             return;
372         }
373     }
374 
375     bool bSent = false;  // Set to TRUE if the send process has been executed.
376 
377     // Resend process.
378     bSent = pSender->processResending();
379 
380     if(pSender->isSendBufferEmpty())
381     {
382         // Send FIN segment
383         if(!bSent)
384         {
385             pSender->sendFinSegment();
386             bSent = true;
387 
388             // To CLOSING state.
389             pSender->setNextState(SenderStateClosing::getInstance());
390         }
391     }
392     else
393     {
394         // Releases the send buffer data
395         if(!bSent)
396         {
397             pSender->sendData();
398             bSent = true;
399         }
400     }
401 
402     // A chance for data transmission if the send process has not occurred even once.
403     if(!bSent)
404     {
405         if(!pSender->isSendBufferEmpty())
406         {
407             pSender->sendData();
408             bSent = true;
409         }
410     }
411 }
412 
413 
getInstance(void)414 SenderStateBase* SenderStateClosing::getInstance(void)
415 {
416     static SenderStateClosing s_instance;
417     return &s_instance;
418 }
419 
420 
getStatus(void) const421 enum SenderState SenderStateClosing::getStatus(void) const
422 {
423     return SENDER_STATE_CLOSING;
424 }
425 
426 
updateCore(SenderImpl * pSender)427 void SenderStateClosing::updateCore(SenderImpl *pSender)
428 {
429     ASSERT(pSender!=NULL);
430 
431     // Resend process.
432     pSender->processResending();
433 
434     // Check content of the received segment.
435     Segment seg;
436     if(pSender->pullSegment(&seg).IsSuccess())
437     {
438         pSender->processReceivedSegment(seg);
439 
440         if(seg.IsRst())
441         {
442             // Because it was RST, goes to CLOSED.
443             pSender->setNextState(SenderStateClosed::getInstance());
444             pSender->errorHandling(ResultResetReceived());
445             return;
446         }
447         else if(seg.IsAck() && seg.GetAckNumber()==pSender->m_sendBuffer.GetCurrentSequenceNumber()+1)
448         {
449             // Check content of the received segment. (FIN check.)
450             // Because an ACK was received for the FIN, goes to CLOSED.
451             pSender->setNextState(SenderStateClosed::getInstance());
452         }
453         else
454         {
455             VERBOSE("Although a segment was received, it does not seem to be an ACK segment to FIN. Destroy. \n");
456         }
457     }
458 }
459 
460 
461 
462 //
SenderImpl(void)463 SenderImpl::SenderImpl(void) throw()
464      :m_initialized(false)
465 {
466 }
467 
468 
469 //
~SenderImpl(void)470 SenderImpl::~SenderImpl(void)
471 {
472     Finalize();
473 }
474 
475 
476 #ifdef _WIN32
Initialize(SOCKET sock,void * pSendBuf,u16 sendBufSize)477 nn::Result SenderImpl::Initialize(SOCKET sock, void *pSendBuf, u16 sendBufSize)
478 #else
479 nn::Result SenderImpl::Initialize(u16 nodeId, u8 port, void *pSendBuf, u16 sendBufSize)
480 #endif
481 {
482     if(m_initialized)
483     {
484         return ResultAlreadyInitialized();
485     }
486     else
487     {
488         if(pSendBuf==NULL)
489         {
490             return ResultNullPointer();
491         }
492 
493         if(sendBufSize==0)
494         {
495             return ResultInvalidSize();
496         }
497 
498 #ifdef _WIN32
499         nn::Result result = HostBase::Initialize(sock);
500 #elif defined(NN_PLATFORM_CTR)
501         nn::Result result = HostBase::Initialize(nodeId, port);
502 #endif
503         if(result.IsFailure())
504         {
505             return result;
506         }
507         else
508         {
509             m_sendBuffer.Initialize(pSendBuf, sendBufSize);
510             m_pState     = SenderStateClosed::getInstance();
511             m_pNextState = NULL;
512 
513             clear();
514 
515             m_initialized = true;
516             return ResultSuccess();
517         }
518     }
519 }
520 
521 
Finalize(void)522 void SenderImpl::Finalize(void)
523 {
524     if(m_initialized)
525     {
526         m_initialized = false;
527         m_sendBuffer.Finalize();
528         HostBase::Finalize();
529     }
530     else
531     {
532         // Do nothing.
533     }
534 }
535 
536 
Process(void)537 nn::Result SenderImpl::Process(void)
538 {
539     ASSERT(m_initialized);
540 
541     // The update function according to the state
542     if(m_pState)
543     {
544         m_pState->update(this);
545     }
546 
547     // State Transitions
548     changeState();
549 
550     // For debugging
551     //    PrintDebugInfo();
552 
553     // Errors are returned here.
554     // If returned, errors are reset.
555     nn::Result ret = GetErrorCode();
556     errorHandling(ResultSuccess());
557     return ret;
558 }
559 
560 
Open(void)561 nn::Result SenderImpl::Open(void)
562 {
563     ASSERT(m_initialized);
564 
565     if(GetStatus()==SENDER_STATE_CLOSED)
566     {
567         setNextState(SenderStateOpenRequested::getInstance());
568         changeState();
569         return ResultSuccess();
570     }
571     else
572     {
573         return ResultUntimelyFunctionCall();
574     }
575 }
576 
577 
Close(void)578 nn::Result SenderImpl::Close(void)
579 {
580     ASSERT(m_initialized);
581 
582     if(GetStatus()==SENDER_STATE_OPENED)
583     {
584         setNextState(SenderStateCloseRequested::getInstance());
585         changeState();
586         return ResultSuccess();
587     }
588     else
589     {
590         // Error if the Close function is called while in a CLOSED state.
591         // This behavior follows the TCP RFC, and this behavior is also included here.
592         return ResultUntimelyFunctionCall();
593     }
594 }
595 
596 
Send(const void * pBuf,size_t bufSize)597 nn::Result SenderImpl::Send(const void *pBuf, size_t bufSize)
598 {
599     ASSERT(m_initialized);
600 
601     if(pBuf==NULL)
602     {
603         return ResultNullPointer();
604     }
605 
606     if(bufSize==0)
607     {
608         return ResultDoNothing();
609     }
610 
611     if(GetStatus()!=SENDER_STATE_OPENED)
612     {
613         return ResultUntimelyFunctionCall();
614     }
615 
616     if(m_sendBuffer.Push(pBuf, bufSize))
617     {
618         return ResultSuccess();
619     }
620     else
621     {
622         return ResultSendBufferIsNotAvailable();
623     }
624 }
625 
626 
Cancel(void)627 void SenderImpl::Cancel(void)
628 {
629     ASSERT(m_initialized);
630 
631     // Cancel processes execute immediately without waiting for the Process function.
632     // This way of implementing error handling might be easier for the application to use.
633     //
634 
635     // RST transmission
636     sendRstSegment(m_sendBuffer.GetCurrentSequenceNumber());
637 
638     // Immediately to Closed state.
639     setNextState(SenderStateClosed::getInstance());
640     changeState();
641 }
642 
643 
GetStatus(void) const644 enum SenderState SenderImpl::GetStatus(void) const
645 {
646     ASSERT(m_initialized);
647     ASSERT(m_pState!=NULL);
648 
649     return m_pState->getStatus();
650 }
651 
652 
processResending(void)653 bool SenderImpl::processResending(void)
654 {
655     Segment seg;
656     // Either a segment that had met a timeout was found in the queue, or such a segment was found and is in a state to wait for the sending of the remaining segments to complete.
657     //
658     //
659     if(m_resendQueue.IsResendMode())
660     {
661         bool ret = m_resendQueue.Front(&seg);
662         ASSERT(ret);
663         VERBOSE("Execute the new send or resend process. \n");
664         VERBOSE("The send segment sequence number is: %d. \n", seg.GetSeqNumber());
665         putSegment(seg);
666 
667         static detail::Stopwatch s_sp("ResendQueue::TryAgain()");
668         s_sp.Start();
669         m_resendQueue.TryAgain();  // Sends the first request in the queue to the end.
670         s_sp.Stop();
671         return true;
672     }
673     else
674     {
675         return false;
676     }
677 }
678 
679 
sendData(void)680 void SenderImpl::sendData(void)
681 {
682     if(m_sendBuffer.IsEmpty())
683     {
684         VERBOSE("The send buffer was empty, so the send process is not run. \n");
685         return;
686     }
687 
688     u32 unackDataSize = m_resendQueue.GetTotalDataSize();
689     if(unackDataSize >= m_remoteWindowSize)
690     {
691         VERBOSE("The unconfirmed received data is larger than the receive window size, so the data send is skipped. \n");
692         return;
693     }
694 
695     if(m_resendQueue.IsFull())
696     {
697         VERBOSE("The resend queue is full, so the send process is not run. \n");
698         return;
699     }
700 
701     size_t vacant = m_remoteWindowSize - unackDataSize;
702     size_t pullSize = min(Segment::PAYLOAD_SIZE, vacant);  // Amount taken from the send buffer.
703     ASSERT(pullSize > 0);
704 
705     // The data send process.
706     Segment seg;
707     seg.ClearHeader();
708     u32 seq = 0;
709 
710     // Runs the process to pack data in the segment.
711     size_t sz = m_sendBuffer.Pull(seg.payload, &seq, pullSize);
712     ASSERT(sz > 0);
713 
714     // To get to here, the send process must be guaranteed to have been run (that is, the resend queue must have space).
715     //
716     seg.header.dataLength = sz;
717     seg.SetSeqNumber(seq);
718     putSegmentWithResend(seg);
719 }
720 
721 
sendSynSegment(void)722 void SenderImpl::sendSynSegment(void)
723 {
724     Segment seg;
725     seg.ClearHeader();
726     seg.SetSeqNumber(getInitialSequenceNumber());
727     seg.SetSyn();
728     putSegmentWithResend(seg);
729 }
730 
731 
sendFinSegment(void)732 void SenderImpl::sendFinSegment(void)
733 {
734     ASSERTMSG(m_sendBuffer.IsEmpty(), "You cannot request FIN if send buffer is not empty.");
735 
736     VERBOSE("sendFinSegment() called.\n");
737 
738     Segment seg;
739     seg.ClearHeader();
740     seg.SetFin();
741     seg.SetSeqNumber(m_sendBuffer.GetCurrentSequenceNumber());
742     putSegmentWithResend(seg);
743 }
744 
745 
clear(void)746 void SenderImpl::clear(void)
747 {
748     m_resendQueue.Clear();
749     m_remoteWindowSize = 0;
750 #if 1
751     m_iss = static_cast<u32>(0xffffffff & GetCurrentTimeAsMillisecond());
752 #else
753     m_iss = 0xffffffff - 100;
754 #endif
755     m_sendBuffer.Clear(m_iss);
756     m_una = m_iss;
757     m_nxt = m_iss;
758 
759     m_arrivals = 0;
760 }
761 
762 
isValidAckNumber(u32 ack) const763 bool SenderImpl::isValidAckNumber(u32 ack) const
764 {
765     s32 s32_ack = static_cast<s32>(ack);
766     s32 s32_una = static_cast<s32>(getUnacknowledgeNumber());
767     s32 s32_nxt = static_cast<s32>(getNextSequenceNumber());
768 
769     // The permission ACK inequality expresses snd.una < seg.ack <= snd.nxt.
770     if((0 <= s32_una - s32_ack) || (0 < s32_ack - s32_nxt))
771     {
772         return false;
773     }
774     else
775     {
776         return true;
777     }
778 }
779 
780 
781 
782 // State Transitions. Do nothing in particular if the next state is not set.
changeState(void)783 void SenderImpl::changeState(void)
784 {
785     if(m_pNextState)
786     {
787         if(m_pState)
788         {
789             m_pState->finalize(this);
790         }
791         m_pState = m_pNextState;
792         m_pNextState = NULL;
793         m_pState->initialize(this);
794     }
795 }
796 
797 
setNextState(SenderStateBase * p)798 void SenderImpl::setNextState(SenderStateBase *p)
799 {
800     ASSERT(p!=NULL);
801     ASSERT(m_pNextState==NULL);
802 
803     m_pNextState = p;
804 }
805 
806 
putSegmentWithResend(const Segment & seg)807 void SenderImpl::putSegmentWithResend(const Segment &seg)
808 {
809     // As long as the resend queue is full, reliable communication is not possible.
810     ASSERT(!m_resendQueue.IsFull());
811 
812     putSegment(seg);
813 
814     // All segments depend on being resend targets.
815     // If the SYN segment is removed from the resend target, it will not work.
816     //
817     m_nxt = seg.GetLastSeqNumber() + 1;
818 
819     // Place a segment in the resend queue.
820     // The sender must resend if an "arrival" cannot be confirmed.
821     // The receiver does not track whether its response is received by the sender.
822     // If the receiver's response is not received by the sender, the sender must resend.
823     bool ret = m_resendQueue.Push(seg);
824     if(!ret)
825     {
826         errorHandling(ResultResendQueueIsFull());
827         PANIC("It seems that resend queue in RDT library is full.");
828     }
829 }
830 
831 
processReceivedSegment(const Segment & seg)832 void SenderImpl::processReceivedSegment(const Segment &seg)
833 {
834     // The processes that must be run when a segment arrives are summarized here.
835     //
836 
837     ++m_arrivals;
838 
839     // ACK field check
840     if(seg.IsAck())
841     {
842         const u32 ack = seg.GetAckNumber();
843         if(isValidAckNumber(ack))
844         {
845             m_una = ack;
846 
847             // Packets for which distribution can be confirmed can be deleted from the resend queue.
848             VERBOSE("ACK number %d was received. \n", ack);
849             m_resendQueue.Remove(ack);
850 
851             // Update window size
852             m_remoteWindowSize = seg.GetWindowSize();
853         }
854         else
855         {
856             VERBOSE("una : %d\n", getUnacknowledgeNumber());
857             VERBOSE("nxt : %d\n", getNextSequenceNumber());
858             VERBOSE("ACK number is not valid or has already been received. (%u)\n", ack);
859         }
860     }
861 }
862 
863 
PrintDebugInfo(void) const864 void SenderImpl::PrintDebugInfo(void) const
865 {
866     ASSERT(m_initialized);
867 
868     m_resendQueue.PrintDebugInfo();
869     m_sendBuffer.PrintDebugInfo();
870     LOG("m_remoteWindowSize: %d\n", m_remoteWindowSize);
871     LOG("m_arrivals: %u\n", m_arrivals);
872 }
873 
874 
PrintProperty(void)875 void SenderImpl::PrintProperty(void)
876 {
877     LOG("m_sendBuffer: %d (%d)\n",       offsetof(SenderImpl, m_sendBuffer), sizeof(SendBuffer));
878     LOG("m_remoteWindowSize: %d (%d)\n", offsetof(SenderImpl, m_remoteWindowSize), sizeof(u16));
879     LOG("m_resendQueue: %d (%d)\n",      offsetof(SenderImpl, m_resendQueue), sizeof(ResendQueue));
880     LOG("m_pState: %d (%d)\n",           offsetof(SenderImpl, m_pState), sizeof(SenderStateBase*));
881     LOG("m_pNextState: %d (%d)\n",       offsetof(SenderImpl, m_pNextState), sizeof(SenderStateBase*));
882     LOG("m_arrivals: %d (%d)\n",         offsetof(SenderImpl, m_arrivals), sizeof(u32));
883 
884     LOG("sizeof(SenderImpl)=%ld\n", (long) sizeof(SenderImpl));
885 }
886 
887 
888 // This stand-alone test aims to be a test that can be run without a Receiver, but it is pending.
889 //
Test(void)890 void SenderImpl::Test(void)
891 {
892     /*
893     const int BUFSIZE = 1024;
894     char buf[BUFSIZE];
895     SenderImpl s;
896     const int SUCCESS = 0;
897     CU_ASSERT(s.GetStatus()==SENDER_STATE_CLOSED);
898     CU_ASSERT(s.Open()==SUCCESS);
899     for(int i=0; i10; ++i)
900     {
901         CU_ASSERT(s.Process()==SUCCESS);
902         CU_ASSERT(s.GetStatus()==SENDER_STATE_OPENING);
903         SleepCurrentThread(50);
904     }
905     CU_ASSERT(s.Cancel()==SUCCESS);
906     while(1)
907     {
908         CU_ASSERT(s.Process()==SUCCESS);
909         CU_ASSERT(s.GetStatus()==SENDER_STATE_CLOSED);
910         SleepCurrentThread(50);
911     }
912 
913 
914 
915 
916 */
917 }
918 
919 
920 }}} // namespace nn::rdt::CTR
921