1 /*---------------------------------------------------------------------------*
2   Project:  Horizon
3   File:     rdt_Utility.h
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 #ifndef NN_LIBRARIES_RDT_CTR_RDT_UTILITY_H_
19 #define NN_LIBRARIES_RDT_CTR_RDT_UTILITY_H_
20 
21 
22 #ifdef _WIN32
23 #include <stdio.h>
24 #include <stdlib.h>
25 #include "types.h"
26 #include <time.h>
27 #else
28 #include <nn/types.h>
29 #endif
30 
31 #include <nn/rdt/CTR/rdt_Misc.h>
32 
33 /* Please see man pages for details
34 
35 */
36 
37 #ifdef _WIN32
38 #define PRINTF printf
39 #else
40 #define PRINTF NN_LOG
41 #endif
42 
43 
infinite_loop(void)44 inline void infinite_loop(void)
45 {
46 #if defined(NN_BUILD_NOOPT) || defined(NN_BUILD_VERBOSE)
47     while(1)
48     {
49     }
50 #else
51     // Do nothing. (Release build)
52 #endif
53 }
54 
55 
56 #define WARNING(exp) (void) ((exp) || (nn::rdt::CTR::GetLogLevel()==nn::rdt::CTR::LOG_LEVEL_NONE) || \
57                                   (PRINTF("WARNING: %s line: %d\n", __FILE__, __LINE__), \
58                                   0))
59 
60 
61 #define WARNINGMSG(exp, ...) (void) ((exp) || (nn::rdt::CTR::GetLogLevel()==nn::rdt::CTR::LOG_LEVEL_NONE) ||  \
62                                   (PRINTF("WARNING: %s line: %d ", __FILE__, __LINE__), \
63                                    PRINTF(__VA_ARGS__),                                 \
64                                    PRINTF("\n"),                                        \
65                                   0))
66 
67 #define PANIC(...) (void) (PRINTF("PANIC: %s line: %d ", __FILE__, __LINE__), \
68                            PRINTF(__VA_ARGS__),                               \
69                            PRINTF("\n"),                                      \
70                            infinite_loop()/*abort()*/)
71 
72 #define ASSERT(exp) (void) ((exp) || \
73                              (PRINTF("ASSERT: %s line: %d\n", __FILE__, __LINE__), \
74                               infinite_loop() /*abort()*/,                         \
75                               0))
76 
77 
78 
79 #define ASSERTMSG(exp, ...) (void) ((exp) || \
80                                     (PRINTF("ASSERTMSG: %s line: %d ", __FILE__, __LINE__), \
81                                      PRINTF(__VA_ARGS__),                                   \
82                                      PRINTF("\n"),                                          \
83                                      infinite_loop() /*abort()*/,                           \
84                                      0))
85 
86 #define LOG(...) if(nn::rdt::CTR::GetLogLevel()==nn::rdt::CTR::LOG_LEVEL_ALL)(void) (PRINTF(__VA_ARGS__))
87 
88 #define VERBOSE(...) (void)(0)
89 
90 
91 #ifdef _WIN32
92 #define ALIGN_ASSERT(exp, align) ASSERTMSG( ((uptr)(exp)) % (align) == 0, "%s must be %d byte aligned.", #exp, align )
93 #elif defined(NN_PLATFORM_CTR)
94 #define ALIGN_ASSERT(exp, align) NN_ALIGN_ASSERT(exp, align)
95 #endif
96 
97 //#define alignof(type) ((int)offsetof(struct { char top; type bot; }, bot))
98 template <class T>
99 class Align{
100 public:
Align(void)101     Align(void)
102     {
103         struct S{
104             char top;  // Just want a 1-byte variable.
105             T    t;
106         };
107 
108         LOG("offset: %d\n", offsetof(S, t));
109     }
110 };
111 
112 
113 namespace nn { namespace rdt { namespace CTR {
114 
115 // Forward declaration
116 class Sender;
117 class Receiver;
118 
119 // Perform network preparation and cleanup.
120 // Aims to achieve a state where data transmission can occur.
121 void SetupNetwork  (void);
122 void CleanupNetwork(void);
123 
124 // Create and destroy instances. Use Destroy function to destroy the pointers returned by Create group functions.
125 Sender*   CreateSender   (u16 port, void *pSendBuf, u16 sendBufSize);
126 void      DestroySender  (Sender *s);
127 
128 Receiver* CreateReceiver (u16 port, void *pRecvBuf, u16 recvBufSize);
129 void      DestroyReceiver(Receiver *r);
130 
131 // Thread idle. Difference between Windows environment and CTR environment is eliminated with internal implementation.
132 void SleepCurrentThread(s32 msec);
133 
134 
135 // Use when the pointer to the buffer is the NULL pointer.
MakeNullPointerResult(void)136 inline nn::Result MakeNullPointerResult(void)
137 {
138     return MakeUsageResult(
139         Result::SUMMARY_INVALID_ARGUMENT,
140         Result::MODULE_NN_RDT,
141         Result::DESCRIPTION_INVALID_POINTER);
142 }
143 
144 
145 // Use when the argument indicating the buffer size is zero.
MakeZeroSizeResult(void)146 inline nn::Result MakeZeroSizeResult(void)
147 {
148     return MakeUsageResult(
149         Result::SUMMARY_INVALID_ARGUMENT,
150         Result::MODULE_NN_RDT,
151         Result::DESCRIPTION_INVALID_SIZE);
152 }
153 
154 
155 // Use when the state is not one in which a function should be called.
MakeInvalidState(void)156 inline nn::Result MakeInvalidState(void)
157 {
158     return MakeStatusResult(
159         Result::SUMMARY_INVALID_STATE,
160         Result::MODULE_NN_RDT,
161         Result::DESCRIPTION_INVALID_RESULT_VALUE);  //  Value is not appropriate?
162 }
163 
164 
165 // Return value of an unimplemented function....
MakeNotImplemented(void)166 inline nn::Result MakeNotImplemented(void)
167 {
168     return MakeFatalResult(
169         Result::SUMMARY_INTERNAL,
170         Result::MODULE_NN_RDT,
171         Result::DESCRIPTION_NOT_IMPLEMENTED);
172 }
173 
174 
175 // Failure in resource allocation
MakeResourceAllocationFailure(void)176 inline nn::Result MakeResourceAllocationFailure(void)
177 {
178     return MakeStatusResult(
179         Result::SUMMARY_OUT_OF_RESOURCE,
180         Result::MODULE_NN_RDT,
181         Result::DESCRIPTION_OUT_OF_MEMORY);   // Would like a DESCRIPTION of the case when resources other than memory are insufficient...
182 }
183 
184 
185 // Returns when initialization is attempted in a state where initialization has been completed.
MakeAlreadyInitialized(void)186 inline nn::Result MakeAlreadyInitialized(void)
187 {
188         return MakeInfoResult(
189             Result::SUMMARY_NOTHING_HAPPENED,
190             Result::MODULE_NN_RDT,
191             Result::DESCRIPTION_ALREADY_INITIALIZED);
192 }
193 
194 
195 // When RST is received from a remote site, this error code notifies the user of that fact.
MakeResetReceived(void)196 inline nn::Result MakeResetReceived(void)
197 {
198         return MakeReInitResult(
199             Result::SUMMARY_CANCELLED,            //
200             Result::MODULE_NN_RDT,
201             Result::DESCRIPTION_CANCEL_REQUESTED);  //
202 }
203 
204 
205 // Error when the connection is lost.
MakeDisconnected(void)206 inline nn::Result MakeDisconnected(void)
207 {
208         return MakeReInitResult(
209             Result::SUMMARY_OUT_OF_RESOURCE,
210             Result::MODULE_NN_RDT,
211             Result::DESCRIPTION_NOT_FOUND);       //
212 }
213 
214 
215 // When there is no received segment (not yet received).
MakeNoData(void)216 inline nn::Result MakeNoData(void)
217 {
218     return MakeTemporaryResult(
219         Result::SUMMARY_NOT_FOUND,
220         Result::MODULE_NN_RDT,
221         Result::DESCRIPTION_NO_DATA);
222 }
223 
224 
225 // Used when there is a slight concern about it, but not so much as to have an error declaration.
MakeNothingHappened(void)226 inline nn::Result MakeNothingHappened(void)
227 {
228         return MakeInfoResult(
229             Result::SUMMARY_NOTHING_HAPPENED,
230             Result::MODULE_NN_RDT,
231             Result::DESCRIPTION_SUCCESS);
232 }
233 
234 #ifdef _WIN32
235 // Runs setup and cleanup for server sockets. For Windows.
236 // Runs the listen and accept functions, and other processes, and waits until a state in which data can be sent and received is reached.
237 //
238 SOCKET SetupServerSide(u16 port);
239 void CleanupServerSide(SOCKET sock);
240 
241 // Runs setup and cleanup for client sockets.
242 // Runs the connect function, and other processes, and waits until a state in which data can be sent and received is reached.
243 //
244 SOCKET SetupClientSide(u16 port);
245 void CleanupClientSide(SOCKET sock);
246 
247 // Returns the port numbers that can be used.
248 u16 GetAvailablePort(void);
249 
250 // Millisecond type.
251 typedef clock_t MSEC_T;
252 MSEC_T GetCurrentTimeAsMillisecond(void);
253 
254 #else
255 template <class T>
min(T a,T b)256 T min(T a, T b)
257 {
258     return a < b ? a : b;
259 }
260 
261 template <class T>
max(T a,T b)262 T max(T a, T b)
263 {
264     return a > b ? a : b;
265 }
266 
267 
268 // Millisecond type.
269 typedef s64 MSEC_T;
270 MSEC_T GetCurrentTimeAsMillisecond(void);
271 
272 
273 void PrintResultCode(nn::Result r);
274 
275 #endif // end of _WIN32
276 
277 
278 // At the time this function is called, it gets how much stack is being consumed.
279 void stackChecker(void);
280 
281 
282 }}} // namespace nn::rdt::CTR
283 
284 #endif  // end of NN_LIBRARIES_RDT_CTR_RDT_UTILITY_H_
285