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