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