1 /*--------------------------------------------------------------------------
2   Project:  HorizonSDK
3   File:     rdt_HostBase.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:: 2010-09-16#$
11   $Rev: 26004 $
12   $Author: hiratsu_daisuke $
13  *-------------------------------------------------------------------------
14 
15 
16 */
17 
18 #include "stdafx.h"
19 
20 #include "rdt_HostBase.h"
21 
22 #include "rdt_Utility.h"
23 
24 #include <cstdlib>  // For rand function.
25 
26 #include <nn/rdt/CTR/rdt_Result.h>
27 
28 
29 namespace
30 {
31 
32 }  // End of anonymous namespace
33 
34 namespace nn { namespace rdt { namespace CTR {
35 
36 
HostBase(void)37 HostBase::HostBase(void)
38      :m_initialized(false)
39 {
40 }
41 
42 
43 //
~HostBase(void)44 HostBase::~HostBase(void)
45 {
46     Finalize();
47 }
48 
49 
Initialize(SOCKET & sock)50 nn::Result HostBase::Initialize(
51 #ifdef _WIN32
52     SOCKET &sock
53 #elif defined(NN_PLATFORM_CTR)
54     u16 nodeId,
55     u8 port
56 #endif
57     )
58 {
59     if(m_initialized)
60     {
61         return ResultAlreadyInitialized();
62     }
63     else
64     {
65         nn::Result result = m_transceiver.Initialize(
66 #ifdef _WIN32
67             sock
68 #elif defined(NN_PLATFORM_CTR)
69             nodeId,
70             port
71 #endif
72             );
73 
74         // If srand function is not executed with CTR, the values obtained with rand function were all 0.
75         std::srand(1234);
76 
77         if(result.IsFailure())
78         {
79             return result;
80         }
81         else
82         {
83             m_packetLossRatio = 0;
84             m_resultCode      = ResultSuccess();
85             m_initialized     = true;
86             return ResultSuccess();
87         }
88     }
89 }
90 
91 
Finalize(void)92 void HostBase::Finalize(void)
93 {
94     if(m_initialized)
95     {
96         m_initialized = false;
97         m_transceiver.Finalize();
98     }
99     else
100     {
101         // Do nothing.
102     }
103 }
104 
105 
SetPacketLossRatio(int per)106 void HostBase::SetPacketLossRatio(int per)
107 {
108     ASSERT(m_initialized);
109     ASSERT((0<=per) && (per<=100));
110 
111     m_packetLossRatio = per;
112 }
113 
114 
PrintProperty(void)115 void HostBase::PrintProperty(void)
116 {
117     LOG("m_transceiver: %d (%d)\n",     offsetof(HostBase, m_transceiver), sizeof(Transceiver));
118     LOG("m_packetLossRatio: %d (%d)\n", offsetof(HostBase, m_packetLossRatio), sizeof(int));
119     LOG("m_resultCode: %d (%d)\n",      offsetof(HostBase, m_resultCode), sizeof(Result));
120 
121     LOG("sizeof(HostBase)=%ld\n", (long) sizeof(HostBase));
122 }
123 
124 
putSegment(const Segment & seg)125 void HostBase::putSegment(const Segment &seg)
126 {
127     // Perform packet loss emulation here.
128     // When there are no packet loss settings, the following was written because we did not want high-cost residue calculations performed.
129     //
130     int r = (m_packetLossRatio==0) ? 100 : std::rand()%100;
131 
132     if(r >= m_packetLossRatio)
133     {
134         nn::Result result = m_transceiver.Put(seg);
135         if(result.IsFailure())
136         {
137             errorHandling(result);
138         }
139 #if 0
140         LOG("Sent segment is:\n");
141         seg.PrintDebugInfo();
142 #endif
143     }
144     else
145     {
146         LOG("Packet loss happened!  Lost segment is:\n");
147         seg.PrintDebugInfo();
148     }
149 }
150 
151 
pullSegment(Segment * pSeg)152 nn::Result HostBase::pullSegment(Segment *pSeg)
153 {
154     ASSERT(pSeg!=NULL);
155 
156     nn::Result result = m_transceiver.Pull(pSeg);
157     if(result.IsFailure() && result!=ResultNoData())
158     {
159         errorHandling(result);
160     }
161     return result;
162 }
163 
164 
sendRstSegment(u32 seq)165 void HostBase::sendRstSegment(u32 seq)
166 {
167     VERBOSE("%s called.\n", __FUNCTION__);
168 
169     Segment seg;
170     seg.ClearHeader();
171     seg.SetRst();
172     seg.SetSeqNumber(seq);
173     putSegment(seg);
174 }
175 
176 
sendRstAckSegment(u32 seq,u32 ack)177 void HostBase::sendRstAckSegment(u32 seq, u32 ack)
178 {
179     VERBOSE("%s called.\n", __FUNCTION__);
180 
181     Segment seg;
182     seg.ClearHeader();
183     seg.SetRst();
184     seg.SetSeqNumber(seq);
185     seg.SetAckNumber(ack);
186     putSegment(seg);
187 }
188 
189 
errorHandling(Result resultCode)190 void HostBase::errorHandling(Result resultCode)
191 {
192     if(resultCode.IsFailure())
193     {
194         LOG("Failure result code will be set...\n");
195     }
196 
197     m_resultCode = resultCode;
198 }
199 
200 
201 }}} // namespace nn::rdt::CTR
202