1 /*---------------------------------------------------------------------------*
2   Project:  Horizon
3   File:     cec_Main.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 <nn.h>
17 #include <nn/fs.h>
18 #include <nn/os.h>
19 #include <nn/dbg.h>
20 #include <ctype.h>
21 
22 #include <nn/cec.h>
23 #include <nn/ndm.h>
24 #include <nn/applet.h>
25 #include "sleep.h"
26 
27 using namespace nn;
28 using namespace nn::fnd;
29 using namespace nn::os;
30 
31 static bool    threadAlive = false;
32 static Event recvEvent;
33 
34 
35 u32   TEST_TITLEID  =     nn::cec::MakeCecTitleId(0x12233) ;   // StreetPass ID (a fixed value)
36                                                 //  (created from a 20-bit unique ID)
37 u32   TEST_PRIVATEID  =   0xaabbccdd  ;   // Card-specific ID (a different value for each card and for each instance of save data)
38 char  TEST_HMACKEY[]  =   "12345678901234567890123456789012"  ;
39 
40 
41 //------------------------------------------------------------
42 // Allocator used by the CEC library
43 class CecTestAllocator : public nn::fnd::IAllocator
44 {
45 private:
46     nn::fnd::ExpHeap expHeap;
47     bool            isInitialized;
48     NN_PADDING3;
49 
50 public:
CecTestAllocator()51     CecTestAllocator(){isInitialized = false;};
~CecTestAllocator()52     virtual ~CecTestAllocator(){};
53 
InitExpHeap()54     void InitExpHeap()
55     {
56         if(isInitialized == false)
57         {
58             expHeap.Initialize(
59                         nn::os::GetDeviceMemoryAddress(),
60                         1024 * 1024 );
61             isInitialized = true;
62         }
63     }
64 
65     /* Please see man pages for details
66 
67     */
Allocate(size_t size,s32 alignment=4)68     virtual void* Allocate(size_t size, s32 alignment = 4)
69     {
70         if(isInitialized == true)
71         {
72             return expHeap.Allocate(size, alignment);
73         }
74         return NULL;
75     }
76 
77     /* Please see man pages for details
78 
79     */
Free(void * p)80     virtual void Free(void* p)
81     {
82         if(isInitialized == true)
83         {
84             expHeap.Free(p);
85         }
86     }
87 
88 };
DateParam2Str(char * outStr,nn::fnd::DateTimeParameters date)89 void DateParam2Str(char* outStr, nn::fnd::DateTimeParameters date)
90 {
91     char tmpStr[32] = {0};
92     s32 strLen = 0;
93 
94     strLen = nn::nstd::TSPrintf(tmpStr, "%04d/%02d/%02d(%d) %02d:%02d:%02d.%04d",
95         date.year, date.month, date.day, date.week, date.hour, date.minute, date.second, date.milliSecond);
96     std::memcpy(outStr, tmpStr, strLen);
97 }
98 
99 
100 CecTestAllocator allocator;
101 
102 //------------------------------------------------------------
103 
104 
BinaryDump(u8 * data,u32 len,u8 type)105 void BinaryDump(u8* data, u32 len, u8 type)
106 {
107     u32 i, j;
108     NN_LOG("   Len[%d]----------\n   ", len);
109     for (i=0; i<len; i++)
110     {
111         char charprint[16];
112         NN_LOG(" %02x", data[i]);
113         if(type == 1 && i%16==7)
114         {
115             // Add spaces
116             NN_LOG(" ");
117         }
118         charprint[i%16] = data[i];
119         if(i%16==15){
120             NN_LOG(" ");
121             for(j=0; j<sizeof(charprint); j++)
122             {
123                 if(j%8==0){
124                     // Add a space every eight characters
125                     NN_LOG(" ");
126                 }
127                 if(type == 1 )
128                 {
129                     // Display the character
130                     if(isprint(charprint[j])){
131                         NN_LOG("%c", charprint[j]);
132                     }else{
133                         // If it cannot be display, use "."
134                         NN_LOG(".");
135                     }
136                 }
137             }
138             NN_LOG("\n   ");
139         }
140     }
141     NN_LOG("\n   ----------\n");
142 
143 }
144 
CecTest_CreateAndOpenBox(nn::cec::MessageBox & cecMessBox,u32 cecTitleId,u32 privateId,char * hmacKey)145 nn::Result CecTest_CreateAndOpenBox(nn::cec::MessageBox& cecMessBox, u32 cecTitleId, u32 privateId, char* hmacKey)
146 {
147     nn::Result  result;
148     NN_LOG("%s : START\n",__FUNCTION__);
149 
150     /* --------------------------------------------------------
151       Create a box
152       --------------------------------------------------------*/
153     // Try to open a box
154     result = cecMessBox.OpenMessageBox(cecTitleId, privateId);
155     if(result.IsFailure())
156     {
157         NN_LOG("%s(%d): Open Box[0x%08x] Failed. \n",__FUNCTION__,__LINE__,cecTitleId);
158         if(result == nn::cec::ResultNoData())
159         {
160             NN_LOG("%s(%d): Box Not Found. -> Create [0x%08x]\n",__FUNCTION__,__LINE__,cecTitleId);
161             // When there is no message box
162 
163             // Box Name
164             wchar_t name[64] = L"CEC_DEMO_BOX1";
165 
166             // Box Icon
167             u8 icon[48*48*2];   //Icon data
168 
169             // Create a message box
170             result = cecMessBox.CreateMessageBox(
171                         cecTitleId, privateId, hmacKey,
172                         icon, sizeof(icon),
173                         name, sizeof(name));
174 
175             if(result.IsFailure())
176             {
177 
178                 if(result == nn::cec::ResultBoxAlreadyExists())
179                 {
180                     // If we are told that a box already exists even though it can't be opened, there is a box whose lower 8 bits are different
181                     NN_LOG("%s(%d): ### BoxAlreadyExists[0x%08x]\n",__FUNCTION__,__LINE__,cecTitleId);
182                 }
183 
184                 if(result == nn::cec::ResultBoxNumFull())
185                 {
186                     NN_LOG("%s(%d): ### BoxNumFull[0x%08x]\n",__FUNCTION__,__LINE__,cecTitleId);
187                     // The maximum box count has been reached
188                 }
189                 return result;
190             }
191 
192             // After we call CreateMessageBox, it is in the open state
193 
194         }
195         else if(result == nn::cec::ResultNotAuthorized())
196         {
197             // The private IDs do not match
198             // Err
199             NN_LOG("%s(%d): ### Invalid Private ID.\n",__FUNCTION__,__LINE__);
200             return result;
201         }
202         else if(result == nn::cec::ResultStateBusy())
203         {
204             NN_LOG("%s(%d): ### BUSY\n",__FUNCTION__,__LINE__);
205             // Err
206             return result;
207         }
208         else
209         {
210             NN_LOG("%s(%d): ### Error\n",__FUNCTION__,__LINE__);
211             // Err
212             return result;
213         }
214     }
215     NN_LOG("%s(%d): Open Box [0x%08x]. \n",__FUNCTION__,__LINE__, cecTitleId);
216     NN_LOG("%s : END\n",__FUNCTION__);
217     return result;
218 }
219 
CecTest_CreateMessage(nn::cec::MessageBox & cecMessBox,u32 cecTitleId,u32 groupId,u8 messFlag,u8 sendMode,u8 sendCount,u8 propCount,size_t dataSize,nn::cec::MessageId & retMessId)220 void CecTest_CreateMessage(
221     nn::cec::MessageBox& cecMessBox,
222     u32     cecTitleId,
223     u32     groupId,
224     u8      messFlag,
225     u8      sendMode,
226     u8      sendCount,
227     u8      propCount,
228     size_t  dataSize,
229     nn::cec::MessageId&   retMessId
230 )
231 {
232     nn::Result  result;
233 
234     nn::cec::Message        cecMess;
235     u8*                     cecMessBody = NULL ;
236 
237     wchar_t                 info_str[64] = L"Message:CEC_DEMO_1";
238     u8                      icon[40*40*2] = {0};
239 
240     NN_LOG("%s : START\n",__FUNCTION__);
241 
242     /* --------------------------------------------------------
243       Create a message
244       --------------------------------------------------------*/
245     cecMess.NewMessage( cecTitleId,    // CecTitleId
246                         groupId,            // Group ID
247                         messFlag,       // Message Type Flag
248                         sendMode,    // Send Mode
249                         sendCount,           // Send Count
250                         propCount     // Propagation Count
251                         );
252 
253     // Set the data itself (the body)
254     if(dataSize>0)
255     {
256         cecMessBody = reinterpret_cast<u8*>(allocator.Allocate(dataSize));
257         if(cecMessBody == NULL){
258             NN_LOG("%s(%d): ### malloc failed.\n",__FUNCTION__,__LINE__);
259             __breakpoint(0);
260         }
261         std::memset(cecMessBody, 0x04, dataSize); //Fill it in randomly
262 
263         cecMess.SetMessageBody(cecMessBody, dataSize);
264     }
265 
266     // Set the icon
267     std::memset(icon, 0x55, sizeof(icon)); //Fill it in randomly
268     cecMess.SetIcon(icon, sizeof(icon));
269 
270     // Set title_str
271     cecMess.SetInfoText(info_str, sizeof(info_str));
272 
273     // Save the message in the outbox
274     result = cecMessBox.WriteMessage(cecMess, nn::cec::CEC_BOXTYPE_OUTBOX, retMessId);
275     if(result.IsFailure())
276     {
277         if(result.GetDescription() == nn::cec::DESCRIPTION_NOT_AGREE_EULA)
278         {
279             NN_LOG("%s(%d): ### Error NOT_AGREE_EULA\n",__FUNCTION__,__LINE__);
280         }
281         if(result.GetDescription() == nn::cec::DESCRIPTION_PARENTAL_CONTROL_CEC)
282         {
283             NN_LOG("%s(%d): ### Error PARENTAL_CONTROL\n",__FUNCTION__,__LINE__);
284         }
285         NN_LOG("%s(%d):Message Write Error\n",__FUNCTION__,__LINE__);
286         NN_DBG_PRINT_RESULT(result);
287         return;
288     }
289 
290     // Display the message ID that was given when WriteMessage was called
291     NN_LOG("Put Mess OutBox[%s] \n", retMessId.GetString());
292 
293     if(dataSize>0)
294     {
295         allocator.Free(cecMessBody);
296     }
297     NN_LOG("%s : END\n",__FUNCTION__);
298 
299 }
300 
301 // Use the MessageBox class to display box information
CecTest_ShowBoxMessageList(nn::cec::MessageBox & cecMessBox)302 void CecTest_ShowBoxMessageList(nn::cec::MessageBox& cecMessBox)
303 {
304     // Display box information
305     NN_LOG("GetMessageBoxInfoFlag: 0x%02x\n", cecMessBox.GetBoxFlag());
306     NN_LOG("GetBoxSizeMax: \t\tIN: %6d\t\tOUT: %6d\n", cecMessBox.GetBoxSizeMax(nn::cec::CEC_BOXTYPE_INBOX), cecMessBox.GetBoxSizeMax(nn::cec::CEC_BOXTYPE_OUTBOX));
307     NN_LOG("GetBoxSize:    \t\tIN: %6d\t\tOUT: %6d\n", cecMessBox.GetBoxSize(nn::cec::CEC_BOXTYPE_INBOX), cecMessBox.GetBoxSize(nn::cec::CEC_BOXTYPE_OUTBOX));
308     NN_LOG("GetMessNumMax: \t\tIN: %6d\t\tOUT: %6d\n", cecMessBox.GetBoxMessageNumMax(nn::cec::CEC_BOXTYPE_INBOX), cecMessBox.GetBoxMessageNumMax(nn::cec::CEC_BOXTYPE_OUTBOX));
309     NN_LOG("GetMessNum:    \t\tIN: %6d\t\tOUT: %6d\n", cecMessBox.GetBoxMessageNum(nn::cec::CEC_BOXTYPE_INBOX), cecMessBox.GetBoxMessageNum(nn::cec::CEC_BOXTYPE_OUTBOX));
310     NN_LOG("GetGroupNumMax:\t\tIN: %6d\t\tOUT: %6d\n", cecMessBox.GetBoxGroupNumMax(nn::cec::CEC_BOXTYPE_INBOX), cecMessBox.GetBoxGroupNumMax(nn::cec::CEC_BOXTYPE_OUTBOX));
311 
312     // Display message information
313     nn::cec::CecBoxType boxType[] = {nn::cec::CEC_BOXTYPE_INBOX, nn::cec::CEC_BOXTYPE_OUTBOX};
314 
315     for(int type=0; type < sizeof(boxType)/sizeof(boxType[0]); type++)
316     {
317         for(int i=0; i<cecMessBox.GetBoxMessageNum(boxType[type]); i++)
318         {
319             NN_LOG(" %sBOX Message[%d]\n",(boxType[type]==nn::cec::CEC_BOXTYPE_INBOX)?"IN":"OUT", i);
320             nn::cec::MessageId messId = nn::cec::MessageId(cecMessBox.GetMessageId(boxType[type], i));
321             NN_LOG("  GetMessageMessId [%s]\n", messId.GetString());
322 
323             NN_LOG("  GetMessageMessSize:         %d\n", cecMessBox.GetMessageSize(boxType[type], i));
324             NN_LOG("  GetMessageBodySize:         %d\n", cecMessBox.GetMessageBodySize(boxType[type], i));
325             NN_LOG("  GetMessageGroupId:          %d\n", cecMessBox.GetMessageGroupId(boxType[type], i));
326             NN_LOG("  GetMessageSessionId:        %d\n", cecMessBox.GetMessageSessionId(boxType[type], i));
327             NN_LOG("  GetMessageTypeFlag:         0x%02x\n", cecMessBox.GetMessageTypeFlag(boxType[type], i));
328             NN_LOG("  GetMessageSendMode:         0x%02x\n", cecMessBox.GetMessageSendMode(boxType[type], i));
329             NN_LOG("  GetMessageSendCount:        %d\n", cecMessBox.GetMessageSendCount(boxType[type], i));
330             NN_LOG("  GetMessagePropagationCount: %d\n", cecMessBox.GetMessagePropagationCount(boxType[type], i));
331             NN_LOG("  GetMessIndex:               %d\n", cecMessBox.GetMessageIndex(boxType[type], messId));
332         }
333     }
334 
335 
336 }
337 
338 // Delete messages in the box
CecTest_DeleteOneMessage(nn::cec::MessageBox & cecMessBox,nn::cec::CecBoxType boxtype)339 void CecTest_DeleteOneMessage(nn::cec::MessageBox& cecMessBox, nn::cec::CecBoxType boxtype)
340 {
341     nn::Result result;
342 
343     nn::cec::MessageId messId;
344 
345     size_t messNum = cecMessBox.GetBoxMessageNum(boxtype);
346     NN_LOG("%s: %sBox Message (%d)\n", __FUNCTION__, (boxtype==nn::cec::CEC_BOXTYPE_OUTBOX)?"Out":"In", messNum);
347 
348     if(messNum > 0)
349     {
350         // Get the first message ID
351         messId = cecMessBox.GetMessageId(boxtype, 0);
352         NN_LOG("  GetMessageMessId [%s]\n", messId.GetString());
353 
354         // Delete the specified message ID
355         result = cecMessBox.DeleteMessage(boxtype, messId);
356         if(result.IsFailure())
357         {
358             NN_LOG("### Delete Message Failed.\n");
359             return;
360         }
361         NN_LOG("  DeleteMessage [%s]\n", messId.GetString());
362     }
363 }
364 
365 // Open and display messages in the inbox
CecTest_ShowInboxMessage(nn::cec::MessageBox & cecMessBox)366 void CecTest_ShowInboxMessage(nn::cec::MessageBox& cecMessBox)
367 {
368     u32 inboxMessNum;       // Number of messages
369     u8* buf;
370     nn::cec::MessageId    messId;
371     nn::Result      result;
372     nn::cec::CecBoxType boxType = nn::cec::CEC_BOXTYPE_INBOX;
373 
374     // Get the number of messages
375     inboxMessNum = cecMessBox.GetBoxMessageNum(boxType);
376 
377     for(int i=0; i<inboxMessNum; i++)
378     {
379         nn::cec::Message cecMessage;
380         // Get the i'th message ID
381         cecMessBox.GetMessageId(&messId, boxType, i);
382 
383         // Get the size
384         size_t messSize = cecMessBox.GetMessageSize(boxType, i);
385 
386         // Allocate a buffer for reading data
387         buf = reinterpret_cast<u8*>(allocator.Allocate(messSize));
388         if(buf==NULL)
389         {
390             NN_LOG("Malloc Error\n");
391         }
392 
393         // Read the message
394         result = cecMessBox.ReadMessage(cecMessage, buf, messSize, boxType, messId);
395         if(result.IsFailure())
396         {
397             NN_LOG("### [Message %d]ReadMessage Error\n", i);
398             allocator.Free(buf);
399             continue;
400         }
401 
402         // Display
403         // Message ID
404         NN_LOG(" ===== (%02d) messageId [%s]\n", i, messId.GetString());
405 
406         // Icon
407         void* p_icon;
408         size_t iconSize;
409         result = cecMessage.GetIcon(&p_icon, &iconSize);
410         if(result.IsSuccess())
411         {
412             NN_LOG("  Icon size:%d\n", iconSize);
413             BinaryDump(reinterpret_cast<u8*>(p_icon), 32, 1);   // Dump only 32 bytes
414         }
415 
416         // info_str
417         const wchar_t*    p_infoStr;
418         size_t      infoStrLen;
419         result = cecMessage.GetInfoText(&p_infoStr, &infoStrLen);
420         if(result.IsSuccess())
421         {
422             NN_LOG("  Info Str: %ls\n", p_infoStr);
423         }
424 
425         // Send Count
426         NN_LOG("  Send Count: %d\n",cecMessage.GetSendCount());
427 
428         // Propagation Count
429         NN_LOG("  Propagation Count: %d\n",cecMessage.GetPropagationCount());
430 
431         // Data
432         u32 messBodySize = cecMessage.GetBodySize();
433         u8* messBodyBuf;
434         NN_LOG("  Data body Size: %d\n", messBodySize);
435 
436         messBodyBuf = reinterpret_cast<u8*>(allocator.Allocate(messBodySize));// Allocate buffer
437         if(messBodyBuf == NULL)
438         {
439             NN_LOG("Malloc Error\n");
440         }
441 
442         cecMessage.GetMessageBody(messBodyBuf, messBodySize);// Get
443         BinaryDump(messBodyBuf, 32, 1);   // Dump only 32 bytes
444 
445         allocator.Free(messBodyBuf);
446         allocator.Free(buf);
447     }
448 }
449 
ReceiveEventThread(uptr param)450 static void ReceiveEventThread(uptr param)
451 {
452     NN_UNUSED_VAR(param)
453     nn::cec::CecNotificationData notificationData;
454     nn::cec::CecControl::GetCecRecvEventHandle(&recvEvent);
455 
456     do{
457         recvEvent.Wait();
458 
459         {
460             NN_LOG("============= Receive Check!!!!!! ============= \n");
461             nn::cec::CTR::CecControl::GetCecInfoBuffer(TEST_TITLEID, reinterpret_cast<u8*>(&notificationData), sizeof(notificationData));
462     #ifndef NN_BUILD_RELEASE
463             NN_LOG(" Recv Count:[%d] Num:[%d] \n", notificationData.count, notificationData.num);
464             for(int i=0; i < notificationData.num; i++)
465             {
466                 char dateStr[32] = {0};
467                 DateParam2Str(dateStr, notificationData.param[i].recvDate);
468                 NN_LOG("(%02d)[%s][0x%08x][%s]\n", i, dateStr, notificationData.param[i].cecTitleId,
469                     nn::cec::MessageId(notificationData.param[i].messageId).GetEncodedString());
470             }
471             NN_LOG("=============================================== \n");
472     #endif
473         }
474     }while(threadAlive);
475     recvEvent.Finalize();
476 
477 }
478 
479 
IsCecDaemonBusy()480 bool IsCecDaemonBusy()
481 {
482     u32 state;
483     nn::cec::CecControl::GetCecState(&state);
484     if(state != nn::cec::CecControl::DAEMON_STATE_IDLE)
485     {
486         return true;
487     }
488     return false;
489 }
490 
491 
492 
nnMain(void)493 extern "C" void nnMain( void )
494 {
495     NN_LOG("START : %s @ %s (Build: %s %s)\n",__FUNCTION__,__FILE__,__DATE__, __TIME__);
496     nn::Result result;
497 
498     nn::os::Thread thread;
499 
500     // Use the FS library to get the EULA version to agree to for the application
501     nn::fs::Initialize();
502 
503     // Initialize hid
504     result = nn::hid::Initialize();
505     NN_UTIL_PANIC_IF_FAILED(result);
506 
507     // Initialize applets
508     SleepHandler::Initialize();
509 
510 
511     // Prepare pad
512     nn::hid::PadReader padReader;
513     nn::hid::PadStatus padStatus;
514 
515     // Wait for HID input to stabilize
516     nn::os::Thread::Sleep(nn::fnd::TimeSpan::FromSeconds(1));
517 
518     // Allocator
519     allocator.InitExpHeap();
520 
521     // Access the daemon
522     NN_LOG("Cec: nn::cec::Initialize()\n");
523     result = nn::cec::Initialize(allocator);
524     NN_UTIL_PANIC_IF_FAILED(result);
525 
526     {
527         threadAlive = true;
528         result = thread.TryStartUsingAutoStack(ReceiveEventThread, NULL, 4096);
529         if(result.IsFailure())
530         {
531             NN_LOG("%s(%d):### TryStartUsingAutoStack Failed.\n",__FUNCTION__,__LINE__);
532             //NN_DBG_PRINT_RESULT(result);
533             __breakpoint(0);
534         }
535     }
536 
537     NN_LOG("---- Cec Demo ----\n");
538     NN_LOG("A: Write data\n");
539     NN_LOG("B: Show box data\n");
540 
541     NN_LOG("UP   : Open  Box\n");
542     NN_LOG("DOWN : Close Box\n");
543     NN_LOG("X    : Delete OutBox Message\n");
544     NN_LOG("Y    : Delete All InBox Messages\n");
545     NN_LOG("START: Delete Box and Exit\n");
546     NN_LOG("-------------------\n");
547 
548     nn::cec::MessageBox cecMessBox;
549     bool bMessBoxOpened = false;
550 
551     while(1)
552     {
553 
554         // Get input
555         padReader.ReadLatest(&padStatus);
556 
557         if(padStatus.hold & nn::hid::BUTTON_A)
558         {
559             // Create a message and write it to the outbox
560             if(bMessBoxOpened)
561             {
562                 nn::cec::MessageId   messId;
563                 CecTest_CreateMessage(
564                     cecMessBox,
565                     TEST_TITLEID,
566                     0,                                      // Group ID
567                     nn::cec::MESSAGE_TYPEFLAG_NON_FRIEND|nn::cec::MESSAGE_TYPEFLAG_FRIEND,
568                                                             // MessageTypeFlag
569                     nn::cec::CEC_SENDMODE_SENDRECV,         // SendMode
570                     nn::cec::MESSAGE_SENDCOUNT_UNLIMITED,   // Send Count
571                     nn::cec::MESSAGE_PROPAGATIONCOUNT_ONCE, // Propagation Count
572                     32*1024,                                // Data Size
573                     messId
574                     );
575             }
576             else
577             {
578                 NN_LOG("Cec: ### Box is not opened.\n");
579             }
580         }
581 
582         if(padStatus.hold & nn::hid::BUTTON_X)
583         {
584             // Delete a single message from the outbox
585             if(bMessBoxOpened)
586             {
587                 NN_LOG("Cec: DeleteOutboxData\n");
588                 CecTest_DeleteOneMessage(cecMessBox, nn::cec::CEC_BOXTYPE_OUTBOX);
589             }
590             else
591             {
592                 NN_LOG("Cec: ### Box is not opened.\n");
593             }
594         }
595 
596         if(padStatus.hold & nn::hid::BUTTON_Y)
597         {
598             // Delete all messages from the inbox
599             if(bMessBoxOpened)
600             {
601                 NN_LOG("Cec: Delete All InBox Messages.\n");
602                 cecMessBox.DeleteAllMessages(nn::cec::CEC_BOXTYPE_INBOX);
603                 NN_LOG("Cec: Delete All InBox Messages. END\n");
604             }
605             else
606             {
607                 NN_LOG("Cec: ### Box is not opened.\n");
608             }
609         }
610 
611         if(padStatus.hold & nn::hid::BUTTON_B)
612         {
613             // Displays the box's content
614             if(bMessBoxOpened)
615             {
616                 // Open and display messages in the inbox
617                 CecTest_ShowInboxMessage(cecMessBox);
618                 // Use the MessageBox class to get information
619                 CecTest_ShowBoxMessageList(cecMessBox);
620             }
621             else
622             {
623                 NN_LOG("Cec: ### Box is not opened.\n");
624             }
625         }
626 
627         if(padStatus.hold & nn::hid::BUTTON_UP)
628         {
629             //Open the box (or create one if it does not exist)
630             NN_LOG("Cec: Open MessageBox\n");
631             result = CecTest_CreateAndOpenBox(cecMessBox, TEST_TITLEID, TEST_PRIVATEID, TEST_HMACKEY);
632             if(result.IsSuccess())
633             {
634                 bMessBoxOpened = true;
635             }
636         }
637 
638         if(padStatus.hold & nn::hid::BUTTON_DOWN)
639         {
640             bMessBoxOpened = false;
641             NN_LOG("Cec: Close MessageBox\n");
642             cecMessBox.CloseMessageBox();
643         }
644 
645 
646         if(padStatus.hold & nn::hid::BUTTON_START)
647         {
648 
649                 // We can only access a box while the daemon is stopped.
650                 result = cecMessBox.OpenMessageBox(TEST_TITLEID, TEST_PRIVATEID);
651 
652                 if(result.IsSuccess())
653                 {
654                     // Delete the box and exit
655                     NN_LOG("Cec: delete Box\n");
656                     cecMessBox.DeleteMessageBox();
657                 }
658                 break;
659         }
660         // Determination for System Sleep Mode
661         if ( SleepHandler::IsSleepRequested() )
662         {
663             NN_LOG("<<SLEEP>>\n");
664             SleepHandler::SleepSystem();
665             NN_LOG("<<AWAKE>>\n");
666         }
667 
668         nn::os::Thread::Sleep(nn::fnd::TimeSpan::FromMilliSeconds(100));
669 
670     }
671 
672     // Sleep handler termination processing
673     SleepHandler::Finalize();
674 
675     nn::cec::Finalize();
676 
677     NN_LOG("Cec: END : %s @ %s \n",__FUNCTION__,__FILE__);
678 
679     while(1){nn::os::Thread::Sleep(nn::fnd::TimeSpan::FromMilliSeconds(1000));}
680 
681 }
682 
683 
684