1 /*---------------------------------------------------------------------------*
2   Project:  TwlSDK - MB - libraries
3   File:     mb_common.c
4 
5   Copyright 2007-2008 Nintendo. 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   $Date:: 2008-09-18#$
14   $Rev: 8573 $
15   $Author: okubata_ryoma $
16  *---------------------------------------------------------------------------*/
17 
18 #include "mb_private.h"
19 
20 // ----------------------------------------------------------------------------
21 // Definitions
22 #define MY_ROUND(n, a)      (((u32) (n) + (a) - 1) & ~((a) - 1))
23 
24 #define MB_PARENT_WORK_SIZE_MIN (32 + sizeof(MBiParam) + 32 + sizeof(MB_CommPWork) + 32 + WM_SYSTEM_BUF_SIZE)
25 #define MB_CHILD_WORK_SIZE_MIN  (32 + sizeof(MBiParam) + 32 + sizeof(MB_CommCWork) + 32 + WM_SYSTEM_BUF_SIZE)
26 /*
27  * Determines whether the capacity is correct for the size that is being requested.
28  */
29 SDK_COMPILER_ASSERT(MB_PARENT_WORK_SIZE_MIN <= MB_SYSTEM_BUF_SIZE);
30 SDK_COMPILER_ASSERT(MB_CHILD_WORK_SIZE_MIN <= MB_CHILD_SYSTEM_BUF_SIZE);
31 
32 
33 /*
34  * Initializes the block header, and only configures the type.
35  * Thereafter, for the time until sending with the MBi_BlockHeaderEnd function, fill the various fields.
36  *
37  * If there are no arguments, it is okay to leave as is.
38  */
MBi_BlockHeaderBegin(u8 type,u32 * sendbuf)39 void MBi_BlockHeaderBegin(u8 type, u32 *sendbuf)
40 {
41     u8     *p = (u8 *)sendbuf;
42     p[0] = type;                       /* type is common to the parent and child. */
43 }
44 
45 /*
46  * Completes the block header configuration and calculates the checksum.
47  * After that, actually sends to the other party that is designated by pollbmp.
48  */
MBi_BlockHeaderEnd(int body_len,u16 pollbmp,u32 * sendbuf)49 int MBi_BlockHeaderEnd(int body_len, u16 pollbmp, u32 *sendbuf)
50 {
51     /*
52      * MY_ROUND may not be needed if sendbuf is 32-byte aligned.
53      * A check has already been added in the Init function.
54      * In the end, a larger quantity is gotten and aligned internally.
55      */
56     DC_FlushRange(sendbuf, MY_ROUND(body_len, 32));
57     DC_WaitWriteBufferEmpty();
58 
59     MB_DEBUG_OUTPUT("SEND (BMP:%04x)", pollbmp);
60     MB_COMM_TYPE_OUTPUT(((u8 *)sendbuf)[0]);
61 
62     return MBi_SendMP(sendbuf, body_len, pollbmp);
63 }
64 
65 /*---------------------------------------------------------------------------*
66   Name:         MB_GetParentSystemBufSize
67 
68   Description:  Gets the size of the work memory used by MB. (Parent Device)
69 
70   Arguments:    None.
71 
72   Returns:      The size of the work memory used by the MB parent device.
73  *---------------------------------------------------------------------------*/
MB_GetParentSystemBufSize(void)74 int MB_GetParentSystemBufSize(void)
75 {
76     return MB_PARENT_WORK_SIZE_MIN;
77 }
78 
79 /*---------------------------------------------------------------------------*
80   Name:         MB_GetChildSystemBufSize
81 
82   Description:  Gets the size of the work memory used by MB. (Child Device)
83 
84   Arguments:    None.
85 
86   Returns:      The size of the work memory used by the MB child device.
87  *---------------------------------------------------------------------------*/
MB_GetChildSystemBufSize(void)88 int MB_GetChildSystemBufSize(void)
89 {
90     return MB_CHILD_WORK_SIZE_MIN;
91 }
92 
93 
MBi_calc_cksum(const u16 * buf,int length)94 u16 MBi_calc_cksum(const u16 *buf, int length)
95 {
96     u32     sum;
97     int     nwords = length >> 1;
98     for (sum = 0; nwords > 0; nwords--)
99         sum += *buf++;
100 
101     sum = (sum >> 16) + (sum & 0xffff);
102     sum += (sum >> 16);
103     return (u16)(sum ^ 0xffff);
104 }
105 
106 /* ============================================================================
107 
108     for debug
109 
110     ============================================================================*/
111 
112 #ifdef	PRINT_DEBUG
113 
MBi_DebugPrint(const char * file,int line,const char * func,const char * fmt,...)114 void MBi_DebugPrint(const char *file, int line, const char *func, const char *fmt, ...)
115 {
116     va_list vlist;
117 
118     OS_TPrintf("func: %s [%s:%d]:\n", func, file, line);
119 
120     va_start(vlist, fmt);
121     OS_TVPrintf(fmt, vlist);
122     va_end(vlist);
123 
124     OS_TPrintf("\n");
125 }
126 
MBi_comm_type_output(u16 type)127 void MBi_comm_type_output(u16 type)
128 {
129     enum
130     { MB_TYPE_STRING_NUM = 12 };
131     static const char *const mb_type_string[MB_TYPE_STRING_NUM] = {
132         "MB_COMM_TYPE_DUMMY",          //      0
133 
134         "MB_COMM_TYPE_PARENT_SENDSTART",        //      1
135         "MB_COMM_TYPE_PARENT_KICKREQ", //      2
136         "MB_COMM_TYPE_PARENT_DL_FILEINFO",      //      3
137         "MB_COMM_TYPE_PARENT_DATA",    //      4
138         "MB_COMM_TYPE_PARENT_BOOTREQ", //      5
139         "MB_COMM_TYPE_PARENT_MEMBER_FULL",      //      6
140 
141         "MB_COMM_TYPE_CHILD_FILEREQ",  //      7
142         "MB_COMM_TYPE_CHILD_ACCEPT_FILEINFO",   //      8
143         "MB_COMM_TYPE_CHILD_CONTINUE", //      9
144         "MB_COMM_TYPE_CHILD_STOPREQ",  //      10
145         "MB_COMM_TYPE_CHILD_BOOTREQ_ACCEPTED",  //      11
146     };
147     if (type >= MB_TYPE_STRING_NUM)
148     {
149         MB_OUTPUT("TYPE: unknown\n");
150         return;
151     }
152     MB_OUTPUT("TYPE: %s\n", mb_type_string[type]);
153 }
154 
MBi_comm_wmevent_output(u16 type,void * arg)155 void MBi_comm_wmevent_output(u16 type, void *arg)
156 {
157     enum
158     { MB_CB_STRING_NUM = 43 };
159     static const char *const mb_cb_string[MB_CB_STRING_NUM + 2] = {
160         "MB_CALLBACK_CHILD_CONNECTED", //              0
161         "MB_CALLBACK_CHILD_DISCONNECTED",       //              1
162         "MB_CALLBACK_MP_PARENT_SENT",  //              2
163         "MB_CALLBACK_MP_PARENT_RECV",  //              3
164         "MB_CALLBACK_PARENT_FOUND",    //              4
165         "MB_CALLBACK_PARENT_NOT_FOUND", //              5
166         "MB_CALLBACK_CONNECTED_TO_PARENT",      //              6
167         "MB_CALLBACK_DISCONNECTED",    //              7
168         "MB_CALLBACK_MP_CHILD_SENT",   //              8
169         "MB_CALLBACK_MP_CHILD_RECV",   //              9
170         "MB_CALLBACK_DISCONNECTED_FROM_PARENT", //              10
171         "MB_CALLBACK_CONNECT_FAILED",  //              11
172         "MB_CALLBACK_DCF_CHILD_SENT",  //              12
173         "MB_CALLBACK_DCF_CHILD_SENT_ERR",       //              13
174         "MB_CALLBACK_DCF_CHILD_RECV",  //              14
175         "MB_CALLBACK_DISCONNECT_COMPLETE",      //              15
176         "MB_CALLBACK_DISCONNECT_FAILED",        //              16
177         "MB_CALLBACK_END_COMPLETE",    //              17
178         "MB_CALLBACK_MP_CHILD_SENT_ERR",        //              18
179         "MB_CALLBACK_MP_PARENT_SENT_ERR",       //              19
180         "MB_CALLBACK_MP_STARTED",      //              20
181         "MB_CALLBACK_INIT_COMPLETE",   //              21
182         "MB_CALLBACK_END_MP_COMPLETE", //              22
183         "MB_CALLBACK_SET_GAMEINFO_COMPLETE",    //              23
184         "MB_CALLBACK_SET_GAMEINFO_FAILED",      //              24
185         "MB_CALLBACK_MP_SEND_ENABLE",  //              25
186         "MB_CALLBACK_PARENT_STARTED",  //              26
187         "MB_CALLBACK_BEACON_LOST",     //              27
188         "MB_CALLBACK_BEACON_SENT",     //              28
189         "MB_CALLBACK_BEACON_RECV",     //              29
190         "MB_CALLBACK_MP_SEND_DISABLE", //              30
191         "MB_CALLBACK_DISASSOCIATE",    //              31
192         "MB_CALLBACK_REASSOCIATE",     //              32
193         "MB_CALLBACK_AUTHENTICATE",    //              33
194         "MB_CALLBACK_SET_LIFETIME",    //              34
195         "MB_CALLBACK_DCF_STARTED",     //              35
196         "MB_CALLBACK_DCF_SENT",        //              36
197         "MB_CALLBACK_DCF_SENT_ERR",    //              37
198         "MB_CALLBACK_DCF_RECV",        //              38
199         "MB_CALLBACK_DCF_END",         //              39
200         "MB_CALLBACK_MPACK_IND",       //              40
201         "MB_CALLBACK_MP_CHILD_SENT_TIMEOUT",    //              41
202         "MB_CALLBACK_SEND_QUEUE_FULL_ERR",      //              42
203         "MB_CALLBACK_API_ERROR",       //              255
204         "MB_CALLBACK_ERROR",           //              256
205     };
206 
207     if (type == MB_CALLBACK_API_ERROR)
208         type = MB_CB_STRING_NUM;
209     else if (type == MB_CALLBACK_ERROR)
210         type = MB_CB_STRING_NUM + 1;
211     else if (type >= MB_CB_STRING_NUM)
212     {
213         MB_OUTPUT("EVENTTYPE: unknown\n");
214         return;
215     }
216 
217     MB_OUTPUT("EVENTTYPE:%s\n", mb_cb_string[type]);
218     if (arg)
219     {
220         MB_OUTPUT("\tAPPID:%04x ERRCODE:%04x\n", ((u16 *)arg)[0], ((u16 *)arg)[1]);
221         MB_OUTPUT("\twlCmd:%04x wlResult:%04x\n", ((u16 *)arg)[2], ((u16 *)arg)[3]);
222     }
223 }
224 
225 #endif
226