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