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