1 /*---------------------------------------------------------------------------*
2   Project:  TwlSDK - WBT - demos - wbt-1
3   File:     bt.c
4 
5   Copyright 2006-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: 8576 $
15   $Author: nishimoto_takashi $
16  *---------------------------------------------------------------------------*/
17 
18 #ifdef SDK_TWL
19 #include <twl.h>
20 #else
21 #include <nitro.h>
22 #endif
23 
24 #include <nitro/wbt.h>
25 #include "wh.h"
26 #include "bt.h"
27 #include "text.h"
28 
29 #define NOT_USE_ALLOC
30 
31 #ifndef	SDK_NO_MESSAGE
32 #define	__MY_LINE__		__LINE__
33 #else
34 #define	__MY_LINE__		0
35 #endif
36 
37 /* Reception block control data for child device */
38 static int request_block_num;
39 static int block_info_num = 0;
40 static OSTick start_tick;
41 static int bt_loop_count = 0;
42 static int bt_running = 0;
43 
44 /* Child device receive buffers */
45 static WBTBlockInfoTable block_info_table;
46 static WBTRecvBufTable recv_buf_table;
47 static WBTPacketBitmapTable recv_buf_packet_bmp_table;
48 static WBTAidBitmap tbmp = 1;          /* Request partner (parent) */
49 
50 /* User data send buffer for child device */
51 static u8 user_data[WBT_SIZE_USER_DATA];
52 
53 #ifdef NOT_USE_ALLOC
54 WBTBlockInfo block_info[WBT_NUM_OF_AID][NUM_OF_BT_LIST];
55 u8      recv_buf[WBT_NUM_OF_AID][BT_DATA_SIZE];
56 u32
57     recv_pkt_bmp_buf[WBT_NUM_OF_AID][WBT_PACKET_BITMAP_SIZE(BT_DATA_SIZE, BT_PARENT_PACKET_SIZE)];
58 #endif
59 
60 /* Block data for parent device */
61 static WBTBlockInfoList bt_list[NUM_OF_BT_LIST];
62 static u8 bt_data[NUM_OF_BT_LIST][BT_DATA_SIZE];
63 
64 static u8 user_char_id[NUM_OF_BT_LIST][WBT_USER_ID_LEN] = {
65     "BT text information area 0",
66     "BT text information area 1",
67     "BT text information area 2",
68 #if 0
69     "BT text information area 3",
70     "BT text information area 4"
71 #endif
72 };
73 
74 
75 const char *command_str[] = {
76     "REQ_NONE",
77     "REQ_WAIT",
78     "REQ_SYNC",
79     "RES_SYNC",
80     "REQ_GET_BLOCK",
81     "RES_GET_BLOCK",
82     "REQ_GET_BLOCKINFO",
83     "RES_GET_BLOCKINFO",
84     "REQ_GET_BLOCK_DONE",
85     "RES_GET_BLOCK_DONE",
86     "REQ_USER_DATA",
87     "RES_USER_DATA",
88     "SYSTEM_CALLBACK",
89     "PREPARE_SEND_DATA",
90     "REQ_ERROR",
91     "RES_ERROR",
92     "CANCEL"
93 };
94 
95 
96 
97 
strlen(char * str)98 static int strlen(char *str)
99 {
100     int     i = 0;
101     while (1)
102     {
103         if (*str != '\0')
104         {
105             str++;
106             i++;
107         }
108         else
109         {
110             break;
111         }
112     }
113     return i;
114 }
115 
116 
117 /* Block registration function for parent device */
bt_register_blocks(void)118 void bt_register_blocks(void)
119 {
120     int     i;
121     char   *end_string = "This is BlockTransfer test data contents end\n";
122     char   *ptr;
123     int     offset;
124 
125     for (i = 0; i < NUM_OF_BT_LIST; i++)
126     {
127         offset = BT_DATA_SIZE - (strlen(end_string) + 1);
128         *(s32 *)(&(bt_data[i][0])) = offset;
129         (void)OS_SPrintf((char *)&(bt_data[i][4]),
130                          "This is BlockTransfer test data contents start %d\n", i);
131 
132         ptr = (char *)(&(bt_data[i][0]) + offset);
133         (void)OS_SPrintf((char *)ptr, "%s", end_string);
134 
135         (void)WBT_RegisterBlock(&(bt_list[i]), (u32)(10000 + i) /* IDs of 1000 or less are not allowed */ ,
136                                 user_char_id[i], &(bt_data[i][0]), BT_DATA_SIZE, 0);
137     }
138 }
139 
140 
141 /* Block transmission end function for child device */
bt_stop(void)142 void bt_stop(void)
143 {
144     bt_running = 0;
145     (void)WBT_CancelCurrentCommand(0xffff);
146 }
147 
148 
149 /* Block transmission start function for child device */
bt_start(void)150 void bt_start(void)
151 {
152     OSIntrMode enabled;
153     static int init_flag = FALSE;
154     int     i;
155 
156     enabled = OS_DisableInterrupts();
157 
158     if (bt_running)
159     {
160         (void)OS_RestoreInterrupts(enabled);
161         return;
162     }
163     bt_running = 1;
164 
165 #ifdef NOT_USE_ALLOC
166 
167     if (init_flag == FALSE)
168     {
169         init_flag = TRUE;
170         for (i = 0; i < WBT_NUM_OF_AID; i++)
171         {
172             block_info_table.block_info[i] = &(block_info[i][0]);
173             recv_buf_table.recv_buf[i] = &(recv_buf[i][0]);
174             recv_buf_packet_bmp_table.packet_bitmap[i] = &(recv_pkt_bmp_buf[i][0]);
175         }
176     }
177 
178 #else
179 
180     mfprintf(tc[2], "child bt start\n");
181 
182     if (init_flag == FALSE)
183 
184     {
185         init_flag = TRUE;
186         /* Initialize child device receive buffers */
187         for (i = 0; i < WBT_NUM_OF_AID; i++)
188         {
189             block_info_table.block_info[i] = NULL;
190             recv_buf_table.recv_buf[i] = NULL;
191             recv_buf_packet_bmp_table.packet_bitmap[i] = NULL;
192         }
193     }
194 
195     for (i = 0; i < WBT_NUM_OF_AID; i++)
196     {
197         if (block_info_table.block_info[i] != NULL)
198         {
199             OS_Free(block_info_table.block_info[i]);
200             block_info_table.block_info[i] = NULL;
201         }
202         if (recv_buf_table.recv_buf[i] != NULL)
203         {
204             OS_Free(recv_buf_table.recv_buf[i]);
205             recv_buf_table.recv_buf[i] = NULL;
206         }
207         if (recv_buf_packet_bmp_table.packet_bitmap[i] != NULL)
208         {
209             OS_Free(recv_buf_packet_bmp_table.packet_bitmap[i]);
210             recv_buf_packet_bmp_table.packet_bitmap[i] = NULL;
211         }
212     }
213 #endif
214 
215     (void)OS_RestoreInterrupts(enabled);
216 
217     (void)WBT_RequestSync(tbmp,        /* Partner that is requesting Sync (multiple only possible for parent) */
218                           bt_callback  /* Callback when ending */
219         );
220 }
221 
222 
223 /* Callback function for block transmission */
bt_callback(void * arg)224 void bt_callback(void *arg)
225 {
226 
227     WBTCommand *uc = (WBTCommand *)arg;
228     int     peer_aid = WBT_AidbitmapToAid(uc->peer_bmp);        /* AID of communications partner station */
229     // mfprintf(tc[2],"aid = %d\n", peer_aid);
230 
231     switch (uc->event)
232     {
233     case WBT_CMD_RES_SYNC:
234         /* WBT_RequestSync end */
235         request_block_num = 0;
236         block_info_num = uc->sync.num_of_list;  /* Number of blocks held by partner */
237         mfprintf(tc[2], "blockinfo num = %d my_packet_size = %d peer_packet_size = %d\n", block_info_num, uc->sync.my_packet_size,      /* Partner's send data size */
238                  uc->sync.peer_packet_size      /* Send data size here */
239             );
240 #ifndef NOT_USE_ALLOC
241         mfprintf(tc[2], "info buf alloc %d\n", peer_aid);
242         /* Block information table initialization */
243         block_info_table.block_info[peer_aid] = (WBTBlockInfo *)OS_Alloc(sizeof(WBTBlockInfo));
244 #endif
245 
246         if (uc->target_bmp == 0)       /* Has there been a response from all partner stations? */
247         {
248             (void)OS_SPrintf((char *)user_data, " %5d\n", bt_loop_count);
249 
250             /* Send user data */
251             if (FALSE == WBT_PutUserData(tbmp,  /* Partner that sends user data (multiple only possible for parent) */
252                                          user_data,     /* User data buffer */
253                                          WBT_SIZE_USER_DATA,    /* User data size of 12 or lower */
254                                          bt_callback    /* Callback when ending */
255                 ))
256             {
257                 mfprintf(tc[2], "command invoke error %d\n", __MY_LINE__);
258             }
259         }
260         break;
261     case WBT_CMD_RES_USER_DATA:
262 
263         if (uc->target_bmp == 0)       /* Has there been a response from all partner stations? */
264         {
265             /* Block list request */
266             if (FALSE == WBT_GetBlockInfo(tbmp, /* Partner that makes block list request (multiple only possible for parent) */
267                                           request_block_num /* Block list number */ ,
268                                           &block_info_table,    /* Block information table */
269                                           bt_callback   /* Callback when ending */
270                 ))
271             {
272                 mfprintf(tc[2], "command invoke error %d\n", __MY_LINE__);
273             }
274         }
275         break;
276     case WBT_CMD_RES_GET_BLOCKINFO:
277 
278         /* End WBT_GetBlockInfo */
279 
280         mfprintf(tc[2], "blockinfo %d done\n", uc->get.block_id);       /* Obtained block list ID */
281         mfprintf(tc[2], " info id = %d\n", block_info_table.block_info[peer_aid]->id);  /* Block ID */
282         mfprintf(tc[2], " info block size = %d\n", block_info_table.block_info[peer_aid]->block_size);  /* Block size */
283         mfprintf(tc[2], " info = %s\n", block_info_table.block_info[peer_aid]->user_id);        /* Block user definition information */
284 
285 #ifndef NOT_USE_ALLOC
286         /* Initialize receive buffer table */
287         recv_buf_table.recv_buf[peer_aid] =
288             (u8 *)OS_Alloc((u32)block_info_table.block_info[peer_aid]->block_size);
289         mfprintf(tc[2], "recv buf alloc %d\n", peer_aid);
290 
291         /* Initialize buffer table for registration of packet reception number */
292         recv_buf_packet_bmp_table.packet_bitmap[peer_aid] =
293             (u32 *)
294             OS_Alloc((u32)
295                      WBT_CalcPacketbitmapSize(block_info_table.block_info[peer_aid]->block_size));
296 
297         mfprintf(tc[2], "recv pkt bmp size = %d\n",
298                  WBT_CalcPacketbitmapSize(block_info_table.block_info[peer_aid]->block_size));
299 #endif
300 
301         if (uc->target_bmp == 0)       /* Has there been a response from all partner stations? */
302         {
303 
304             /* Block reception request */
305             if (FALSE == WBT_GetBlock(tbmp,     /* Partner that makes the block reception request (multiple only possible for parent) */
306                                       block_info_table.block_info[peer_aid]->id /* Block ID */ ,
307                                       &recv_buf_table,  /* Receive buffer table */
308                                       (u32)block_info_table.block_info[peer_aid]->block_size,   /* Block size */
309                                       &recv_buf_packet_bmp_table,       /* Buffer table for registration of packet reception number */
310                                       bt_callback       /* Callback when ending */
311                 ))
312             {
313                 mfprintf(tc[2], "command invoke error %d\n", __MY_LINE__);
314             }
315             else
316             {
317                 start_tick = OS_GetTick();      /* Start time measurement */
318             }
319 
320         }
321 
322         break;
323     case WBT_CMD_RES_GET_BLOCK:
324         /* End WBT_GetBlock */
325 
326         mfprintf(tc[2], "get block %d done\n", uc->get.block_id);       /* Received block ID */
327         mfprintf(tc[2], " time %d msec\n", OS_TicksToMilliSeconds(OS_GetTick() - start_tick));
328 
329         mfprintf(tc[2], " %s\n", &(recv_buf_table.recv_buf[peer_aid][4]));      /* Received block contents */
330         {
331             u32     offset;
332             offset = *(u32 *)&(recv_buf_table.recv_buf[peer_aid][0]);
333             mfprintf(tc[2], " %s\n", (char *)(&(recv_buf_table.recv_buf[peer_aid][offset])));
334         }
335 
336 #ifndef NOT_USE_ALLOC
337         /* Reception buffer table deallocation */
338         mfprintf(tc[2], "recv buf free %d\n", peer_aid);
339         OS_Free(recv_buf_table.recv_buf[peer_aid]);
340         recv_buf_table.recv_buf[peer_aid] = NULL;
341 
342         /* Deallocation of buffer table for recording of the packet reception number */
343         OS_Free(recv_buf_packet_bmp_table.packet_bitmap[peer_aid]);
344         recv_buf_packet_bmp_table.packet_bitmap[peer_aid] = NULL;
345 
346         OS_Free(block_info_table.block_info[peer_aid]);
347         block_info_table.block_info[peer_aid] = NULL;
348 
349         {
350             mfprintf(tc[2], "info buf alloc %d\n", peer_aid);
351             /* Block information table initialization */
352             block_info_table.block_info[peer_aid] = (WBTBlockInfo *)OS_Alloc(sizeof(WBTBlockInfo));
353         }
354 #endif
355 
356         if (uc->target_bmp == 0)
357         {                              /* Has there been a response from all requested partner stations? */
358 
359             request_block_num++;
360 
361             if (request_block_num < block_info_num)
362             {
363 
364                 /* Block list request */
365                 if (FALSE == WBT_GetBlockInfo(tbmp, request_block_num,  /* Block list number */
366                                               &block_info_table,        /* Block information table */
367                                               bt_callback       /* Callback when ending */
368                     ))
369                 {
370                     mfprintf(tc[2], "command invoke error %d\n", __MY_LINE__);
371                 }
372             }
373             else
374             {
375                 request_block_num = 0;
376 
377                 bt_loop_count++;
378                 if (bt_loop_count > 99999)
379                 {
380                     bt_loop_count = 0;
381                 }
382 
383                 (void)OS_SPrintf((char *)user_data, " %05d\n", bt_loop_count);
384 
385                 /* Send user data */
386                 if (FALSE == WBT_PutUserData(tbmp,      /* Partner that sends user data (multiple only possible for parent) */
387                                              user_data, /* User data buffer */
388                                              WBT_SIZE_USER_DATA,        /* User data size of 12 or lower */
389                                              bt_callback        /* Callback when ending */
390                     ))
391                 {
392                     mfprintf(tc[2], "command invoke error %d\n", __MY_LINE__);
393                 }
394             }
395         }
396         break;
397     case WBT_CMD_REQ_NONE:
398         mfprintf(tc[2], "WBT user none\n");
399         break;
400     case WBT_CMD_REQ_USER_DATA:
401         mfprintf(tc[2], "get user data = %s\n", uc->user_data.data);
402         break;
403     case WBT_CMD_REQ_GET_BLOCK_DONE:
404         mfprintf(tc[2], "get peer getblockdone %d done from %d\n", uc->blockdone.block_id,
405                  peer_aid);
406         break;
407     case WBT_CMD_REQ_SYNC:
408         mfprintf(tc[2], "get peer sync from %d\n", peer_aid);
409         break;
410     case WBT_CMD_RES_ERROR:
411         mfprintf(tc[2], "get req error %d from %d\n", peer_aid, uc->result);
412         break;
413     case WBT_CMD_REQ_ERROR:
414         mfprintf(tc[2], "get res error %d from %d\n", peer_aid, uc->result);
415         break;
416     case WBT_CMD_CANCEL:
417         mfprintf(tc[2], "get canncel [%s] command from %d\n", command_str[uc->command], peer_aid);
418         break;
419     default:
420         mfprintf(tc[2], "WBT callback unknown %d\n", uc->event);
421         break;
422     }
423 }
424