1 /*---------------------------------------------------------------------------*
2   Project:  TwlSDK - WXC - libraries -
3   File:     wxc_protocol_impl_wpb.c
4 
5   Copyright 2005-2009 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-12-16#$
14   $Rev: 9661 $
15   $Author: okubata_ryoma $
16  *---------------------------------------------------------------------------*/
17 
18 #include <nitro.h>
19 
20 #include <nitro/wxc/common.h>
21 #include <nitro/wxc/protocol.h>
22 #include <nitro/wxc/wxc_protocol_impl_wpb.h>
23 
24 #include <nitro/wxc.h>                 /* Use WXC_IsParentMode() */
25 
26 
27 /*****************************************************************************/
28 /* Declaration */
29 
30 static void WXCi_BeaconSendHook(WXCProtocolContext * protocol, WMParentParam *p_param);
31 static BOOL WXCi_BeaconRecvHook(WXCProtocolContext * protocol, const WMBssDesc *p_desc);
32 static void WXCi_PacketSendHook(WXCProtocolContext * protocol, WXCPacketInfo * packet);
33 static BOOL WXCi_PacketRecvHook(WXCProtocolContext * protocol, const WXCPacketInfo * packet);
34 static void WXCi_InitSequence(WXCProtocolContext * protocol, u16 send_max, u16 recv_max);
35 static BOOL WXCi_AddData(WXCProtocolContext * protocol, const void *send_buf, u32 send_size,
36                          void *recv_buf, u32 recv_max);
37 static BOOL WXCi_IsExecuting(WXCProtocolContext * protocol);
38 
39 static void pass_copy_to_structure(u8 *buf, PassBuffer * pb);
40 
41 
42 /*****************************************************************************/
43 /* Variables */
44 
45 static WXCImplWorkWpb impl_work_wpb;
46 
47 WXCProtocolImpl impl_wpb = {
48     "WPB",
49     WXCi_BeaconSendHook,
50     WXCi_BeaconRecvHook,
51     NULL,
52     WXCi_PacketSendHook,
53     WXCi_PacketRecvHook,
54     WXCi_InitSequence,
55     WXCi_AddData,
56     WXCi_IsExecuting,
57     &impl_work_wpb,
58 };
59 
60 
61 /*****************************************************************************/
62 /* Functions */
63 
64 /*---------------------------------------------------------------------------*
65   Name:         WXCi_GetProtocolImplWPB
66 
67   Description:  Gets the interface for the WPB chance encounter communication protocol.
68 
69   Arguments:    None.
70 
71   Returns:      None.
72  *---------------------------------------------------------------------------*/
WXCi_GetProtocolImplWPB(void)73 WXCProtocolImpl* WXCi_GetProtocolImplWPB(void)
74 {
75     return &impl_wpb;
76 }
77 
78 /*---------------------------------------------------------------------------*
79   Name:         PrintPassBuffer
80 
81   Description:  Output debug of the received content.
82 
83   Arguments:    None.
84 
85   Returns:      None.
86  *---------------------------------------------------------------------------*/
PrintPassBuffer(void * buf,const char * message)87 static void PrintPassBuffer(void *buf, const char *message)
88 {
89 #ifdef SDK_FINALROM
90 #pragma unused(message)
91 #endif
92 
93     static PassBuffer pass;
94     pass_copy_to_structure((u8 *)buf, &pass);
95 
96     OS_TPrintf("%s(req=%02X,res=%02X)\n", message, pass.req_count, pass.res_count);
97     if (pass.req_count == pass.req_count)
98     {
99         pass.req_count = pass.req_count;
100     }
101 }
102 
103 /*---------------------------------------------------------------------------*
104   Name:         pass_data_init_recv_bitmap
105 
106   Description:  Initializes the receive history bitmap.
107 
108   Arguments:    None.
109 
110   Returns:      None.
111  *---------------------------------------------------------------------------*/
pass_data_init_recv_bitmap(PassCtrl * pass_ctrl)112 static void pass_data_init_recv_bitmap(PassCtrl * pass_ctrl)
113 {
114     pass_ctrl->recv_bitmap = 0;
115     pass_ctrl->recv_bitmap_index = 0;
116 }
117 
118 /*---------------------------------------------------------------------------*
119   Name:         pass_InitBuf
120 
121   Description:  Initializes the PassBuffer structure.
122 
123   Arguments:    pb: PassBuffer structure
124 
125   Returns:      None.
126  *---------------------------------------------------------------------------*/
pass_InitBuf(PassBuffer * pb)127 static void pass_InitBuf(PassBuffer * pb)
128 {
129     pb->res_count = REQUEST_NONE;
130     pb->req_count = 0;
131     MI_CpuClear8(pb->buf, PASS_BUFFER_SIZE);
132 }
133 
134 /*---------------------------------------------------------------------------*
135   Name:         pass_ResetData
136 
137   Description:  Function called by xxxx.
138 
139   Arguments:    None.
140 
141   Returns:      None.
142  *---------------------------------------------------------------------------*/
pass_ResetData(WXCImplWorkWpb * wxc_work)143 static void pass_ResetData(WXCImplWorkWpb * wxc_work)
144 {
145     PassCtrl *pc;
146     pc = &wxc_work->pass_ctrl;
147 
148     pass_InitBuf(&(pc->send_buf));
149     pass_InitBuf(&(pc->recv_buf));
150     pass_data_init_recv_bitmap(pc);
151     pc->pre_send_count = REQUEST_NONE;
152     pc->reset_done = TRUE;
153     pc->send_done = FALSE;
154     pc->recv_done = FALSE;
155     pc->hardware_buffer_count = 0;
156 }
157 
158 /*---------------------------------------------------------------------------*
159   Name:         WXCi_BeaconSendHook
160 
161   Description:  Hook called at beacon update.
162 
163   Arguments:    protocol: WXCProtocolContext structure
164                 p_param: WMParentParam structure used for next beacon
165                          Change inside the function as necessary.
166 
167   Returns:      None.
168  *---------------------------------------------------------------------------*/
WXCi_BeaconSendHook(WXCProtocolContext * protocol,WMParentParam * p_param)169 void WXCi_BeaconSendHook(WXCProtocolContext * protocol, WMParentParam *p_param)
170 {
171 #pragma unused(protocol)
172 
173     /* Process embedding common chance encounter information in gameInfo
174      *Rewrite p_param->userGameInfo and p_param->userGameInfoLength
175      */
176 
177     static u16 gameInfo[2] ATTRIBUTE_ALIGN(32);
178     u16     gameInfoLength = sizeof gameInfo;
179 
180     /* The first 4 byte of gameInfo is reserved (0) */
181     MI_CpuClear16(gameInfo, sizeof gameInfo);
182 
183     if (gameInfoLength > WM_SIZE_USER_GAMEINFO)
184     {
185         SDK_ASSERT(FALSE);
186     }
187 
188     if (gameInfoLength)
189     {
190         p_param->userGameInfo = gameInfo;
191     }
192     p_param->userGameInfoLength = gameInfoLength;
193 }
194 
195 /*---------------------------------------------------------------------------*
196   Name:         WXCi_BeaconRecvHook
197 
198   Description:  Hook called for individual scanned beacons.
199 
200   Arguments:    protocol: WXCProtocolContext structure
201                 p_desc: Scanned WMBssDesc structure
202 
203   Returns:      If it is seen as connection target, return TRUE. Otherwise, return FALSE.
204  *---------------------------------------------------------------------------*/
WXCi_BeaconRecvHook(WXCProtocolContext * protocol,const WMBssDesc * p_desc)205 BOOL WXCi_BeaconRecvHook(WXCProtocolContext * protocol, const WMBssDesc *p_desc)
206 {
207 #pragma unused(protocol)
208 
209     BOOL    ret = FALSE;
210 
211     /* Determine how to handle common chance encounters here
212      * userGameInfo has at least 4 bytes. If the first 4 bytes are treated as a u32 value and the most-significant bit is 0, common chance encounters are supported.
213      *
214      */
215 
216     if (p_desc->gameInfoLength >=
217         (char *)&p_desc->gameInfo.ggid - (char *)&p_desc->gameInfo
218         + sizeof p_desc->gameInfo.ggid &&
219         p_desc->gameInfo.userGameInfoLength >= 4 &&
220         (*(u32 *)p_desc->gameInfo.userGameInfo & 1 << 31) == 0)
221     {
222         ret = TRUE;
223     }
224 
225     return ret;
226 }
227 
228 /*---------------------------------------------------------------------------*
229   Name:         pass_data_get_recv_bitmap
230 
231   Description:  Checks the receive history bitmap.
232 
233   Arguments:    seq_no: Sequence number
234 
235   Returns:      None.
236  *---------------------------------------------------------------------------*/
pass_data_get_recv_bitmap(WXCProtocolContext * protocol,int seq_no)237 static BOOL pass_data_get_recv_bitmap(WXCProtocolContext * protocol, int seq_no)
238 {
239     WXCImplWorkWpb *wxc_work = WXC_GetCurrentBlockImpl(protocol)->impl_work;
240     PassCtrl *pass_ctrl = &wxc_work->pass_ctrl;
241 
242     if (seq_no < pass_ctrl->recv_bitmap_index)
243     {
244         return TRUE;
245     }
246     if (seq_no >= pass_ctrl->recv_bitmap_index + 32)
247     {
248         return FALSE;
249     }
250     if (pass_ctrl->recv_bitmap & 1 << seq_no % 32)
251     {
252         return TRUE;
253     }
254     else
255     {
256         return FALSE;
257     }
258 }
259 
260 /*---------------------------------------------------------------------------*
261   Name:         pass_data_get_next_count
262 
263   Description:  Gets the next sequence number you will require from the other party.
264 
265   Arguments:    None.
266 
267   Returns:      None.
268  *---------------------------------------------------------------------------*/
pass_data_get_next_count(WXCProtocolContext * protocol)269 static u16 pass_data_get_next_count(WXCProtocolContext * protocol)
270 {
271     WXCImplWorkWpb *wxc_work = WXC_GetCurrentBlockImpl(protocol)->impl_work;
272     PassCtrl *pc = &wxc_work->pass_ctrl;
273 
274     int     count;
275 
276     if (pc->recv_bitmap_index >= wxc_work->my_pass_data.total_count)
277     {
278         return REQUEST_DONE;           /* All received */
279     }
280     count = pc->pre_send_count;
281     for (;;)
282     {
283         count++;
284         if (count >= wxc_work->my_pass_data.total_count || count >= pc->recv_bitmap_index + 32)
285         {
286             count = pc->recv_bitmap_index;
287         }
288         if (!pass_data_get_recv_bitmap(protocol, count))
289         {
290             pc->pre_send_count = count;
291             return (u16)count;
292         }
293         if (count == pc->pre_send_count)
294         {
295             /* Control should never reach here */
296             OS_TPrintf("Error ! %d %d %d %08X\n", pc->pre_send_count, pc->recv_bitmap_index,
297                        wxc_work->my_pass_data.total_count, pc->recv_bitmap);
298             return REQUEST_DONE;       /* All received */
299         }
300     }
301 }
302 
303 /*---------------------------------------------------------------------------*
304   Name:         pass_copy_to_buffer
305 
306   Description:  Copies from the PassBuffer structure to the WM receive buffer.
307 
308   Arguments:    pb: PassBuffer structure
309                 buf: WM send buffer
310 
311   Returns:      None.
312  *---------------------------------------------------------------------------*/
pass_copy_to_buffer(PassBuffer * pb,u8 * buf)313 static void pass_copy_to_buffer(PassBuffer * pb, u8 *buf)
314 {
315     int     i;
316 
317     *buf++ = (u8)(((pb->req_count) >> 8) & 0xff);       /* HI */
318     *buf++ = (u8)(pb->req_count & 0xff);        /* LO */
319 
320     *buf++ = (u8)(((pb->res_count) >> 8) & 0xff);       /* HI */
321     *buf++ = (u8)(pb->res_count & 0xff);        /* LO */
322 
323     for (i = 0; i < PASS_BUFFER_SIZE; i++)
324     {
325         *buf++ = pb->buf[i];
326     }
327 }
328 
329 /*---------------------------------------------------------------------------*
330   Name:         pass_DataToBuf
331 
332   Description:  Copies from the user send buffer to the PassBuffer structure.
333 
334   Arguments:    seq_no: Sequence number
335                 pb: PassBuffer structure
336                 buf: User send buffer
337 
338   Returns:      None.    {TRUE, TRUE, FALSE, TRUE},
339 
340  *---------------------------------------------------------------------------*/
pass_DataToBuf(WXCProtocolContext * protocol,int seq_no,PassBuffer * pb,PassData * pd)341 static void pass_DataToBuf(WXCProtocolContext * protocol, int seq_no, PassBuffer * pb,
342                            PassData * pd)
343 {
344     WXCImplWorkWpb *wxc_work = WXC_GetCurrentBlockImpl(protocol)->impl_work;
345     PassCtrl *pass_ctrl = &wxc_work->pass_ctrl;
346 
347     const u8 *src;
348     u8     *dest;
349 
350     pb->res_count = (u16)seq_no;
351 
352     if (seq_no != REQUEST_DONE && seq_no != REQUEST_NONE && seq_no != REQUEST_BYE)
353     {
354         src = pd->user_send_data + (seq_no * wxc_work->send_unit);
355         dest = pb->buf;
356         if (seq_no == wxc_work->my_pass_data.total_count - 1)
357         {
358             int     mod = wxc_work->my_pass_data.size % wxc_work->send_unit;
359             if (mod)
360             {
361                 MI_CpuCopy8(src, dest, (u32)mod);
362             }
363             else
364             {
365                 MI_CpuCopy8(src, dest, wxc_work->send_unit);
366             }
367         }
368         else
369         {
370             MI_CpuCopy8(src, dest, wxc_work->send_unit);
371         }
372     }
373 }
374 
375 /*---------------------------------------------------------------------------*
376   Name:         WXCi_PacketSendHook
377 
378   Description:  Hook called at MP packet transmission.
379 
380   Arguments:    protocol: WXCProtocolContext structure
381                 packet: WXCPacketInfo pointer configuring transmission packet information
382 
383   Returns:      None.
384  *---------------------------------------------------------------------------*/
WXCi_PacketSendHook(WXCProtocolContext * protocol,WXCPacketInfo * packet)385 void WXCi_PacketSendHook(WXCProtocolContext * protocol, WXCPacketInfo * packet)
386 {
387     WXCImplWorkWpb *wxc_work = WXC_GetCurrentBlockImpl(protocol)->impl_work;
388     PassCtrl *pass_ctrl = &wxc_work->pass_ctrl;
389 
390     /* WPB will operate differently depending whether one is communicating with the parent as a child or communicating with the child as a parent */
391     if (WXC_IsParentMode())
392     {
393         int     send_size = 0;
394         int     send_buf_count;
395         u8     *send_buf = packet->buffer;
396 
397         /* Set request number of own station */
398         if (pass_ctrl->recv_done == TRUE)
399         {
400             if (pass_ctrl->reset_done)
401             {
402                 pass_ctrl->send_buf.req_count = REQUEST_DONE;
403             }
404             else
405             {
406                 pass_ctrl->send_buf.req_count = REQUEST_BYE;
407             }
408         }
409         else
410         {
411             pass_ctrl->send_buf.req_count = pass_data_get_next_count(protocol);
412             if (pass_ctrl->send_buf.req_count == REQUEST_DONE)
413             {
414                 pass_ctrl->recv_done = TRUE;
415             }
416         }
417 
418         /* Set data to the other party's request */
419         if (pass_ctrl->send_done)
420         {
421             send_buf_count = REQUEST_NONE;
422         }
423         else
424         {
425             send_buf_count = pass_ctrl->recv_buf.req_count;
426         }
427         pass_DataToBuf(protocol, send_buf_count, &(pass_ctrl->send_buf), &wxc_work->my_pass_data);
428 
429         /* Copy from send_buf to send buffer */
430         pass_copy_to_buffer(&(pass_ctrl->send_buf), send_buf);
431 
432 #ifdef DEBUG
433         OS_TPrintf("parent send->%x req->%x\n", send_buf_count, pass_ctrl->send_buf.req_count);
434 #endif
435         send_size = PASS_PACKET_SIZE;
436 
437         /* Specify packet size */
438         packet->length = (u16)MATH_ROUNDUP(4 + wxc_work->send_unit, 2);
439 
440 #ifdef DEBUG
441         PrintPassBuffer(packet->buffer, "parent send");
442 #endif
443     }
444     else
445     {
446         int     peer_request;
447 
448         /* Set request number of own station */
449         if (pass_ctrl->recv_done == TRUE)
450         {
451             if (pass_ctrl->reset_done)
452             {
453                 pass_ctrl->send_buf.req_count = REQUEST_DONE;
454             }
455             else
456             {
457                 pass_ctrl->send_buf.req_count = REQUEST_BYE;
458             }
459         }
460         else
461         {
462             pass_ctrl->send_buf.req_count = pass_data_get_next_count(protocol);
463             if (pass_ctrl->send_buf.req_count == REQUEST_DONE)
464             {
465                 pass_ctrl->recv_done = TRUE;
466             }
467         }
468 
469         /* Set data matching the other party's request number */
470         peer_request = (int)(pass_ctrl->recv_buf.req_count);
471         pass_DataToBuf(protocol, peer_request, &(pass_ctrl->send_buf), &wxc_work->my_pass_data);
472 
473         /* Copy from send_buf to send buffer */
474         pass_copy_to_buffer(&(pass_ctrl->send_buf), packet->buffer);
475 
476 #ifdef DEBUG
477         OS_TPrintf("child send->%x req->%x\n", peer_request, pass_ctrl.send_buf.req_count);
478 #endif
479         /* Specify packet size */
480         packet->length = (u16)MATH_ROUNDUP(4 + wxc_work->send_unit, 2);
481 #ifdef DEBUG
482         PrintPassBuffer(packet->buffer, "child send");
483 #endif
484     }
485 }
486 
487 /*---------------------------------------------------------------------------*
488   Name:         pass_copy_to_structure
489 
490   Description:  Copies from the WM receive buffer to the PassBuffer structure.
491 
492   Arguments:    buf: WM receive buffer
493                 pb: PassBuffer structure
494 
495   Returns:      None.
496  *---------------------------------------------------------------------------*/
pass_copy_to_structure(u8 * buf,PassBuffer * pb)497 static void pass_copy_to_structure(u8 *buf, PassBuffer * pb)
498 {
499     int     i;
500 
501     pb->req_count = (u16)(((u32)(*buf++)) << 8);        /* HI */
502     pb->req_count += (u16)(*buf++);    /* LO */
503 
504     pb->res_count = (u16)(((u32)(*buf++)) << 8);        /* HI */
505     pb->res_count += (u16)(*buf++);    /* LO */
506 
507     for (i = 0; i < PASS_BUFFER_SIZE; i++)
508     {
509         pb->buf[i] = *buf++;
510     }
511 }
512 
513 /*---------------------------------------------------------------------------*
514   Name:         pass_data_set_recv_bitmap
515 
516   Description:  Sets the receive history bitmap.
517 
518   Arguments:    aid: AID (because receive buffer is managed for each AID)
519                 seq_no: Sequence number
520 
521   Returns:      BOOL: FALSE/already checked.
522  *---------------------------------------------------------------------------*/
pass_data_set_recv_bitmap(WXCProtocolContext * protocol,int seq_no)523 static BOOL pass_data_set_recv_bitmap(WXCProtocolContext * protocol, int seq_no)
524 {
525     WXCImplWorkWpb *wxc_work = WXC_GetCurrentBlockImpl(protocol)->impl_work;
526     PassCtrl *pass_ctrl = &wxc_work->pass_ctrl;
527 
528     if (seq_no < pass_ctrl->recv_bitmap_index)
529     {
530         return FALSE;
531     }
532     if (seq_no >= pass_ctrl->recv_bitmap_index + 32)
533     {
534         return FALSE;
535     }
536     if (pass_ctrl->recv_bitmap & 1 << seq_no % 32)
537     {
538         return FALSE;
539     }
540     pass_ctrl->recv_bitmap |= 1 << seq_no % 32;
541     while (pass_ctrl->recv_bitmap & 1 << pass_ctrl->recv_bitmap_index % 32)
542     {
543         pass_ctrl->recv_bitmap &= ~(1 << pass_ctrl->recv_bitmap_index++ % 32);
544     }
545     return TRUE;
546 }
547 
548 /*---------------------------------------------------------------------------*
549   Name:         pass_BufToData
550 
551   Description:  Copies data from the PassBuffer structure to the user receive buffer.
552 
553   Arguments:    pb: PassBuffer structure
554                 buf: User receive buffer
555 
556   Returns:      None.
557  *---------------------------------------------------------------------------*/
pass_BufToData(WXCProtocolContext * protocol,PassBuffer * pb,PassCtrl * pctrl)558 static void pass_BufToData(WXCProtocolContext * protocol, PassBuffer * pb, PassCtrl * pctrl)
559 {
560     WXCImplWorkWpb *wxc_work = WXC_GetCurrentBlockImpl(protocol)->impl_work;
561 
562     int     res_count;
563     u8     *src, *dest;
564 
565     res_count = (int)pb->res_count;
566     src = pb->buf;
567 
568     if (pctrl->user_recv_buffer == NULL)
569     {
570         return;
571     }
572 
573     dest = pctrl->user_recv_buffer + (res_count * PASS_BUFFER_SIZE);
574     if (res_count == wxc_work->my_pass_data.total_count - 1)
575     {
576         int     mod = wxc_work->my_pass_data.size % wxc_work->recv_unit;
577         if (mod)
578         {
579             MI_CpuCopy8(src, dest, (u32)mod);
580         }
581         else
582         {
583             MI_CpuCopy8(src, dest, wxc_work->recv_unit);
584         }
585     }
586     else
587     {
588         MI_CpuCopy8(src, dest, wxc_work->recv_unit);
589     }
590 }
591 
disconnect_callback(PassCtrl * pass_ctrl)592 static void disconnect_callback(PassCtrl * pass_ctrl)
593 {
594     if (!(pass_ctrl->reset_done == FALSE && pass_ctrl->recv_done))
595     {
596         pass_ctrl->reset_done = FALSE;
597         pass_ctrl->recv_done = TRUE;
598     }
599 }
600 
601 /*---------------------------------------------------------------------------*
602   Name:         WXCi_PacketRecvHook
603 
604   Description:  Hook called at MP packet reception.
605 
606   Arguments:    protocol: WXCProtocolContext structure
607                 packet: WXCPacketInfo pointer configuring reception packet information
608 
609   Returns:      If a single data exchange is completed, return TRUE.
610  *---------------------------------------------------------------------------*/
WXCi_PacketRecvHook(WXCProtocolContext * protocol,const WXCPacketInfo * packet)611 BOOL WXCi_PacketRecvHook(WXCProtocolContext * protocol, const WXCPacketInfo * packet)
612 {
613     WXCImplWorkWpb *wpb_work = WXC_GetCurrentBlockImpl(protocol)->impl_work;
614     PassCtrl *pass_ctrl = &wpb_work->pass_ctrl;
615 
616     /* WPB will operate differently depending whether one is communicating with the parent as a child or communicating with the child as a parent */
617     if (WXC_IsParentMode())
618     {
619         PrintPassBuffer(packet->buffer, "parent recv");
620 
621         if (packet->buffer == NULL || packet->length == 0)
622         {
623             return FALSE;              /* Continue communication */
624         }
625 
626         /* First, copy data from receive buffer to pass_recv_buf */
627         pass_copy_to_structure(((u8 *)packet->buffer), &(pass_ctrl->recv_buf));
628         if (pass_ctrl->recv_buf.req_count == REQUEST_BYE)
629         {
630 #ifdef DEBUG
631             OS_TPrintf("parent : get REQUEST_BYE\n");
632 #endif
633             wpb_work->executing = FALSE;        /* Cut off communication */
634             return TRUE;
635         }
636         if (pass_ctrl->reset_done == TRUE)
637         {
638             if (pass_ctrl->recv_done == FALSE)
639             {
640 #ifdef DEBUG
641                 OS_TPrintf("parent recv->%x\n", pass_ctrl->recv_buf.res_count);
642 #endif
643                 if (pass_ctrl->recv_buf.res_count < wpb_work->my_pass_data.total_count)
644                 {
645                     /* Insert a check in the receive history */
646                     if (TRUE == pass_data_set_recv_bitmap(protocol, pass_ctrl->recv_buf.res_count))
647                     {
648                         /* Save the received data */
649                         pass_BufToData(protocol, &(pass_ctrl->recv_buf), pass_ctrl);
650                     }
651                 }
652             }
653             else
654             {
655                 if (pass_ctrl->recv_buf.req_count == REQUEST_DONE)
656                 {
657                     pass_ctrl->send_done = TRUE;
658                 }
659                 if (pass_ctrl->send_done == TRUE)
660                 {
661 
662                     /* When data transmission ends this side as well: */
663                     if (pass_ctrl->hardware_buffer_count < (HARDWARE_BUFFER_DUMMY_COUNT * 2))
664                     {
665                         /* Wait until execution arrives here four times */
666                         pass_ctrl->hardware_buffer_count++;
667                         return FALSE;  /* Continue communication */
668                     }
669 
670                     pass_ctrl->reset_done = FALSE;
671 
672                     /* End */
673                     return TRUE;
674                 }
675             }
676         }
677         return FALSE;                  /* Continue communication */
678     }
679     else
680     {
681         PrintPassBuffer(packet->buffer, "child recv");
682 
683         /* Protocol for communicating with the child device as a parent */
684         if (packet->buffer == NULL || packet->length == 0)
685         {
686             return FALSE;              /* Continue communication */
687         }
688 
689 #ifdef DEBUG
690         OS_TPrintf("child recv->%x\n", pass_ctrl->recv_buf.res_count);
691 #endif
692 
693         /* First, copy data from receive buffer to pass_recv_buf */
694         pass_copy_to_structure(((u8 *)packet->buffer), &(pass_ctrl->recv_buf));
695         if (pass_ctrl->recv_buf.req_count == REQUEST_BYE)
696         {
697 #ifdef DEBUG
698             OS_TPrintf("child: get REQUEST_BYE\n");
699 #endif
700             wpb_work->executing = FALSE;        /* Cut off communication */
701             return TRUE;
702         }
703         if (pass_ctrl->reset_done == TRUE)
704         {
705             if (packet->length < PASS_PACKET_SIZE)
706             {
707                 return FALSE;          /* Continue communication */
708             }
709             if (pass_ctrl->recv_done == FALSE)
710             {
711                 if (pass_ctrl->recv_buf.res_count < wpb_work->my_pass_data.total_count)
712                 {
713                     /* Insert a check in the receive history */
714                     if (TRUE == pass_data_set_recv_bitmap(protocol, pass_ctrl->recv_buf.res_count))
715                     {
716                         pass_BufToData(protocol, &(pass_ctrl->recv_buf), pass_ctrl);
717                     }
718                 }
719             }
720             else
721             {
722                 if (pass_ctrl->recv_buf.req_count == REQUEST_DONE)
723                 {
724                     pass_ctrl->send_done = TRUE;
725                 }
726                 if (pass_ctrl->send_done == TRUE)
727                 {
728 
729                     /* When data transmission ends this station as well: */
730                     if (pass_ctrl->hardware_buffer_count < HARDWARE_BUFFER_DUMMY_COUNT)
731                     {
732                         /* Wait until execution arrives here twice
733                            pass_ctrl->hardware_buffer_count++;
734                            return FALSE;        /* Continue communication */
735                     }
736 
737                     pass_ctrl->reset_done = FALSE;
738 
739                     /* End */
740                     return TRUE;
741                 }
742             }
743         }
744         return FALSE;                  /* Continue communication */
745     }
746     return FALSE;
747 }
748 
749 /*---------------------------------------------------------------------------*
750   Name:         WXCi_InitSequence
751 
752   Description:  Reinitializes the WXC library protocol.
753 
754   Arguments:    protocol: WXCProtocolContext structure
755                 send_max: Maximum send packet size
756                 recv_max: Maximum receive packet size
757 
758   Returns:      None.
759  *---------------------------------------------------------------------------*/
WXCi_InitSequence(WXCProtocolContext * protocol,u16 send_max,u16 recv_max)760 void WXCi_InitSequence(WXCProtocolContext * protocol, u16 send_max, u16 recv_max)
761 {
762     WXCImplWorkWpb *wpb_work = WXC_GetCurrentBlockImpl(protocol)->impl_work;
763 
764     /* 4 is the WPB packet header length.
765      * Apply it to this protocol (WPB is 512-byte)
766      * Be careful to not rewrite the ParentParam value!!
767      */
768     wpb_work->send_unit = (u16)(send_max - 4);  /* Should be 512 - 4 = 508 */
769     wpb_work->recv_unit = (u16)(recv_max - 4);  /* Should be 512 - 4 = 508 */
770 
771     /* Initialize the data receive management information */
772     MI_CpuClear32(wpb_work->recv_bitmap_buf, sizeof(wpb_work->recv_bitmap_buf));
773 
774     /* Initialize WPB relationship */
775     wpb_work->my_pass_data.total_count = 0;
776     wpb_work->my_pass_data.size = 0;
777     wpb_work->my_pass_data.user_send_data = NULL;
778 
779     wpb_work->executing = TRUE;
780 }
781 
782 /*---------------------------------------------------------------------------*
783   Name:         WXCi_AddData
784 
785   Description:  Configures the block data exchange.
786 
787   Arguments:    protocol: WXCProtocolContext structure
788                 send_buf: Send buffer
789                 send_size: Send buffer size
790                 recv_buf: Receive buffer
791                 recv_max: Receive buffer size
792 
793   Returns:      If registration is possible, return TRUE after configuration.
794  *---------------------------------------------------------------------------*/
WXCi_AddData(WXCProtocolContext * protocol,const void * send_buf,u32 send_size,void * recv_buf,u32 recv_max)795 BOOL WXCi_AddData(WXCProtocolContext * protocol, const void *send_buf, u32 send_size,
796                   void *recv_buf, u32 recv_max)
797 {
798     WXCImplWorkWpb *wpb_work = WXC_GetCurrentBlockImpl(protocol)->impl_work;
799 
800     /* Initialize data buffer */
801     pass_ResetData(WXC_GetCurrentBlockImpl(protocol)->impl_work);
802 
803     /* Also connect the common protocol members' send and receive buffers */
804     protocol->send.buffer = (void *)send_buf;
805     protocol->send.length = (u16)send_size;
806     protocol->send.checksum = MATH_CalcChecksum8(send_buf, send_size);
807     protocol->recv.buffer = recv_buf;
808     protocol->recv.buffer_max = (u16)recv_max;
809     MI_CpuClear32(wpb_work->recv_bitmap_buf, sizeof(wpb_work->recv_bitmap_buf));
810 
811     /* Configure WPB side buffer */
812     wpb_work->my_pass_data.total_count =
813         (int)(recv_max / PASS_BUFFER_SIZE) + ((recv_max % PASS_BUFFER_SIZE) ? 1 : 0);
814     wpb_work->my_pass_data.size = (int)send_size;
815     wpb_work->my_pass_data.user_send_data = send_buf;
816 
817     wpb_work->pass_ctrl.user_recv_buffer = recv_buf;
818 
819     return TRUE;
820 }
821 
822 /*---------------------------------------------------------------------------*
823   Name:         WXCi_IsExecuting
824 
825   Description:  Checks whether data is currently being exchanged.
826 
827   Arguments:    None.
828 
829   Returns:      Return TRUE if data is currently being exchanged.
830  *---------------------------------------------------------------------------*/
WXCi_IsExecuting(WXCProtocolContext * protocol)831 BOOL WXCi_IsExecuting(WXCProtocolContext * protocol)
832 {
833     WXCImplWorkWpb *wpb_work = WXC_GetCurrentBlockImpl(protocol)->impl_work;
834 
835     return wpb_work->executing;
836 }
837