void CWII_IPC_HLE_WiiMote::ReceiveL2capData(u16 scid, const void* _pData, u32 _Size)
{

	// Allocate DataFrame
	u8 DataFrame[1024];
	u32 Offset = 0;
	l2cap_hdr_t* pHeader = (l2cap_hdr_t*)DataFrame;
	Offset += sizeof(l2cap_hdr_t);

	// Check if we are already reporting on this channel
	_dbg_assert_(WII_IPC_WIIMOTE, DoesChannelExist(scid));
	SChannel& rChannel = m_Channel[scid];

	// Add an additional 4 byte header to the Wiimote report
	pHeader->dcid = rChannel.DCID;
	pHeader->length = _Size;

	// Copy the Wiimote report to DataFrame
	memcpy(DataFrame + Offset, _pData, _Size);
	// Update Offset to the final size of the report
	Offset += _Size;

	// Update the status bar
	Host_SetWiiMoteConnectionState(2);

	// Send the report
	m_pHost->SendACLPacket(GetConnectionHandle(), DataFrame, Offset);
}
void CWII_IPC_HLE_WiiMote::ReceiveConnectionResponse(u8 _Ident, u8* _pData, u32 _Size)
{
	l2cap_con_rsp_cp* rsp = (l2cap_con_rsp_cp*)_pData;

	_dbg_assert_(WII_IPC_WIIMOTE, _Size == sizeof(l2cap_con_rsp_cp));

	INFO_LOG(WII_IPC_WIIMOTE, "[L2CAP] ReceiveConnectionResponse");
	DEBUG_LOG(WII_IPC_WIIMOTE, "    DCID: 0x%04x", rsp->dcid);
	DEBUG_LOG(WII_IPC_WIIMOTE, "    SCID: 0x%04x", rsp->scid);
	DEBUG_LOG(WII_IPC_WIIMOTE, "    Result: 0x%04x", rsp->result);
	DEBUG_LOG(WII_IPC_WIIMOTE, "    Status: 0x%04x", rsp->status);

	_dbg_assert_(WII_IPC_WIIMOTE, rsp->result == L2CAP_SUCCESS);
	_dbg_assert_(WII_IPC_WIIMOTE, rsp->status == L2CAP_NO_INFO);
	_dbg_assert_(WII_IPC_WIIMOTE, DoesChannelExist(rsp->scid));

	SChannel& rChannel = m_Channel[rsp->scid];
	rChannel.DCID = rsp->dcid;

	// update state machine
	if (rChannel.PSM == L2CAP_PSM_HID_CNTL)
		m_HIDControlChannel_Connected = true;
	else if (rChannel.PSM == L2CAP_PSM_HID_INTR)
		m_HIDInterruptChannel_Connected = true;
}
示例#3
0
void CWII_IPC_HLE_WiiMote::SendConfigurationRequest(u16 scid, u16 MTU, u16 FlushTimeOut)
{
	_dbg_assert_(WII_IPC_WIIMOTE, DoesChannelExist(scid));
	SChannel& rChannel = m_Channel[scid];

	u8 Buffer[1024];
	int Offset = 0;

	l2cap_cfg_req_cp* cr = (l2cap_cfg_req_cp*)&Buffer[Offset];
	cr->dcid = rChannel.DCID;
	cr->flags = 0;
	Offset += sizeof(l2cap_cfg_req_cp);

	DEBUG_LOG(WII_IPC_WIIMOTE, "[L2CAP] SendConfigurationRequest");
	DEBUG_LOG(WII_IPC_WIIMOTE, "    Dcid: 0x%04x", cr->dcid);
	DEBUG_LOG(WII_IPC_WIIMOTE, "    Flags: 0x%04x", cr->flags);

	l2cap_cfg_opt_t* pOptions;

	// (shuffle2) currently we end up not appending options. this is because we don't
	// negotiate after trying to set MTU = 0 fails (stack will respond with
	// "configuration failed" msg...). This is still fine, we'll just use whatever the
	// Bluetooth stack defaults to.
	if (MTU || rChannel.MTU)
	{
		if (MTU == 0)
			MTU = rChannel.MTU;
		pOptions = (l2cap_cfg_opt_t*)&Buffer[Offset];
		Offset += sizeof(l2cap_cfg_opt_t);
		pOptions->type = L2CAP_OPT_MTU;
		pOptions->length = L2CAP_OPT_MTU_SIZE;
		*(u16*)&Buffer[Offset] = MTU;
		Offset += L2CAP_OPT_MTU_SIZE;
		DEBUG_LOG(WII_IPC_WIIMOTE, "    MTU: 0x%04x", MTU);
	}

	if (FlushTimeOut || rChannel.FlushTimeOut)
	{
		if (FlushTimeOut == 0)
			FlushTimeOut = rChannel.FlushTimeOut;
		pOptions = (l2cap_cfg_opt_t*)&Buffer[Offset];
		Offset += sizeof(l2cap_cfg_opt_t);
		pOptions->type = L2CAP_OPT_FLUSH_TIMO;
		pOptions->length = L2CAP_OPT_FLUSH_TIMO_SIZE;
		*(u16*)&Buffer[Offset] = FlushTimeOut;
		Offset += L2CAP_OPT_FLUSH_TIMO_SIZE;
		DEBUG_LOG(WII_IPC_WIIMOTE, "    FlushTimeOut: 0x%04x", FlushTimeOut);
	}

	SendCommandToACL(L2CAP_CONFIG_REQ, L2CAP_CONFIG_REQ, Offset, Buffer);
}
void CWII_IPC_HLE_WiiMote::ReceiveConfigurationReq(u8 _Ident, u8* _pData, u32 _Size)
{
	u32 Offset = 0;
	l2cap_cfg_req_cp* pCommandConfigReq = (l2cap_cfg_req_cp*)_pData;

	_dbg_assert_(WII_IPC_WIIMOTE, pCommandConfigReq->flags == 0x00); // 1 means that the options are send in multi-packets
	_dbg_assert_(WII_IPC_WIIMOTE, DoesChannelExist(pCommandConfigReq->dcid));

	SChannel& rChannel = m_Channel[pCommandConfigReq->dcid];

	INFO_LOG(WII_IPC_WIIMOTE, "[L2CAP] ReceiveConfigurationRequest");
	DEBUG_LOG(WII_IPC_WIIMOTE, "    Ident: 0x%02x", _Ident);
	DEBUG_LOG(WII_IPC_WIIMOTE, "    DCID: 0x%04x", pCommandConfigReq->dcid);
	DEBUG_LOG(WII_IPC_WIIMOTE, "    Flags: 0x%04x", pCommandConfigReq->flags);

	Offset += sizeof(l2cap_cfg_req_cp);

	u8 TempBuffer[1024];
	u32 RespLen = 0;

	l2cap_cfg_rsp_cp* Rsp = (l2cap_cfg_rsp_cp*)TempBuffer;
	Rsp->scid   = rChannel.DCID;
	Rsp->flags  = 0x00;
	Rsp->result = L2CAP_SUCCESS;

	RespLen += sizeof(l2cap_cfg_rsp_cp);

	// read configuration options
	while (Offset < _Size)
	{
		l2cap_cfg_opt_t* pOptions = (l2cap_cfg_opt_t*)&_pData[Offset];
		Offset += sizeof(l2cap_cfg_opt_t);

		switch (pOptions->type)
		{
		case L2CAP_OPT_MTU:
			{
				_dbg_assert_(WII_IPC_WIIMOTE, pOptions->length == L2CAP_OPT_MTU_SIZE);
				l2cap_cfg_opt_val_t* pMTU = (l2cap_cfg_opt_val_t*)&_pData[Offset];
				rChannel.MTU = pMTU->mtu;
				DEBUG_LOG(WII_IPC_WIIMOTE, "    MTU: 0x%04x", pMTU->mtu);
			}
			break;

		case L2CAP_OPT_FLUSH_TIMO:
			{
				_dbg_assert_(WII_IPC_WIIMOTE, pOptions->length == L2CAP_OPT_FLUSH_TIMO_SIZE);
				l2cap_cfg_opt_val_t* pFlushTimeOut = (l2cap_cfg_opt_val_t*)&_pData[Offset];
				rChannel.FlushTimeOut = pFlushTimeOut->flush_timo;
				DEBUG_LOG(WII_IPC_WIIMOTE, "    FlushTimeOut: 0x%04x", pFlushTimeOut->flush_timo);
			}
			break;

		default:
			_dbg_assert_msg_(WII_IPC_WIIMOTE, 0, "Unknown Option: 0x%02x", pOptions->type);
			break;
		}

		Offset += pOptions->length;

		u32 OptionSize = sizeof(l2cap_cfg_opt_t) + pOptions->length;
		memcpy(&TempBuffer[RespLen], pOptions, OptionSize);
		RespLen += OptionSize;
	}

	INFO_LOG(WII_IPC_WIIMOTE, "[L2CAP] SendConfigurationResponse");
	SendCommandToACL(_Ident, L2CAP_CONFIG_RSP, RespLen, TempBuffer);

	// update state machine
	if (rChannel.PSM == L2CAP_PSM_HID_CNTL)
		m_HIDControlChannel_Connected = true;
	else if (rChannel.PSM == L2CAP_PSM_HID_INTR)
		m_HIDInterruptChannel_Connected = true;
}
// This function receives L2CAP commands from the CPU
void CWII_IPC_HLE_WiiMote::ExecuteL2capCmd(u8* _pData, u32 _Size)
{
	// parse the command
	l2cap_hdr_t* pHeader = (l2cap_hdr_t*)_pData;
	u8* pData = _pData + sizeof(l2cap_hdr_t);
	u32 DataSize = _Size - sizeof(l2cap_hdr_t);
	INFO_LOG(WII_IPC_WIIMOTE, "  CID 0x%04x, Len 0x%x, DataSize 0x%x", pHeader->dcid, pHeader->length, DataSize);

	if (pHeader->length != DataSize)
	{
		INFO_LOG(WII_IPC_WIIMOTE, "Faulty packet. It is dropped.");
		return;
	}

	switch (pHeader->dcid)
	{
	case L2CAP_SIGNAL_CID:
		SignalChannel(pData, DataSize);
		break;

	default:
		{
			_dbg_assert_msg_(WII_IPC_WIIMOTE, DoesChannelExist(pHeader->dcid), "L2CAP: SendACLPacket to unknown channel %i", pHeader->dcid);
			CChannelMap::iterator  itr= m_Channel.find(pHeader->dcid);

			const int number = m_ConnectionHandle & 0xFF;

			if (itr != m_Channel.end())
			{
				SChannel& rChannel = itr->second;
				switch (rChannel.PSM)
				{
				case L2CAP_PSM_SDP:
					HandleSDP(pHeader->dcid, pData, DataSize);
					break;

				case L2CAP_PSM_HID_CNTL:
					if (number < MAX_BBMOTES)
						Wiimote::ControlChannel(number, pHeader->dcid, pData, DataSize);
					break;

				case L2CAP_PSM_HID_INTR:
					{
						if (number < MAX_BBMOTES)
						{
							DEBUG_LOG(WIIMOTE, "Wiimote_InterruptChannel");
							DEBUG_LOG(WIIMOTE, "    Channel ID: %04x", pHeader->dcid);
							std::string Temp = ArrayToString((const u8*)pData, DataSize);
							DEBUG_LOG(WIIMOTE, "    Data: %s", Temp.c_str());

							Wiimote::InterruptChannel(number, pHeader->dcid, pData, DataSize);
						}
					}
					break;

				default:
					ERROR_LOG(WII_IPC_WIIMOTE, "Channel 0x04%x has unknown PSM %x", pHeader->dcid, rChannel.PSM);
					break;
				}
			}
		}
		break;
	}
}