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_RDT_UTILITY_H_
19 #define NN_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; // Only 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 // Performs network preparation and cleanup.
120 // Purpose is to keep until the state where data transmission can be done.
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 // Used when the pointer to the buffer is a 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 // Used when the argument displaying buffer length 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 // Used when not in a state in which functions 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 a 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 as a case 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 arrived yet).
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 // Executes setup and cleanup of server-side socket. For Windows only.
236 // The implementation calls listen(), accept(), and other processes to prepare for the sending and receiving of data.
237 //
238 SOCKET SetupServerSide(u16 port);
239 void CleanupServerSide(SOCKET sock);
240
241 // Executes setup and cleanup of client-side socket.
242 // The implementation calls connect() and other processes to prepare to send and receive data.
243 //
244 SOCKET SetupClientSide(u16 port);
245 void CleanupClientSide(SOCKET sock);
246
247 // Returns the port number that can be used.
248 u16 GetAvailablePort(void);
249
250 // Millisecond format.
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 format.
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 // When this function was called, gets how much of the stack was consumed.
279 void stackChecker(void);
280
281
282 }}} // namespace nn::rdt::CTR
283
284 #endif // end of NN_RDT_UTILITY_H_
285