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 is no packet loss setting, a high-cost surplus calculation cannot be performed, so the following is written.
124     //
125     // Note that if an appropriate type is not set with srand() in advance, the value acquired with rand() will be all zeros, so be careful.
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