1 /*---------------------------------------------------------------------------*
2 Project: Horizon
3 File: Parent.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: 47228 $
14 *---------------------------------------------------------------------------*/
15
16 #include <string.h>
17 #include <nn.h>
18 #include <nn/fs.h>
19 #include <nn/dlp.h>
20 #include <nn/types.h>
21 #include <nn/dbg.h>
22 #include <nn/nstd/nstd_String.h>
23
24 #include <nn/os/os_Memory.h>
25 #include <nn/os/os_MemoryTypes.h>
26 #include <nn/fnd/fnd_ExpHeap.h>
27
28 #include <nn/gx.h>
29
30 #include "dlpDemo.h"
31 #include "demo.h"
32
33 enum ParentState
34 {
35 NOT_INITIALIZED, // Uninitialized state
36 MASTER, // Communicate as Master
37 ERROR // Entered sleep or Wi-Fi OFF mode
38 };
39
40 const int GL_MEMORY_SIZE = 0x800000;
41
42 struct NodeData
43 {
44 u16 nodeId; //
45 char name[11]; //
46 NN_PADDING3;
47 };
48
49
50 static u16 s_NodeNum;
51 static NodeData s_NodeData[nn::uds::NODE_MAX];
52
DoParent(u16 childNum,const char passphrase[])53 void DoParent(u16 childNum, const char passphrase[])
54 {
55 DLP_DEBUG_PRINT("Parent start\n");
56
57 nn::Result result;
58 nn::uds::EndpointDescriptor ed;
59 ParentState state = NOT_INITIALIZED;
60 uptr heapForGx;
61 nn::os::Event statusUpdateEvent;
62 size_t sendCount;
63 char tmpPassphrase[nn::dlp::MAX_CHILD_UDS_PASSPHRASE_LENGTH];
64
65 static demo::RenderSystemDrawing s_RenderSystem;
66 static nn::fnd::ExpHeap s_AppHeap;
67 static bit8 s_UdsReceiveBuffer[4096*20] NN_ATTRIBUTE_ALIGN(4096);
68
69 nn::nstd::MemCpy(tmpPassphrase, passphrase, sizeof(tmpPassphrase));
70 tmpPassphrase[nn::dlp::MAX_CHILD_UDS_PASSPHRASE_LENGTH - 1] = '\0';
71
72 // Initialize hid
73 NN_UTIL_PANIC_IF_FAILED(nn::hid::Initialize());
74
75 // Create heap
76 s_AppHeap.Initialize(nn::os::GetDeviceMemoryAddress(),
77 nn::os::GetDeviceMemorySize() );
78 heapForGx = reinterpret_cast<uptr>(s_AppHeap.Allocate(GL_MEMORY_SIZE));
79
80 // Allocates 8 MB memory in FCRAM for graphics
81 s_RenderSystem.Initialize(heapForGx, GL_MEMORY_SIZE);
82
83 s_RenderSystem.SetClearColor(NN_GX_DISPLAY0, 0.0f, 0.0f, 0.0f, 0.0f);
84 s_RenderSystem.SetClearColor(NN_GX_DISPLAY1, 0.0f, 0.0f, 0.0f, 0.0f);
85
86 nn::hid::PadReader padReader;
87 nn::hid::PadStatus padStatus;
88
89 while(true)
90 {
91 s_RenderSystem.SetRenderTarget(NN_GX_DISPLAY1);
92 s_RenderSystem.Clear();
93 s_RenderSystem.SetFontSize(FONT_SIZE);
94 s_RenderSystem.SetColor(1.0f, 1.0f, 1.0f);
95
96 padReader.ReadLatest(&padStatus);
97
98 switch( state )
99 {
100 case NOT_INITIALIZED:
101 {
102 s_RenderSystem.DrawText(0, 0, "Create network");
103 s_NodeNum = 0;
104 sendCount = 0;
105 ::std::memset(s_NodeData, 0, sizeof(s_NodeData));
106
107 if ((result = nn::uds::Initialize( &statusUpdateEvent, s_UdsReceiveBuffer, sizeof(s_UdsReceiveBuffer))).IsFailure())
108 {
109 DLP_DEBUG_POINT;
110 }
111
112 DLP_DEBUG_PRINT("Passphrase : %s \n", tmpPassphrase);
113 if ((result = nn::uds::CreateNetwork(SUB_ID, childNum + 1, nn::uds::CreateLocalCommunicationId(UNIQUE_ID_SAMPLEDEMOS_DLP), tmpPassphrase, strlen(tmpPassphrase))).IsFailure())
114 {
115 DLP_DEBUG_POINT;
116 }
117 if ((result = nn::uds::CreateEndpoint(&ed)).IsFailure())
118 {
119 DLP_DEBUG_POINT;
120 }
121
122 if (result.IsFailure())
123 {
124 DLP_DEBUG_POINT;
125 NN_DBG_PRINT_RESULT(result);
126 state = ERROR;
127 }
128 else
129 {
130 DLP_DEBUG_POINT;
131 state = MASTER;
132 }
133 } break;
134
135 case MASTER:
136 {
137 if (statusUpdateEvent.WaitOne(nn::fnd::TimeSpan::FromSeconds(0)))
138 {
139 nn::uds::ConnectionStatus connectionStatus;
140 NN_UTIL_PANIC_IF_FAILED(nn::uds::GetConnectionStatus(&connectionStatus));
141
142 if( connectionStatus.nowState != nn::uds::STATE_MASTER)
143 {
144 DLP_DEBUG_PRINT("Leave Network (Reason:%d)\n", connectionStatus.disconnectReason);
145 state = ERROR;
146 }
147 else
148 {
149 DLP_DEBUG_POINT;
150
151 for(int i = 0;i < nn::uds::NODE_MAX; i++) //List all nodes
152 {
153 if( connectionStatus.updateNodeBitmap&(0x0001 << i ) )
154 {
155 if( connectionStatus.nodeIdList[i] != 0 ) //New connection
156 {
157 nn::uds::NodeInformation nodeInfo;
158
159 if(nn::uds::GetNodeInformation( &nodeInfo, connectionStatus.nodeIdList[i] ).IsSuccess())
160 {
161 DLP_DEBUG_POINT;
162 //Get name
163 char name[12];
164 if( nodeInfo.userName.isNgUserName == true )
165 {
166 // If the user name is a profanity word, change to ***********
167 std::memset(name, '*', 11);
168 }
169 else
170 {
171 std::wcstombs(name, nodeInfo.userName.userName, 11);
172 }
173 name[11] = NULL;
174 s_NodeData[i].nodeId = connectionStatus.nodeIdList[i];
175 std::memcpy(s_NodeData[i].name, name, sizeof(name));
176 DLP_DEBUG_PRINT("Connect! ID:%d, name:%s\n", connectionStatus.nodeIdList[i], name);
177 s_NodeNum ++;
178 }
179 else
180 {
181 DLP_DEBUG_POINT;
182 state = ERROR;
183 break;
184 }
185 }
186 else //Disconnect
187 {
188 DLP_DEBUG_PRINT("Disconnect! ID:%d\n", s_NodeData[i].nodeId);
189 state = ERROR;
190 break;
191 }
192 }
193 }
194 }
195 }
196
197 s_RenderSystem.DrawText(0, 0, "Node num : %2d/%2d", s_NodeNum, childNum + 1);
198 s_RenderSystem.DrawText(0, 1 * FONT_SIZE, "------------------------------------------");
199
200 int j = 0;
201 for (int i = 0; i < nn::uds::NODE_MAX; i++)
202 {
203 if (s_NodeData[i].nodeId)
204 {
205 s_RenderSystem.DrawText(0, (2 + j) * FONT_SIZE, "%02d : %s", s_NodeData[i].nodeId, s_NodeData[i].name);
206 j ++;
207 }
208
209 }
210 } break;
211
212 case ERROR: // If the system enters sleep or Wi-Fi OFF mode during this, UDS must be initialized again.
213 {
214 s_RenderSystem.DrawText(0, 0, "(Error) Press A to restart");
215 if(padStatus.trigger & nn::hid::BUTTON_A)
216 {
217 DLP_DEBUG_POINT;
218 nn::uds::CTR::DestroyEndpoint(&ed);
219 nn::uds::DestroyNetwork();
220 nn::uds::Finalize();
221 state = NOT_INITIALIZED;
222 }
223 }break;
224 }
225
226 s_RenderSystem.SwapBuffers();
227
228 //Display the communication status
229 s_RenderSystem.SetRenderTarget(NN_GX_DISPLAY0);
230 s_RenderSystem.Clear();
231
232 if (state == MASTER)
233 {
234 if (s_NodeNum >= (childNum + 1))
235 {
236 if (nn::uds::SendTo(ed, &sendCount, sizeof(sendCount), nn::uds::BROADCAST_NODE_ID, 1, nn::uds::NO_WAIT).IsSuccess())
237 {
238 sendCount ++;
239 }
240 s_RenderSystem.DrawText(0, 0, "Sending packet : %08x", sendCount);
241
242 }
243 }
244
245 s_RenderSystem.SwapBuffers();
246 s_RenderSystem.WaitVsync(NN_GX_DISPLAY_BOTH);
247
248 }
249 }
250
251
252