mirror of
https://github.com/Ninjdai1/pokeemerald.git
synced 2024-12-26 19:54:21 +01:00
1399 lines
46 KiB
C
1399 lines
46 KiB
C
#include "global.h"
|
|
#include "librfu.h"
|
|
#include "link_rfu.h"
|
|
|
|
#define RN_ACCEPT 0x01
|
|
#define RN_NAME_TIMER_CLEAR 0x02
|
|
#define RN_DISCONNECT 0x04
|
|
|
|
#define LINK_RECOVERY_OFF 0x00
|
|
#define LINK_RECOVERY_START 0x01
|
|
#define LINK_RECOVERY_EXE 0x02
|
|
#define LINK_RECOVERY_IMPOSSIBLE 0x04
|
|
|
|
#define FSP_ON 0x01
|
|
#define FSP_START 0x02
|
|
|
|
LINK_MANAGER lman;
|
|
|
|
static void rfu_LMAN_clearVariables(void);
|
|
static void rfu_LMAN_settingPCSWITCH(u32 rand);
|
|
static void rfu_LMAN_REQ_callback(u16 reqCommandId, u16 reqResult);
|
|
static void rfu_LMAN_MSC_callback(u16 reqCommandId);
|
|
static void rfu_LMAN_PARENT_checkRecvChildName(void);
|
|
static void rfu_LMAN_CHILD_checkSendChildName(void);
|
|
static void rfu_LMAN_CHILD_checkSendChildName2(void);
|
|
static void rfu_LMAN_CHILD_linkRecoveryProcess(void);
|
|
static u8 rfu_LMAN_CHILD_checkEnableParentCandidate(void);
|
|
static void rfu_LMAN_occureCallback(u8 msg, u8 param_count);
|
|
static void rfu_LMAN_disconnect(u8 bmDisconnectSlot);
|
|
static void rfu_LMAN_reflectCommunicationStatus(u8 bm_disconnectedSlot);
|
|
static void rfu_LMAN_checkNICommunicateStatus(void);
|
|
static void rfu_LMAN_managerChangeAgbClockMaster(void);
|
|
|
|
u32 rfu_LMAN_REQBN_softReset_and_checkID(void)
|
|
{
|
|
u32 id = rfu_REQBN_softReset_and_checkID();
|
|
if (id == RFU_ID)
|
|
lman.RFU_powerOn_flag = 1;
|
|
if (lman.state != LMAN_FORCED_STOP_AND_RFU_RESET && lman.state != LMAN_STATE_SOFT_RESET_AND_CHECK_ID)
|
|
{
|
|
lman.state = lman.next_state = LMAN_STATE_READY;
|
|
}
|
|
lman.pcswitch_flag = 0;
|
|
lman.reserveDisconnectSlot_flag = 0;
|
|
lman.acceptCount = 0;
|
|
lman.acceptSlot_flag = 0;
|
|
lman.parent_child = MODE_NEUTRAL;
|
|
rfu_LMAN_managerChangeAgbClockMaster();
|
|
return id;
|
|
}
|
|
|
|
void rfu_LMAN_REQ_sendData(bool8 clockChangeFlag)
|
|
{
|
|
if (gRfuLinkStatus->parentChild == MODE_CHILD)
|
|
{
|
|
if (lman.childClockSlave_flag == RFU_CHILD_CLOCK_SLAVE_ON)
|
|
clockChangeFlag = TRUE;
|
|
else
|
|
clockChangeFlag = FALSE;
|
|
}
|
|
else
|
|
lman.parentAck_flag = 0;
|
|
rfu_REQ_sendData(clockChangeFlag);
|
|
}
|
|
|
|
u8 rfu_LMAN_initializeManager(void (*LMAN_callback_p)(u8, u8), void (*MSC_callback_p)(u16))
|
|
{
|
|
if (LMAN_callback_p == NULL)
|
|
{
|
|
return LMAN_ERROR_ILLEGAL_PARAMETER;
|
|
}
|
|
CpuFill16(0, &lman, sizeof(struct linkManagerTag));
|
|
lman.parent_child = MODE_NEUTRAL;
|
|
lman.LMAN_callback = LMAN_callback_p;
|
|
lman.MSC_callback = MSC_callback_p;
|
|
rfu_setMSCCallback(rfu_LMAN_MSC_callback);
|
|
rfu_setREQCallback(rfu_LMAN_REQ_callback);
|
|
return 0;
|
|
}
|
|
|
|
static void rfu_LMAN_endManager(void)
|
|
{
|
|
CpuFill16(0, &lman, sizeof(struct linkManagerTag) - 8);
|
|
lman.parent_child = MODE_NEUTRAL;
|
|
}
|
|
|
|
void rfu_LMAN_initializeRFU(INIT_PARAM *init_parameters)
|
|
{
|
|
rfu_LMAN_clearVariables();
|
|
lman.state = LMAN_STATE_SOFT_RESET_AND_CHECK_ID;
|
|
lman.next_state = LMAN_STATE_RESET;
|
|
lman.init_param = init_parameters;
|
|
lman.linkRecovery_enable = init_parameters->linkRecovery_enable;
|
|
lman.linkRecoveryTimer.count_max = init_parameters->linkRecovery_period;
|
|
lman.NI_failCounter_limit = init_parameters->NI_failCounter_limit;
|
|
if (init_parameters->fastSearchParent_flag)
|
|
{
|
|
lman.fastSearchParent_flag = FSP_ON;
|
|
}
|
|
}
|
|
|
|
static void rfu_LMAN_clearVariables(void)
|
|
{
|
|
u8 i;
|
|
|
|
lman.state = lman.next_state = LMAN_STATE_READY;
|
|
lman.parent_child = MODE_NEUTRAL;
|
|
lman.pcswitch_flag = 0;
|
|
lman.child_slot = 0;
|
|
lman.connectSlot_flag_old = 0;
|
|
lman.nameAcceptTimer.active = 0;
|
|
lman.linkRecoveryTimer.active = 0;
|
|
for (i = 0; i < RFU_CHILD_MAX; i++)
|
|
{
|
|
lman.nameAcceptTimer.count[i] = 0;
|
|
lman.linkRecoveryTimer.count[i] = 0;
|
|
}
|
|
}
|
|
|
|
void rfu_LMAN_powerDownRFU(void)
|
|
{
|
|
lman.state = LMAN_STATE_STOP_MODE;
|
|
}
|
|
|
|
u8 rfu_LMAN_establishConnection(u8 parent_child, u16 connect_period, u16 name_accept_period, u16 *acceptable_serialNo_list)
|
|
{
|
|
u8 i;
|
|
u16 *serial_list;
|
|
|
|
if (lman.state != LMAN_STATE_READY && (lman.state != LMAN_STATE_WAIT_RECV_CHILD_NAME || parent_child != MODE_PARENT))
|
|
{
|
|
lman.param[0] = 1;
|
|
rfu_LMAN_occureCallback(LMAN_MSG_LMAN_API_ERROR_RETURN, 1);
|
|
return LMAN_ERROR_MANAGER_BUSY;
|
|
}
|
|
if (rfu_getMasterSlave() == AGB_CLK_SLAVE)
|
|
{
|
|
lman.param[0] = 2;
|
|
rfu_LMAN_occureCallback(LMAN_MSG_LMAN_API_ERROR_RETURN, 1);
|
|
return LMAN_ERROR_AGB_CLK_SLAVE;
|
|
}
|
|
for (i = 0, serial_list = acceptable_serialNo_list; i < 16; i++)
|
|
{
|
|
if (*serial_list++ == 0xFFFF)
|
|
{
|
|
break;
|
|
}
|
|
}
|
|
if (i == 16)
|
|
{
|
|
lman.param[0] = 4;
|
|
rfu_LMAN_occureCallback(LMAN_MSG_LMAN_API_ERROR_RETURN, 1);
|
|
return LMAN_ERROR_ILLEGAL_PARAMETER;
|
|
}
|
|
if (parent_child > MODE_PARENT)
|
|
{
|
|
lman.pcswitch_flag = PCSWITCH_1ST_SC_START;
|
|
parent_child = MODE_PARENT;
|
|
connect_period = 0;
|
|
}
|
|
else
|
|
{
|
|
lman.pcswitch_flag = 0;
|
|
}
|
|
if (parent_child != MODE_CHILD)
|
|
{
|
|
lman.state = LMAN_STATE_START_SEARCH_CHILD;
|
|
}
|
|
else
|
|
{
|
|
lman.state = LMAN_STATE_START_SEARCH_PARENT;
|
|
if (lman.fastSearchParent_flag)
|
|
{
|
|
lman.fastSearchParent_flag = FSP_START;
|
|
}
|
|
}
|
|
lman.parent_child = parent_child;
|
|
lman.connect_period = connect_period;
|
|
lman.nameAcceptTimer.count_max = name_accept_period;
|
|
lman.acceptable_serialNo_list = acceptable_serialNo_list;
|
|
return 0;
|
|
}
|
|
|
|
u8 rfu_LMAN_CHILD_connectParent(u16 parentId, u16 connect_period)
|
|
{
|
|
u8 i;
|
|
|
|
if (lman.state != LMAN_STATE_READY && (lman.state < 9 || lman.state > 11))
|
|
{
|
|
lman.param[0] = 1;
|
|
rfu_LMAN_occureCallback(LMAN_MSG_LMAN_API_ERROR_RETURN, 1);
|
|
return LMAN_ERROR_MANAGER_BUSY;
|
|
}
|
|
if (rfu_getMasterSlave() == AGB_CLK_SLAVE)
|
|
{
|
|
lman.param[0] = 2;
|
|
rfu_LMAN_occureCallback(LMAN_MSG_LMAN_API_ERROR_RETURN, 1);
|
|
return LMAN_ERROR_AGB_CLK_SLAVE;
|
|
}
|
|
for (i = 0; i < gRfuLinkStatus->findParentCount; i++)
|
|
{
|
|
if (gRfuLinkStatus->partner[i].id == parentId)
|
|
{
|
|
break;
|
|
}
|
|
}
|
|
if (gRfuLinkStatus->findParentCount == 0 || i == gRfuLinkStatus->findParentCount)
|
|
{
|
|
lman.param[0] = 3;
|
|
rfu_LMAN_occureCallback(LMAN_MSG_LMAN_API_ERROR_RETURN, 1);
|
|
return LMAN_ERROR_PID_NOT_FOUND;
|
|
}
|
|
if (lman.state == LMAN_STATE_READY || lman.state == LMAN_STATE_START_SEARCH_PARENT)
|
|
{
|
|
lman.state = LMAN_STATE_START_CONNECT_PARENT;
|
|
lman.next_state = LMAN_STATE_POLL_CONNECT_PARENT;
|
|
}
|
|
else
|
|
{
|
|
lman.state = LMAN_STATE_END_SEARCH_PARENT;
|
|
lman.next_state = LMAN_STATE_START_CONNECT_PARENT;
|
|
}
|
|
lman.work = parentId;
|
|
lman.connect_period = connect_period;
|
|
if (lman.pcswitch_flag != 0)
|
|
{
|
|
lman.pcswitch_flag = PCSWITCH_CP;
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
static void rfu_LMAN_PARENT_stopWaitLinkRecoveryAndDisconnect(u8 bm_targetSlot)
|
|
{
|
|
u8 i;
|
|
|
|
if ((bm_targetSlot & lman.linkRecoveryTimer.active) == 0)
|
|
return;
|
|
lman.linkRecoveryTimer.active &= ~bm_targetSlot;
|
|
for (i = 0; i < RFU_CHILD_MAX; i++)
|
|
{
|
|
if ((bm_targetSlot >> i) & 1)
|
|
{
|
|
lman.linkRecoveryTimer.count[i] = 0;
|
|
}
|
|
}
|
|
i = gRfuLinkStatus->linkLossSlotFlag & bm_targetSlot;
|
|
if (i)
|
|
{
|
|
rfu_LMAN_disconnect(i);
|
|
}
|
|
lman.param[0] = i;
|
|
rfu_LMAN_occureCallback(LMAN_MSG_LINK_RECOVERY_FAILED_AND_DISCONNECTED, i);
|
|
}
|
|
|
|
void rfu_LMAN_stopManager(u8 forced_stop_and_RFU_reset_flag)
|
|
{
|
|
u8 msg = 0;
|
|
lman.pcswitch_flag = 0;
|
|
if (forced_stop_and_RFU_reset_flag)
|
|
{
|
|
rfu_LMAN_clearVariables();
|
|
lman.state = LMAN_FORCED_STOP_AND_RFU_RESET;
|
|
return;
|
|
}
|
|
switch (lman.state)
|
|
{
|
|
case LMAN_STATE_START_SEARCH_CHILD:
|
|
lman.state = LMAN_STATE_WAIT_RECV_CHILD_NAME;
|
|
lman.next_state = LMAN_STATE_READY;
|
|
msg = LMAN_MSG_SEARCH_CHILD_PERIOD_EXPIRED;
|
|
break;
|
|
case LMAN_STATE_POLL_SEARCH_CHILD:
|
|
lman.state = LMAN_STATE_END_SEARCH_CHILD;
|
|
lman.next_state = LMAN_STATE_WAIT_RECV_CHILD_NAME;
|
|
break;
|
|
case LMAN_STATE_END_SEARCH_CHILD:
|
|
lman.state = LMAN_STATE_END_SEARCH_CHILD;
|
|
lman.next_state = LMAN_STATE_WAIT_RECV_CHILD_NAME;
|
|
break;
|
|
case LMAN_STATE_WAIT_RECV_CHILD_NAME:
|
|
break;
|
|
case LMAN_STATE_START_SEARCH_PARENT:
|
|
lman.state = lman.next_state = LMAN_STATE_READY;
|
|
msg = LMAN_MSG_SEARCH_PARENT_PERIOD_EXPIRED;
|
|
break;
|
|
case LMAN_STATE_POLL_SEARCH_PARENT:
|
|
lman.state = LMAN_STATE_END_SEARCH_PARENT;
|
|
lman.next_state = LMAN_STATE_READY;
|
|
break;
|
|
case LMAN_STATE_END_SEARCH_PARENT:
|
|
lman.state = LMAN_STATE_END_SEARCH_PARENT;
|
|
lman.next_state = LMAN_STATE_READY;
|
|
break;
|
|
case LMAN_STATE_START_CONNECT_PARENT:
|
|
lman.state = lman.next_state = LMAN_STATE_READY;
|
|
msg = LMAN_MSG_CONNECT_PARENT_FAILED;
|
|
break;
|
|
case LMAN_STATE_POLL_CONNECT_PARENT:
|
|
lman.state = LMAN_STATE_END_CONNECT_PARENT;
|
|
break;
|
|
case LMAN_STATE_END_CONNECT_PARENT:
|
|
lman.state = LMAN_STATE_END_CONNECT_PARENT;
|
|
break;
|
|
case LMAN_STATE_SEND_CHILD_NAME:
|
|
break;
|
|
case LMAN_STATE_START_LINK_RECOVERY:
|
|
lman.state = lman.state_bak[0];
|
|
lman.next_state = lman.state_bak[1];
|
|
rfu_LMAN_disconnect(gRfuLinkStatus->linkLossSlotFlag);
|
|
lman.param[0] = gRfuLinkStatus->linkLossSlotFlag;
|
|
rfu_LMAN_occureCallback(LMAN_MSG_LINK_RECOVERY_FAILED_AND_DISCONNECTED, 1);
|
|
return;
|
|
case LMAN_STATE_POLL_LINK_RECOVERY:
|
|
lman.state = LMAN_STATE_END_LINK_RECOVERY;
|
|
break;
|
|
case LMAN_STATE_END_LINK_RECOVERY:
|
|
lman.state = LMAN_STATE_END_LINK_RECOVERY;
|
|
break;
|
|
default:
|
|
lman.state = lman.next_state = LMAN_STATE_READY;
|
|
msg = LMAN_MSG_MANAGER_STOPPED;
|
|
break;
|
|
}
|
|
if (lman.state == LMAN_STATE_READY)
|
|
{
|
|
rfu_LMAN_occureCallback(msg, 0);
|
|
}
|
|
}
|
|
|
|
static bool8 rfu_LMAN_linkWatcher(u16 REQ_commandID)
|
|
{
|
|
u8 i;
|
|
u8 bm_linkLossSlot;
|
|
u8 reason;
|
|
u8 bm_linkRecoverySlot;
|
|
u8 bm_disconnectSlot;
|
|
|
|
bool8 disconnect_occure_flag = FALSE;
|
|
rfu_REQBN_watchLink(REQ_commandID, &bm_linkLossSlot, &reason, &bm_linkRecoverySlot);
|
|
if (bm_linkLossSlot)
|
|
{
|
|
lman.param[0] = bm_linkLossSlot;
|
|
lman.param[1] = reason;
|
|
if (lman.linkRecovery_enable)
|
|
{
|
|
lman.linkRecovery_start_flag = LINK_RECOVERY_START;
|
|
if (lman.parent_child == MODE_CHILD && reason == REASON_DISCONNECTED)
|
|
{
|
|
lman.linkRecovery_start_flag = LINK_RECOVERY_IMPOSSIBLE;
|
|
}
|
|
if (lman.linkRecovery_start_flag == LINK_RECOVERY_START)
|
|
{
|
|
for (i = 0; i < RFU_CHILD_MAX; i++)
|
|
{
|
|
if ((bm_linkLossSlot >> i) & 1)
|
|
{
|
|
lman.linkRecoveryTimer.active |= (1 << i);
|
|
lman.linkRecoveryTimer.count[i] = lman.linkRecoveryTimer.count_max;
|
|
}
|
|
}
|
|
rfu_LMAN_occureCallback(LMAN_MSG_LINK_LOSS_DETECTED_AND_START_RECOVERY, 1);
|
|
}
|
|
else
|
|
{
|
|
lman.linkRecovery_start_flag = 0;
|
|
rfu_LMAN_disconnect(bm_linkLossSlot);
|
|
disconnect_occure_flag = TRUE;
|
|
rfu_LMAN_occureCallback(LMAN_MSG_LINK_RECOVERY_FAILED_AND_DISCONNECTED, 1);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
rfu_LMAN_disconnect(bm_linkLossSlot);
|
|
disconnect_occure_flag = TRUE;
|
|
rfu_LMAN_occureCallback(LMAN_MSG_LINK_LOSS_DETECTED_AND_DISCONNECTED, 2);
|
|
}
|
|
rfu_LMAN_managerChangeAgbClockMaster();
|
|
}
|
|
if (gRfuLinkStatus->parentChild == MODE_PARENT)
|
|
{
|
|
if (bm_linkRecoverySlot)
|
|
{
|
|
for (i = 0; i < RFU_CHILD_MAX; i++)
|
|
{
|
|
if ((lman.linkRecoveryTimer.active >> i) & 1 && (bm_linkRecoverySlot >> i) & 1)
|
|
{
|
|
lman.linkRecoveryTimer.count[i] = 0;
|
|
}
|
|
}
|
|
lman.linkRecoveryTimer.active &= ~bm_linkRecoverySlot;
|
|
lman.param[0] = bm_linkRecoverySlot;
|
|
rfu_LMAN_occureCallback(LMAN_MSG_LINK_RECOVERY_SUCCESSED, 1);
|
|
}
|
|
if (lman.linkRecoveryTimer.active)
|
|
{
|
|
bm_disconnectSlot = 0;
|
|
for (i = 0; i < RFU_CHILD_MAX; i++)
|
|
{
|
|
if ((lman.linkRecoveryTimer.active >> i) & 1 && lman.linkRecoveryTimer.count[i] && --lman.linkRecoveryTimer.count[i] == 0)
|
|
{
|
|
lman.linkRecoveryTimer.active &= ~(1 << i);
|
|
bm_disconnectSlot |= (1 << i);
|
|
}
|
|
}
|
|
if (bm_disconnectSlot)
|
|
{
|
|
rfu_LMAN_disconnect(bm_disconnectSlot);
|
|
disconnect_occure_flag = TRUE;
|
|
lman.param[0] = bm_disconnectSlot;
|
|
rfu_LMAN_occureCallback(LMAN_MSG_LINK_RECOVERY_FAILED_AND_DISCONNECTED, 1);
|
|
}
|
|
}
|
|
if (!lman.linkRecoveryTimer.active)
|
|
{
|
|
lman.linkRecovery_start_flag = 0;
|
|
}
|
|
}
|
|
return disconnect_occure_flag;
|
|
}
|
|
|
|
void rfu_LMAN_syncVBlank(void)
|
|
{
|
|
if (rfu_syncVBlank())
|
|
{
|
|
rfu_LMAN_occureCallback(LMAN_MSG_WATCH_DOG_TIMER_ERROR, 0);
|
|
rfu_LMAN_managerChangeAgbClockMaster();
|
|
}
|
|
}
|
|
|
|
void rfu_LMAN_manager_entity(u32 rand)
|
|
{
|
|
u8 msg;
|
|
|
|
if (lman.LMAN_callback == NULL && lman.state != LMAN_STATE_READY)
|
|
{
|
|
lman.state = LMAN_STATE_READY;
|
|
return;
|
|
}
|
|
if (lman.pcswitch_flag)
|
|
{
|
|
rfu_LMAN_settingPCSWITCH(rand);
|
|
}
|
|
while (1)
|
|
{
|
|
if (lman.state != LMAN_STATE_READY)
|
|
{
|
|
rfu_waitREQComplete();
|
|
lman.active = 1;
|
|
switch (lman.state)
|
|
{
|
|
case LMAN_FORCED_STOP_AND_RFU_RESET:
|
|
if (rfu_LMAN_REQBN_softReset_and_checkID() == RFU_ID)
|
|
{
|
|
msg=LMAN_MSG_MANAGER_FORCED_STOPPED_AND_RFU_RESET;
|
|
}
|
|
else
|
|
{
|
|
msg=LMAN_MSG_RFU_FATAL_ERROR;
|
|
}
|
|
lman.state = lman.next_state = LMAN_STATE_READY;
|
|
rfu_LMAN_occureCallback(msg, 0);
|
|
break;
|
|
case LMAN_STATE_SOFT_RESET_AND_CHECK_ID:
|
|
if (rfu_LMAN_REQBN_softReset_and_checkID() == RFU_ID)
|
|
{
|
|
lman.state = lman.next_state;
|
|
lman.next_state = LMAN_STATE_CONFIG_SYSTEM;
|
|
}
|
|
else
|
|
{
|
|
lman.state = lman.next_state = LMAN_STATE_READY;
|
|
rfu_LMAN_occureCallback(LMAN_MSG_RFU_FATAL_ERROR, 0);
|
|
}
|
|
break;
|
|
case LMAN_STATE_RESET:
|
|
rfu_REQ_reset();
|
|
break;
|
|
case LMAN_STATE_CONFIG_SYSTEM:
|
|
rfu_REQ_configSystem(lman.init_param->availSlot_flag, lman.init_param->maxMFrame, lman.init_param->MC_TimerCount);
|
|
break;
|
|
case LMAN_STATE_CONFIG_GAME_DATA:
|
|
rfu_REQ_configGameData(lman.init_param->mboot_flag, lman.init_param->serialNo, (const u8 *)lman.init_param->gameName, lman.init_param->userName);
|
|
break;
|
|
case LMAN_STATE_START_SEARCH_CHILD:
|
|
rfu_REQ_startSearchChild();
|
|
break;
|
|
case LMAN_STATE_POLL_SEARCH_CHILD:
|
|
rfu_REQ_pollSearchChild();
|
|
break;
|
|
case LMAN_STATE_END_SEARCH_CHILD:
|
|
rfu_REQ_endSearchChild();
|
|
break;
|
|
case LMAN_STATE_WAIT_RECV_CHILD_NAME:
|
|
break;
|
|
case LMAN_STATE_START_SEARCH_PARENT:
|
|
rfu_REQ_startSearchParent();
|
|
break;
|
|
case LMAN_STATE_POLL_SEARCH_PARENT:
|
|
rfu_REQ_pollSearchParent();
|
|
break;
|
|
case LMAN_STATE_END_SEARCH_PARENT:
|
|
rfu_REQ_endSearchParent();
|
|
break;
|
|
case LMAN_STATE_START_CONNECT_PARENT:
|
|
rfu_REQ_startConnectParent(lman.work);
|
|
break;
|
|
case LMAN_STATE_POLL_CONNECT_PARENT:
|
|
rfu_REQ_pollConnectParent();
|
|
break;
|
|
case LMAN_STATE_END_CONNECT_PARENT:
|
|
rfu_REQ_endConnectParent();
|
|
break;
|
|
case LMAN_STATE_SEND_CHILD_NAME:
|
|
break;
|
|
case LMAN_STATE_START_LINK_RECOVERY:
|
|
rfu_REQ_CHILD_startConnectRecovery(gRfuLinkStatus->linkLossSlotFlag);
|
|
break;
|
|
case LMAN_STATE_POLL_LINK_RECOVERY:
|
|
rfu_REQ_CHILD_pollConnectRecovery();
|
|
break;
|
|
case LMAN_STATE_END_LINK_RECOVERY:
|
|
rfu_REQ_CHILD_endConnectRecovery();
|
|
break;
|
|
case LMAN_STATE_MS_CHANGE:
|
|
rfu_REQ_changeMasterSlave();
|
|
break;
|
|
case LMAN_STATE_WAIT_CLOCK_MASTER:
|
|
break;
|
|
case LMAN_STATE_STOP_MODE:
|
|
rfu_REQ_stopMode();
|
|
break;
|
|
case LMAN_STATE_BACK_STATE:
|
|
break;
|
|
default:
|
|
break;
|
|
}
|
|
rfu_waitREQComplete();
|
|
lman.active = 0;
|
|
}
|
|
if (lman.state == LMAN_STATE_END_LINK_RECOVERY || lman.state == LMAN_STATE_MS_CHANGE)
|
|
;
|
|
else
|
|
break;
|
|
}
|
|
if (gRfuLinkStatus->parentChild == MODE_PARENT)
|
|
{
|
|
if (rfu_LMAN_linkWatcher(0))
|
|
return;
|
|
}
|
|
rfu_LMAN_PARENT_checkRecvChildName();
|
|
rfu_LMAN_CHILD_checkSendChildName();
|
|
rfu_LMAN_CHILD_linkRecoveryProcess();
|
|
rfu_LMAN_checkNICommunicateStatus();
|
|
}
|
|
|
|
static void rfu_LMAN_settingPCSWITCH(u32 rand)
|
|
{
|
|
if (lman.pcswitch_flag == PCSWITCH_3RD_SC_START)
|
|
{
|
|
lman.parent_child = MODE_PARENT;
|
|
lman.state = LMAN_STATE_START_SEARCH_CHILD;
|
|
lman.connect_period = lman.pcswitch_period_bak;
|
|
if (lman.connect_period)
|
|
{
|
|
lman.pcswitch_flag = PCSWITCH_3RD_SC;
|
|
}
|
|
else
|
|
{
|
|
lman.pcswitch_flag = PCSWITCH_1ST_SC_START;
|
|
}
|
|
}
|
|
if (lman.pcswitch_flag == PCSWITCH_1ST_SC_START)
|
|
{
|
|
lman.parent_child = MODE_PARENT;
|
|
lman.state = LMAN_STATE_START_SEARCH_CHILD;
|
|
lman.connect_period = rand % 140;
|
|
lman.pcswitch_period_bak = 140 - lman.connect_period;
|
|
if (lman.connect_period)
|
|
{
|
|
lman.pcswitch_flag = PCSWITCH_1ST_SC;
|
|
}
|
|
else
|
|
{
|
|
lman.pcswitch_flag = PCSWITCH_2ND_SP_START;
|
|
}
|
|
}
|
|
if (lman.pcswitch_flag == PCSWITCH_2ND_SP_START)
|
|
{
|
|
lman.parent_child = MODE_CHILD;
|
|
lman.connect_period = PCSWITCH_SP_PERIOD;
|
|
lman.pcswitch_flag = PCSWITCH_2ND_SP;
|
|
lman.state = LMAN_STATE_START_SEARCH_PARENT;
|
|
}
|
|
}
|
|
|
|
static void rfu_LMAN_REQ_callback(u16 reqCommandId, u16 reqResult)
|
|
{
|
|
u8 status;
|
|
u8 *stwiRecvBuffer;
|
|
u8 i;
|
|
|
|
if (lman.active != 0)
|
|
{
|
|
lman.active = 0;
|
|
switch (reqCommandId)
|
|
{
|
|
case ID_RESET_REQ:
|
|
if (reqResult == 0)
|
|
{
|
|
lman.state = lman.next_state;
|
|
lman.next_state = LMAN_STATE_CONFIG_GAME_DATA;
|
|
}
|
|
break;
|
|
case ID_SYSTEM_CONFIG_REQ:
|
|
if (reqResult == 0)
|
|
{
|
|
lman.state = lman.next_state;
|
|
lman.next_state = LMAN_STATE_READY;
|
|
}
|
|
break;
|
|
case ID_GAME_CONFIG_REQ:
|
|
if (reqResult == 0)
|
|
{
|
|
lman.state = lman.next_state = LMAN_STATE_READY;
|
|
rfu_LMAN_occureCallback(LMAN_MSG_INITIALIZE_COMPLETED, 0);
|
|
}
|
|
break;
|
|
case ID_SC_START_REQ:
|
|
if (reqResult == 0)
|
|
{
|
|
lman.state = lman.next_state = LMAN_STATE_POLL_SEARCH_CHILD;
|
|
}
|
|
break;
|
|
case ID_SC_POLL_REQ:
|
|
if (lman.connect_period && --lman.connect_period == 0)
|
|
{
|
|
lman.state = LMAN_STATE_END_SEARCH_CHILD;
|
|
lman.next_state = LMAN_STATE_WAIT_RECV_CHILD_NAME;
|
|
}
|
|
break;
|
|
case ID_SC_END_REQ:
|
|
if (reqResult == 0)
|
|
{
|
|
lman.state = lman.next_state;
|
|
lman.next_state = LMAN_STATE_READY;
|
|
if (lman.pcswitch_flag == 0)
|
|
{
|
|
rfu_LMAN_occureCallback(LMAN_MSG_SEARCH_CHILD_PERIOD_EXPIRED, 0);
|
|
}
|
|
}
|
|
break;
|
|
case ID_SP_START_REQ:
|
|
if (reqResult == 0)
|
|
{
|
|
if (lman.fastSearchParent_flag == FSP_ON)
|
|
{
|
|
if (lman.connect_period > 1)
|
|
{
|
|
lman.connect_period--;
|
|
}
|
|
}
|
|
lman.state = lman.next_state = LMAN_STATE_POLL_SEARCH_PARENT;
|
|
}
|
|
break;
|
|
case ID_SP_POLL_REQ:
|
|
if (reqResult == 0)
|
|
{
|
|
status = rfu_LMAN_CHILD_checkEnableParentCandidate();
|
|
lman.param[0] = status;
|
|
if (status)
|
|
{
|
|
rfu_LMAN_occureCallback(LMAN_MSG_PARENT_FOUND, 1);
|
|
}
|
|
if (lman.fastSearchParent_flag && lman.connect_period != 1 && gRfuLinkStatus->findParentCount == RFU_CHILD_MAX)
|
|
{
|
|
rfu_REQ_endSearchParent();
|
|
rfu_waitREQComplete();
|
|
lman.state = LMAN_STATE_START_SEARCH_PARENT;
|
|
lman.fastSearchParent_flag = FSP_ON;
|
|
}
|
|
}
|
|
if (lman.connect_period && --lman.connect_period == 0)
|
|
{
|
|
lman.state = LMAN_STATE_END_SEARCH_PARENT;
|
|
lman.next_state = LMAN_STATE_READY;
|
|
}
|
|
break;
|
|
case ID_SP_END_REQ:
|
|
if (reqResult == 0)
|
|
{
|
|
lman.state = lman.next_state;
|
|
if (lman.pcswitch_flag == 0)
|
|
{
|
|
if (lman.state == LMAN_STATE_READY)
|
|
{
|
|
rfu_LMAN_occureCallback(LMAN_MSG_SEARCH_PARENT_PERIOD_EXPIRED, 0);
|
|
}
|
|
}
|
|
else if (lman.pcswitch_flag != PCSWITCH_CP)
|
|
{
|
|
lman.state = LMAN_STATE_START_SEARCH_CHILD;
|
|
lman.pcswitch_flag = PCSWITCH_3RD_SC_START;
|
|
}
|
|
}
|
|
break;
|
|
case ID_CP_START_REQ:
|
|
if (reqResult == 0)
|
|
{
|
|
lman.state = lman.next_state = LMAN_STATE_POLL_CONNECT_PARENT;
|
|
}
|
|
break;
|
|
case ID_CP_POLL_REQ:
|
|
if (reqResult == 0 && !rfu_getConnectParentStatus(&status, &lman.child_slot) && !status)
|
|
{
|
|
lman.state = LMAN_STATE_END_CONNECT_PARENT;
|
|
}
|
|
if (lman.connect_period && --lman.connect_period == 0)
|
|
{
|
|
lman.state = LMAN_STATE_END_CONNECT_PARENT;
|
|
}
|
|
break;
|
|
case ID_CP_END_REQ:
|
|
if (reqResult == 0 && !rfu_getConnectParentStatus(&status, &lman.child_slot))
|
|
{
|
|
if (!status)
|
|
{
|
|
lman.state = LMAN_STATE_MS_CHANGE;
|
|
lman.next_state = LMAN_STATE_SEND_CHILD_NAME;
|
|
lman.work = 0x22;
|
|
lman.param[0] = lman.child_slot;
|
|
}
|
|
else
|
|
{
|
|
lman.state = lman.next_state = LMAN_STATE_READY;
|
|
lman.work = 0x23;
|
|
lman.param[0] = status;
|
|
if (lman.pcswitch_flag)
|
|
{
|
|
lman.pcswitch_flag = PCSWITCH_2ND_SP_START;
|
|
lman.state = LMAN_STATE_START_SEARCH_PARENT;
|
|
}
|
|
}
|
|
rfu_LMAN_occureCallback(lman.work, 0x01);
|
|
lman.work = 0;
|
|
}
|
|
break;
|
|
case ID_CPR_START_REQ:
|
|
if (reqResult == 0)
|
|
{
|
|
lman.param[0] = gRfuLinkStatus->linkLossSlotFlag;
|
|
lman.state = lman.next_state = LMAN_STATE_POLL_LINK_RECOVERY;
|
|
for (lman.child_slot = 0; lman.child_slot < RFU_CHILD_MAX; lman.child_slot++)
|
|
{
|
|
if ((gRfuLinkStatus->linkLossSlotFlag >> lman.child_slot) & 1)
|
|
{
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
break;
|
|
case ID_CPR_POLL_REQ:
|
|
if (reqResult == 0 && !rfu_CHILD_getConnectRecoveryStatus(&status) && status < 2)
|
|
{
|
|
lman.state = LMAN_STATE_END_LINK_RECOVERY;
|
|
}
|
|
if (lman.linkRecoveryTimer.count[lman.child_slot] && --lman.linkRecoveryTimer.count[lman.child_slot] == 0)
|
|
{
|
|
lman.state = LMAN_STATE_END_LINK_RECOVERY;
|
|
}
|
|
break;
|
|
case ID_CPR_END_REQ:
|
|
if (reqResult == 0 && !rfu_CHILD_getConnectRecoveryStatus(&status))
|
|
{
|
|
if (!status)
|
|
{
|
|
lman.state = LMAN_STATE_MS_CHANGE;
|
|
lman.next_state = LMAN_STATE_BACK_STATE;
|
|
lman.work = 0x32;
|
|
}
|
|
else
|
|
{
|
|
lman.state = lman.next_state = LMAN_STATE_READY;
|
|
rfu_LMAN_disconnect(gRfuLinkStatus->linkLossSlotFlag);
|
|
lman.work = 0x33;
|
|
}
|
|
lman.linkRecoveryTimer.count[lman.child_slot] = 0;
|
|
lman.linkRecoveryTimer.active = 0;
|
|
lman.linkRecovery_start_flag = 0;
|
|
rfu_LMAN_occureCallback(lman.work, 0x01);
|
|
lman.work = 0;
|
|
}
|
|
break;
|
|
case ID_MS_CHANGE_REQ:
|
|
if (reqResult == 0)
|
|
{
|
|
if (lman.next_state == LMAN_STATE_BACK_STATE)
|
|
{
|
|
lman.state = lman.state_bak[0];
|
|
lman.next_state = lman.state_bak[1];
|
|
lman.childClockSlave_flag = RFU_CHILD_CLOCK_SLAVE_ON;
|
|
rfu_LMAN_occureCallback(LMAN_MSG_CHANGE_AGB_CLOCK_SLAVE, 0);
|
|
}
|
|
else if (lman.next_state == LMAN_STATE_SEND_CHILD_NAME)
|
|
{
|
|
lman.state = lman.next_state;
|
|
lman.childClockSlave_flag = RFU_CHILD_CLOCK_SLAVE_ON;
|
|
rfu_LMAN_occureCallback(LMAN_MSG_CHANGE_AGB_CLOCK_SLAVE, 0);
|
|
lman.nameAcceptTimer.active |= 1 << lman.child_slot;
|
|
lman.nameAcceptTimer.count[lman.child_slot] = lman.nameAcceptTimer.count_max;
|
|
rfu_clearSlot(TYPE_NI_SEND, lman.child_slot);
|
|
status = rfu_NI_CHILD_setSendGameName(lman.child_slot, 0x0e);
|
|
if (status)
|
|
{
|
|
lman.state = lman.next_state = LMAN_STATE_READY;
|
|
rfu_LMAN_managerChangeAgbClockMaster();
|
|
rfu_LMAN_disconnect(gRfuLinkStatus->connSlotFlag | gRfuLinkStatus->linkLossSlotFlag);
|
|
lman.param[0] = status;
|
|
rfu_LMAN_occureCallback(LMAN_MSG_CHILD_NAME_SEND_FAILED_AND_DISCONNECTED, 1);
|
|
}
|
|
}
|
|
}
|
|
break;
|
|
case ID_STOP_MODE_REQ:
|
|
if (reqResult == 0)
|
|
{
|
|
lman.state = lman.next_state = LMAN_STATE_READY;
|
|
rfu_LMAN_occureCallback(LMAN_MSG_RFU_POWER_DOWN, 0);
|
|
}
|
|
break;
|
|
}
|
|
lman.active = 1;
|
|
}
|
|
else if (reqResult == 3 && lman.msc_exe_flag && (reqCommandId == ID_DATA_TX_REQ || reqCommandId == ID_DATA_RX_REQ || reqCommandId == ID_MS_CHANGE_REQ))
|
|
{
|
|
rfu_REQ_RFUStatus();
|
|
rfu_waitREQComplete();
|
|
rfu_getRFUStatus(&status);
|
|
if (status == 0 && gRfuLinkStatus->parentChild == MODE_CHILD)
|
|
{
|
|
stwiRecvBuffer = rfu_getSTWIRecvBuffer() + 4;
|
|
*stwiRecvBuffer++ = gRfuLinkStatus->connSlotFlag;
|
|
*stwiRecvBuffer = REASON_LINK_LOSS;
|
|
rfu_LMAN_linkWatcher(ID_DISCONNECTED_AND_CHANGE_REQ);
|
|
reqResult = 0;
|
|
}
|
|
}
|
|
switch (reqCommandId)
|
|
{
|
|
case ID_DISCONNECT_REQ:
|
|
if (reqResult == 0)
|
|
{
|
|
lman.param[0] = *(rfu_getSTWIRecvBuffer() + 8);
|
|
rfu_LMAN_reflectCommunicationStatus(lman.param[0]);
|
|
if (lman.linkRecoveryTimer.active)
|
|
{
|
|
lman.linkRecoveryTimer.active &= ~lman.param[0];
|
|
for (i = 0; i < RFU_CHILD_MAX; i++)
|
|
{
|
|
if ((lman.param[0] >> i) & 1)
|
|
{
|
|
lman.linkRecoveryTimer.count[i] = 0;
|
|
}
|
|
}
|
|
if (lman.parent_child == MODE_CHILD)
|
|
{
|
|
lman.state = lman.next_state = LMAN_STATE_READY;
|
|
}
|
|
}
|
|
status = lman.acceptSlot_flag & lman.param[0];
|
|
for (i = 0; i < RFU_CHILD_MAX; i++)
|
|
{
|
|
if ((status >> i) & 1 && lman.acceptCount)
|
|
{
|
|
lman.acceptCount--;
|
|
}
|
|
}
|
|
lman.acceptSlot_flag &= ~lman.param[0];
|
|
if (lman.pcswitch_flag)
|
|
{
|
|
if (gRfuLinkStatus->parentChild == MODE_NEUTRAL)
|
|
{
|
|
if (lman.pcswitch_flag == PCSWITCH_SC_LOCK)
|
|
{
|
|
lman.connect_period = lman.pcswitch_period_bak;
|
|
lman.pcswitch_flag = PCSWITCH_3RD_SC;
|
|
lman.state = LMAN_STATE_POLL_SEARCH_CHILD;
|
|
}
|
|
else if (lman.state != LMAN_STATE_POLL_SEARCH_CHILD && lman.state != LMAN_STATE_END_SEARCH_CHILD)
|
|
{
|
|
lman.pcswitch_flag = PCSWITCH_1ST_SC_START;
|
|
lman.state = LMAN_STATE_START_SEARCH_CHILD;
|
|
}
|
|
}
|
|
}
|
|
if (gRfuLinkStatus->parentChild == MODE_NEUTRAL)
|
|
{
|
|
if (lman.state == LMAN_STATE_READY)
|
|
{
|
|
lman.parent_child = MODE_NEUTRAL;
|
|
}
|
|
}
|
|
if (lman.active == 0)
|
|
{
|
|
rfu_LMAN_occureCallback(LMAN_MSG_LINK_DISCONNECTED_BY_USER, 1);
|
|
}
|
|
}
|
|
break;
|
|
case ID_DATA_RX_REQ:
|
|
rfu_LMAN_CHILD_checkSendChildName2();
|
|
if (gRfuLinkStatus->parentChild != MODE_NEUTRAL)
|
|
{
|
|
rfu_LMAN_occureCallback(LMAN_MSG_RECV_DATA_REQ_COMPLETED, 0);
|
|
}
|
|
break;
|
|
case ID_RESET_REQ:
|
|
case ID_STOP_MODE_REQ:
|
|
if (reqResult == 0)
|
|
{
|
|
lman.reserveDisconnectSlot_flag = 0;
|
|
lman.acceptCount = 0;
|
|
lman.acceptSlot_flag = 0;
|
|
lman.parent_child = MODE_NEUTRAL;
|
|
rfu_LMAN_managerChangeAgbClockMaster();
|
|
if (reqCommandId == ID_STOP_MODE_REQ)
|
|
{
|
|
rfu_LMAN_endManager();
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
if (reqResult != 0)
|
|
{
|
|
if (reqCommandId == ID_SP_START_REQ && reqResult != 0 && lman.pcswitch_flag == PCSWITCH_2ND_SP)
|
|
{
|
|
gRfuLinkStatus->parentChild = MODE_PARENT;
|
|
gRfuLinkStatus->connSlotFlag = 0xF;
|
|
rfu_LMAN_disconnect(15);
|
|
rfu_waitREQComplete();
|
|
return;
|
|
}
|
|
else
|
|
{
|
|
lman.param[0] = reqCommandId;
|
|
lman.param[1] = reqResult;
|
|
if (lman.active)
|
|
{
|
|
lman.state = lman.next_state = LMAN_STATE_READY;
|
|
}
|
|
rfu_LMAN_occureCallback(LMAN_MSG_REQ_API_ERROR, 2);
|
|
rfu_LMAN_managerChangeAgbClockMaster();
|
|
}
|
|
}
|
|
if (reqCommandId == ID_CLOCK_SLAVE_MS_CHANGE_ERROR_BY_DMA_REQ)
|
|
{
|
|
rfu_LMAN_occureCallback(LMAN_MSG_CLOCK_SLAVE_MS_CHANGE_ERROR_BY_DMA, 0);
|
|
rfu_LMAN_managerChangeAgbClockMaster();
|
|
}
|
|
}
|
|
|
|
static void rfu_LMAN_MSC_callback(u16 reqCommandId)
|
|
{
|
|
u8 active_bak;
|
|
u8 thisAck_flag;
|
|
|
|
active_bak = lman.active;
|
|
lman.active = 0;
|
|
lman.msc_exe_flag = 1;
|
|
if (gRfuLinkStatus->parentChild == MODE_CHILD)
|
|
{
|
|
rfu_LMAN_linkWatcher(reqCommandId);
|
|
if (lman.childClockSlave_flag != RFU_CHILD_CLOCK_SLAVE_ON)
|
|
{
|
|
rfu_LMAN_managerChangeAgbClockMaster();
|
|
lman.msc_exe_flag = 0;
|
|
lman.active = active_bak;
|
|
return;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
if (!rfu_UNI_PARENT_getDRAC_ACK(&thisAck_flag))
|
|
{
|
|
lman.parentAck_flag |= thisAck_flag;
|
|
}
|
|
}
|
|
if (lman.MSC_callback != NULL)
|
|
{
|
|
lman.MSC_callback(reqCommandId);
|
|
rfu_waitREQComplete();
|
|
if (lman.childClockSlave_flag == RFU_CHILD_CLOCK_SLAVE_OFF_REQ)
|
|
{
|
|
rfu_LMAN_managerChangeAgbClockMaster();
|
|
}
|
|
}
|
|
lman.msc_exe_flag = 0;
|
|
lman.active = active_bak;
|
|
}
|
|
|
|
static void rfu_LMAN_PARENT_checkRecvChildName(void)
|
|
{
|
|
u8 newSlot;
|
|
u8 newAcceptSlot;
|
|
u8 i;
|
|
u8 flags;
|
|
u8 tgtSlot;
|
|
const u16 *ptr;
|
|
|
|
if (lman.state == LMAN_STATE_START_SEARCH_CHILD || lman.state == LMAN_STATE_POLL_SEARCH_CHILD || lman.state == LMAN_STATE_END_SEARCH_CHILD || lman.state == LMAN_STATE_WAIT_RECV_CHILD_NAME)
|
|
{
|
|
newSlot = ((gRfuLinkStatus->connSlotFlag ^ lman.connectSlot_flag_old) & gRfuLinkStatus->connSlotFlag) & ~gRfuLinkStatus->getNameFlag;
|
|
lman.connectSlot_flag_old = gRfuLinkStatus->connSlotFlag;
|
|
if (newSlot)
|
|
{
|
|
lman.param[0] = newSlot;
|
|
rfu_LMAN_occureCallback(LMAN_MSG_NEW_CHILD_CONNECT_DETECTED, 1);
|
|
}
|
|
newAcceptSlot = 0x00;
|
|
for (i = 0; i < RFU_CHILD_MAX; i++)
|
|
{
|
|
tgtSlot = 1 << i;
|
|
flags = 0x00;
|
|
if (newSlot & tgtSlot)
|
|
{
|
|
lman.nameAcceptTimer.count[i] = lman.nameAcceptTimer.count_max;
|
|
lman.nameAcceptTimer.active |= tgtSlot;
|
|
}
|
|
else if (lman.nameAcceptTimer.active & tgtSlot)
|
|
{
|
|
if (gRfuSlotStatusNI[i]->recv.state == SLOT_STATE_RECV_SUCCESS)
|
|
{
|
|
if (gRfuSlotStatusNI[i]->recv.dataType == 1)
|
|
{
|
|
flags = RN_NAME_TIMER_CLEAR;
|
|
for (ptr = lman.acceptable_serialNo_list; *ptr != 0xFFFF; ptr++)
|
|
{
|
|
if (gRfuLinkStatus->partner[i].serialNo == *ptr)
|
|
{
|
|
lman.acceptSlot_flag |= tgtSlot;
|
|
lman.acceptCount++;
|
|
newAcceptSlot |= tgtSlot;
|
|
flags |= RN_ACCEPT;
|
|
break;
|
|
}
|
|
}
|
|
if (!(flags & RN_ACCEPT))
|
|
{
|
|
flags |= RN_DISCONNECT;
|
|
}
|
|
}
|
|
}
|
|
else if (--lman.nameAcceptTimer.count[i] == 0)
|
|
{
|
|
flags = RN_NAME_TIMER_CLEAR | RN_DISCONNECT;
|
|
}
|
|
if (flags & RN_NAME_TIMER_CLEAR)
|
|
{
|
|
lman.nameAcceptTimer.active &= ~tgtSlot;
|
|
lman.nameAcceptTimer.count[i] = 0;
|
|
rfu_clearSlot(TYPE_NI_RECV, i);
|
|
}
|
|
if (flags & RN_DISCONNECT)
|
|
{
|
|
lman.reserveDisconnectSlot_flag |= tgtSlot;
|
|
}
|
|
}
|
|
}
|
|
if (newAcceptSlot)
|
|
{
|
|
lman.param[0] = newAcceptSlot;
|
|
rfu_LMAN_occureCallback(LMAN_MSG_NEW_CHILD_CONNECT_ACCEPTED, 1);
|
|
}
|
|
if (lman.reserveDisconnectSlot_flag)
|
|
{
|
|
flags = 1;
|
|
if (gRfuLinkStatus->sendSlotUNIFlag)
|
|
{
|
|
if (((lman.parentAck_flag & lman.acceptSlot_flag) != lman.acceptSlot_flag))
|
|
{
|
|
flags = 0;
|
|
}
|
|
}
|
|
if (flags)
|
|
{
|
|
rfu_LMAN_disconnect(lman.reserveDisconnectSlot_flag);
|
|
lman.param[0] = lman.reserveDisconnectSlot_flag;
|
|
lman.reserveDisconnectSlot_flag = 0;
|
|
rfu_LMAN_occureCallback(LMAN_MSG_NEW_CHILD_CONNECT_REJECTED, 1);
|
|
}
|
|
}
|
|
if (lman.nameAcceptTimer.active == 0 && lman.state == LMAN_STATE_WAIT_RECV_CHILD_NAME)
|
|
{
|
|
if (lman.pcswitch_flag == 0)
|
|
{
|
|
lman.state = lman.next_state = LMAN_STATE_READY;
|
|
rfu_LMAN_occureCallback(LMAN_MSG_END_WAIT_CHILD_NAME, 0);
|
|
}
|
|
else
|
|
{
|
|
if (lman.pcswitch_flag == PCSWITCH_1ST_SC)
|
|
{
|
|
lman.pcswitch_flag = PCSWITCH_2ND_SP_START;
|
|
lman.state = LMAN_STATE_START_SEARCH_PARENT;
|
|
}
|
|
else
|
|
{
|
|
lman.pcswitch_flag = PCSWITCH_1ST_SC_START;
|
|
lman.state = LMAN_STATE_START_SEARCH_CHILD;
|
|
}
|
|
if (lman.acceptSlot_flag)
|
|
{
|
|
lman.connect_period = 0;
|
|
lman.pcswitch_flag = PCSWITCH_SC_LOCK;
|
|
lman.state = LMAN_STATE_START_SEARCH_CHILD;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
static void rfu_LMAN_CHILD_checkSendChildName(void)
|
|
{
|
|
u16 imeBak = REG_IME;
|
|
REG_IME = 0;
|
|
if (lman.state == LMAN_STATE_SEND_CHILD_NAME)
|
|
{
|
|
if (--lman.nameAcceptTimer.count[lman.child_slot] == 0 || gRfuSlotStatusNI[lman.child_slot]->send.state == SLOT_STATE_SEND_FAILED)
|
|
{
|
|
rfu_LMAN_requestChangeAgbClockMaster();
|
|
lman.state = LMAN_STATE_WAIT_CHANGE_CLOCK_MASTER;
|
|
rfu_clearSlot(TYPE_NI_SEND, lman.child_slot);
|
|
lman.nameAcceptTimer.active &= ~(1 << lman.child_slot);
|
|
lman.nameAcceptTimer.count[lman.child_slot] = 0;
|
|
}
|
|
}
|
|
REG_IME = imeBak;
|
|
if (lman.state == LMAN_STATE_WAIT_CHANGE_CLOCK_MASTER)
|
|
{
|
|
if (lman.childClockSlave_flag == RFU_CHILD_CLOCK_SLAVE_ON)
|
|
{
|
|
rfu_LMAN_requestChangeAgbClockMaster();
|
|
}
|
|
if (lman.childClockSlave_flag == RFU_CHILD_CLOCK_SLAVE_OFF)
|
|
{
|
|
lman.state = lman.next_state = LMAN_STATE_READY;
|
|
rfu_LMAN_disconnect(gRfuLinkStatus->connSlotFlag | gRfuLinkStatus->linkLossSlotFlag);
|
|
lman.param[0] = 0;
|
|
rfu_LMAN_occureCallback(LMAN_MSG_CHILD_NAME_SEND_FAILED_AND_DISCONNECTED, 1);
|
|
}
|
|
}
|
|
}
|
|
|
|
static void rfu_LMAN_CHILD_checkSendChildName2(void)
|
|
{
|
|
if (lman.state == LMAN_STATE_SEND_CHILD_NAME && gRfuSlotStatusNI[lman.child_slot]->send.state == SLOT_STATE_SEND_SUCCESS)
|
|
{
|
|
lman.state = lman.next_state = LMAN_STATE_READY;
|
|
rfu_clearSlot(TYPE_NI_SEND, lman.child_slot);
|
|
lman.nameAcceptTimer.active &= ~(1 << lman.child_slot);
|
|
lman.nameAcceptTimer.count[lman.child_slot] = 0;
|
|
rfu_LMAN_occureCallback(LMAN_MSG_CHILD_NAME_SEND_COMPLETED, 0);
|
|
}
|
|
}
|
|
|
|
static void rfu_LMAN_CHILD_linkRecoveryProcess(void)
|
|
{
|
|
if (lman.parent_child == MODE_CHILD && lman.linkRecovery_start_flag == LINK_RECOVERY_START)
|
|
{
|
|
lman.state_bak[0] = lman.state;
|
|
lman.state_bak[1] = lman.next_state;
|
|
lman.state = LMAN_STATE_START_LINK_RECOVERY;
|
|
lman.next_state = LMAN_STATE_POLL_LINK_RECOVERY;
|
|
lman.linkRecovery_start_flag = LINK_RECOVERY_EXE;
|
|
}
|
|
}
|
|
|
|
static u8 rfu_LMAN_CHILD_checkEnableParentCandidate(void)
|
|
{
|
|
u8 i;
|
|
u16 *serialNo;
|
|
u8 flags = 0x00;
|
|
|
|
for (i = 0; i < gRfuLinkStatus->findParentCount; i++)
|
|
{
|
|
for (serialNo = lman.acceptable_serialNo_list; *serialNo != 0xFFFF; serialNo++)
|
|
{
|
|
if (gRfuLinkStatus->partner[i].serialNo == *serialNo)
|
|
{
|
|
flags |= (1 << i);
|
|
}
|
|
}
|
|
}
|
|
return flags;
|
|
}
|
|
|
|
static void rfu_LMAN_occureCallback(u8 msg, u8 param_count)
|
|
{
|
|
if (lman.LMAN_callback != NULL)
|
|
{
|
|
lman.LMAN_callback(msg, param_count);
|
|
}
|
|
lman.param[0] = lman.param[1] = 0;
|
|
}
|
|
|
|
static void rfu_LMAN_disconnect(u8 bm_disconnectedSlot)
|
|
{
|
|
u8 active_bak = lman.active;
|
|
lman.active = 1;
|
|
rfu_REQ_disconnect(bm_disconnectedSlot);
|
|
rfu_waitREQComplete();
|
|
lman.active = active_bak;
|
|
}
|
|
|
|
static void rfu_LMAN_reflectCommunicationStatus(u8 bm_disconnectedSlot)
|
|
{
|
|
u8 i;
|
|
|
|
if (gRfuLinkStatus->sendSlotNIFlag)
|
|
{
|
|
for (i = 0; i < RFU_CHILD_MAX; i++)
|
|
{
|
|
if (gRfuSlotStatusNI[i]->send.state & SLOT_BUSY_FLAG && gRfuSlotStatusNI[i]->send.bmSlot & bm_disconnectedSlot)
|
|
{
|
|
rfu_changeSendTarget(TYPE_NI, i, gRfuSlotStatusNI[i]->send.bmSlot & ~bm_disconnectedSlot);
|
|
}
|
|
}
|
|
}
|
|
if (gRfuLinkStatus->recvSlotNIFlag)
|
|
{
|
|
for (i = 0; i < RFU_CHILD_MAX; i++)
|
|
{
|
|
if (gRfuSlotStatusNI[i]->recv.state & SLOT_BUSY_FLAG && gRfuSlotStatusNI[i]->recv.bmSlot & bm_disconnectedSlot)
|
|
{
|
|
rfu_NI_stopReceivingData(i);
|
|
}
|
|
}
|
|
}
|
|
if (gRfuLinkStatus->sendSlotUNIFlag)
|
|
{
|
|
gRfuLinkStatus->sendSlotUNIFlag &= ~bm_disconnectedSlot;
|
|
for (i = 0; i < RFU_CHILD_MAX; i++)
|
|
{
|
|
if (gRfuSlotStatusUNI[i]->send.state == SLOT_STATE_SEND_UNI && bm_disconnectedSlot & gRfuSlotStatusUNI[i]->send.bmSlot)
|
|
{
|
|
gRfuSlotStatusUNI[i]->send.bmSlot &= ~bm_disconnectedSlot;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
static void rfu_LMAN_checkNICommunicateStatus(void)
|
|
{
|
|
u8 i;
|
|
u8 j;
|
|
u8 flags;
|
|
|
|
if (lman.NI_failCounter_limit)
|
|
{
|
|
if (gRfuLinkStatus->sendSlotNIFlag)
|
|
{
|
|
for (i = 0; i < RFU_CHILD_MAX; i++)
|
|
{
|
|
if (gRfuSlotStatusNI[i]->send.state & SLOT_BUSY_FLAG)
|
|
{
|
|
flags = 0;
|
|
for (j = 0; j < RFU_CHILD_MAX; j++)
|
|
{
|
|
if ((gRfuSlotStatusNI[i]->send.bmSlot >> j) & 1 && gRfuSlotStatusNI[j]->send.failCounter > lman.NI_failCounter_limit)
|
|
{
|
|
flags |= (1 << j);
|
|
}
|
|
if (flags)
|
|
{
|
|
rfu_changeSendTarget(TYPE_NI, i, flags ^ gRfuSlotStatusNI[i]->send.bmSlot);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
if (gRfuLinkStatus->recvSlotNIFlag)
|
|
{
|
|
for (i = 0; i < RFU_CHILD_MAX; i++)
|
|
{
|
|
if (gRfuSlotStatusNI[i]->recv.state & SLOT_BUSY_FLAG && gRfuSlotStatusNI[i]->recv.failCounter > lman.NI_failCounter_limit)
|
|
{
|
|
rfu_NI_stopReceivingData(i);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
void rfu_LMAN_setMSCCallback(void (*MSC_callback_p)(u16))
|
|
{
|
|
lman.MSC_callback = MSC_callback_p;
|
|
rfu_setMSCCallback(rfu_LMAN_MSC_callback);
|
|
}
|
|
|
|
static void rfu_LMAN_setLMANCallback(void (*func)(u8, u8))
|
|
{
|
|
lman.LMAN_callback = func;
|
|
}
|
|
|
|
u8 rfu_LMAN_setLinkRecovery(u8 enable_flag, u16 recovery_period)
|
|
{
|
|
u16 imeBak;
|
|
if (lman.linkRecovery_enable && enable_flag == 0 && lman.linkRecoveryTimer.active)
|
|
{
|
|
return LMAN_ERROR_NOW_LINK_RECOVERY;
|
|
}
|
|
imeBak = REG_IME;
|
|
REG_IME = 0;
|
|
lman.linkRecovery_enable = enable_flag;
|
|
lman.linkRecoveryTimer.count_max = recovery_period;
|
|
REG_IME = imeBak;
|
|
return 0;
|
|
}
|
|
|
|
static u8 rfu_LMAN_setNIFailCounterLimit(u16 NI_failCounter_limit)
|
|
{
|
|
if (gRfuLinkStatus->sendSlotNIFlag | gRfuLinkStatus->recvSlotNIFlag)
|
|
{
|
|
lman.param[0] = 6;
|
|
rfu_LMAN_occureCallback(LMAN_MSG_LMAN_API_ERROR_RETURN, 1);
|
|
return LMAN_ERROR_NOW_COMMUNICATION;
|
|
}
|
|
lman.NI_failCounter_limit = NI_failCounter_limit;
|
|
return 0;
|
|
}
|
|
|
|
static u8 rfu_LMAN_setFastSearchParent(u8 enable_flag)
|
|
{
|
|
if (lman.state == LMAN_STATE_START_SEARCH_PARENT || lman.state == LMAN_STATE_POLL_SEARCH_PARENT || lman.state == LMAN_STATE_END_SEARCH_PARENT)
|
|
{
|
|
lman.param[0] = 7;
|
|
rfu_LMAN_occureCallback(LMAN_MSG_LMAN_API_ERROR_RETURN, 1);
|
|
return LMAN_ERROR_NOW_SEARCH_PARENT;
|
|
}
|
|
if (enable_flag)
|
|
{
|
|
lman.fastSearchParent_flag = FSP_ON;
|
|
}
|
|
else
|
|
{
|
|
lman.fastSearchParent_flag = 0;
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
static void rfu_LMAN_managerChangeAgbClockMaster(void)
|
|
{
|
|
if (lman.childClockSlave_flag != RFU_CHILD_CLOCK_SLAVE_OFF)
|
|
{
|
|
lman.childClockSlave_flag = RFU_CHILD_CLOCK_SLAVE_OFF;
|
|
rfu_LMAN_occureCallback(LMAN_MSG_CHANGE_AGB_CLOCK_MASTER, 0);
|
|
}
|
|
}
|
|
|
|
void rfu_LMAN_requestChangeAgbClockMaster(void)
|
|
{
|
|
if (lman.childClockSlave_flag == RFU_CHILD_CLOCK_SLAVE_OFF)
|
|
{
|
|
rfu_LMAN_occureCallback(LMAN_MSG_CHANGE_AGB_CLOCK_MASTER, 0);
|
|
}
|
|
else if (lman.childClockSlave_flag == RFU_CHILD_CLOCK_SLAVE_ON)
|
|
{
|
|
lman.childClockSlave_flag = RFU_CHILD_CLOCK_SLAVE_OFF_REQ;
|
|
}
|
|
}
|
|
|
|
void rfu_LMAN_forceChangeSP(void)
|
|
{
|
|
if (lman.pcswitch_flag)
|
|
{
|
|
switch (lman.state)
|
|
{
|
|
case LMAN_STATE_START_SEARCH_CHILD:
|
|
lman.pcswitch_flag = PCSWITCH_2ND_SP_START;
|
|
lman.state = LMAN_STATE_START_SEARCH_PARENT;
|
|
break;
|
|
case LMAN_STATE_POLL_SEARCH_CHILD:
|
|
lman.pcswitch_flag = PCSWITCH_1ST_SC;
|
|
lman.connect_period = 1;
|
|
break;
|
|
case LMAN_STATE_END_SEARCH_CHILD:
|
|
case LMAN_STATE_WAIT_RECV_CHILD_NAME:
|
|
lman.pcswitch_flag = PCSWITCH_1ST_SC;
|
|
break;
|
|
case LMAN_STATE_START_SEARCH_PARENT:
|
|
case LMAN_STATE_POLL_SEARCH_PARENT:
|
|
lman.connect_period = PCSWITCH_SP_PERIOD;
|
|
break;
|
|
case LMAN_STATE_END_SEARCH_PARENT:
|
|
lman.connect_period = PCSWITCH_SP_PERIOD;
|
|
lman.state = LMAN_STATE_POLL_SEARCH_PARENT;
|
|
break;
|
|
}
|
|
}
|
|
}
|