1 /*--------------------------------------------------------------------------
2   Project:  HorizonSDK
3   File:     rdt_HostBase.cpp
4 
5   Copyright 2009 Nintendo.  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   $Date:: 2010-09-16#$
14   $Rev: 26004 $
15   $Author: hiratsu_daisuke $
16  *-------------------------------------------------------------------------*/
17 
18 #include "stdafx.h"
19 
20 #include "rdt_HostBase.h"
21 
22 #include "rdt_Utility.h"
23 
24 #include <cstdlib>  // rand()用。
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         // TORIAEZU。CTRでsrand()を実行しないと、rand()で得られる値がオール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     // パケロスのエミュレーションはここで行う。
128     // パケロス設定が無いときに、高コストな剰余計算を
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