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