⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 tdi.cxx

📁 三星2440原版bsp
💻 CXX
📖 第 1 页 / 共 5 页
字号:
			}

			break;
		}

		if (cSend > pConn->mtu)
			cSend = pConn->mtu;

		if (cSend > pConn->imax_send - pConn->isent)
			cSend = pConn->imax_send - pConn->isent;

		RFCOMM_PACKET_OBJECT *pPacket = new RFCOMM_PACKET_OBJECT;
		if (! pPacket) {
			IFDBG(DebugOut (DEBUG_ERROR, L"[TDI] SendData <out of memory>\n"));
			break;
		}

		BD_BUFFER *pBuffer = BufferAlloc (cSend + gpTDIR->cDeviceHeader + gpTDIR->cDeviceTrailer + DEBUG_OVERHEAD);

		if (! pBuffer) {
			delete pPacket;
			IFDBG(DebugOut (DEBUG_ERROR, L"[TDI] SendData <out of memory>\n"));
			break;
		}

		pPacket->pConn = pConn;
		pPacket->cBytesSent = cSend;
		pPacket->pNext = pConn->pPacketList;
		pConn->pPacketList = pPacket;

		pBuffer->cEnd = pBuffer->cSize - gpTDIR->cDeviceTrailer;
		pBuffer->cStart = gpTDIR->cDeviceHeader;

		SVSUTIL_ASSERT (BufferTotal (pBuffer) == (int)(cSend + DEBUG_OVERHEAD));

		int cCopiedData = TransferPendingSends (pConn, pBuffer->pBuffer + pBuffer->cStart, cSend);
		SVSUTIL_ASSERT (cCopiedData == cSend);

		pConn->isent += cSend;

		int iCredits = GiveCredits (pConn);

		if (pConn->fc_credit) {
			--pConn->iHaveCredits;
			pConn->iGaveCredits += iCredits;

#if defined (DEBUG_CREDIT_FLOW)
			pConn->iCreditsSent += iCredits;
			pConn->iPacketsSent += 1;

			if (pConn->iGaveCredits != (pConn->iCreditsSent - pConn->iPacketsRecv)) {
				SVSUTIL_ASSERT (0);
				RETAILMSG(1, (L"Bluetooth TDI Credit mismatch: GaveCredits = %d Total SentCredits = %d Total PacketsRecv = %d\n", pConn->iGaveCredits, pConn->iCreditsSent, pConn->iPacketsRecv));
			}

			if (pConn->iHaveCredits != (pConn->iCreditsRecv - pConn->iPacketsSent)) {
				RETAILMSG(1, (L"Bluetooth TDI Credit mismatch: HaveCredits = %d Total CreditsRecv = %d Total PacketsSent = %d\n", pConn->iHaveCredits, pConn->iCreditsRecv, pConn->iPacketsSent));
				SVSUTIL_ASSERT (0);
			}
#endif
		}

#if defined (DEBUG_PEER_SYNCHRONIZATION)
		PeerDebugData pd;

#if defined (DEBUG_CREDIT_FLOW)
		pd.iGaveCredits = pConn->iGaveCredits;
		pd.iHaveCredits = pConn->iHaveCredits;
		pd.iPacketsRecv = pConn->iPacketsRecv;
		pd.iPacketsSent = pConn->iPacketsSent;
		pd.iCreditsRecv = pConn->iCreditsRecv;
		pd.iCreditsSent = pConn->iCreditsSent;
#endif

		SVSUTIL_ASSERT (sizeof(pd) == DEBUG_OVERHEAD);
		memcpy (pBuffer->pBuffer + pBuffer->cEnd - sizeof(pd), &pd, sizeof(pd));
#endif

		HANDLE h = gpTDIR->hRFCOMM;
		HANDLE hConnect = pConn->hConnect;
		RFCOMM_DataDown_In pCallback = gpTDIR->rfcomm_if.rfcomm_DataDown_In;

		IFDBG(DebugOut (DEBUG_TDI_PACKETS, L"SendData 0x%08x : sending %d bytes and %d credits\n", pConn, BufferTotal(pBuffer), iCredits));

		pConn->fSending = TRUE;

		gpTDIR->AddRef ();
		gpTDIR->Unlock ();
		__try {
			int iRes = pCallback (h, pPacket, hConnect, pBuffer, iCredits);
#if defined (DEBUG) || defined (_DEBUG) || defined (RETAILLOG)
			if (iRes != ERROR_SUCCESS)
				IFDBG(DebugOut (DEBUG_ERROR, L"[TDI] SendData return %d\n", iRes));
#endif
		} __except (1) {
			IFDBG(DebugOut (DEBUG_ERROR, L"[TDI] SendData Exception in rfcomm_DataDown_In!\n"));
		}
		gpTDIR->Lock ();
		gpTDIR->DelRef ();

		if (pConn != GetConnectionObject ((HANDLE)pConn))
			return TDI_INVALID_CONNECTION;

		pConn->fSending = FALSE;
	}

	return TDI_PENDING;
}

static int RegisterTransferCompletion (RFCOMM_CONNECTION_OBJECT *pConn, int cBytes) {
	RFCOMM_SEND_OBJECT *pS = pConn->pSendList;
	pConn->isent -= cBytes;
	SVSUTIL_ASSERT (pConn->isent >= 0);

	while (pS && (cBytes > 0)) {
		int cUnconfirmed = pS->cBytesUsed - pS->cBytesConfirmed;
		int cConfirm = cUnconfirmed;
		if (cBytes < cConfirm)
			cConfirm = cBytes;
		pS->cBytesConfirmed += cConfirm;
		cBytes -= cConfirm;
		pS = pS->pNext;
	}

	SVSUTIL_ASSERT (cBytes == 0);

	for ( ; ; ) {
		if (! (gpTDIR->fIsConnected && (pConn == GetConnectionObject ((HANDLE)pConn))))
			return ERROR_OPERATION_ABORTED;

		if ((! pConn->pSendList) || (pConn->pSendList->cBytesConfirmed != QueryNdisSize (pConn->pSendList->pNdisBuffer)))
			break;
		
		RFCOMM_SEND_OBJECT *pNext = pConn->pSendList->pNext;
		PBT_SEND_COMPLETE pCallback = pConn->pSendList->pSendCallback;
		void *pCallbackContext = pConn->pSendList->pSendContext;
		int cBytesSent = pConn->pSendList->cBytesUsed;
		delete pConn->pSendList;
		pConn->pSendList = pNext;

		gpTDIR->AddRef ();
		gpTDIR->Unlock ();

		pCallback (pCallbackContext, TDI_SUCCESS, cBytesSent);

		gpTDIR->Lock ();
		gpTDIR->DelRef ();
	}

	SendData (pConn);

	return ERROR_SUCCESS;
}

static int AcceptIncomingCall (RFCOMM_ADDRESS_OBJECT *pAddr, HANDLE hConnection) {
	BD_ADDR			b;
	unsigned char	c;
	int				fLocal;
	int             fAcceptConnection = FALSE;

	int             imtu = TDIR_MTU;
	int				fcreditflow = FALSE;
	int				icredits = 0;
	
	ExtractPN (hConnection, &imtu, &fcreditflow, &icredits);

	if (ERROR_SUCCESS != gpTDIR->rfcomm_if.rfcomm_GetChannelAddress (gpTDIR->hRFCOMM, hConnection, &b, &c, &fLocal)) {
		IFDBG(DebugOut (DEBUG_WARN, L"[TDI] AcceptIncomingCall : Cannot resolve address from 0x%08x\n", hConnection));
		return FALSE;
	} else
		IFDBG(DebugOut (DEBUG_TDI_TRACE, L"Connection from %04x%08x 0x%02x accepted\n", b.NAP, b.SAP, c));

	BYTE				AddrBuf[sizeof(TRANSPORT_ADDRESS) + sizeof(SOCKADDR_BTH)];
	PTRANSPORT_ADDRESS	pTA = (PTRANSPORT_ADDRESS)AddrBuf;

	pTA->TAAddressCount           = 1;
	pTA->Address[0].AddressLength = sizeof(SOCKADDR_BTH) - 2;

	SOCKADDR_BTH *pSockAddr = (SOCKADDR_BTH *) &(pTA->Address[0].AddressType);
	BT_ADDR bt = SET_NAP_SAP(b.NAP, b.SAP);

	memset (pSockAddr, 0x00, sizeof(SOCKADDR_BTH));
	memcpy (&pSockAddr->btAddr, &bt, sizeof(bt));

	pSockAddr->addressFamily			= AF_BT;
	pSockAddr->port		                = c;

	void *pConnectionContext = NULL;
	ConnectEventInfo ci;
	PConnectEvent pEventConnect = pAddr->pEventConnect;

	gpTDIR->AddRef ();
	gpTDIR->Unlock ();

	TDI_STATUS TdiStatus = pEventConnect (pAddr->pEventConnectContext, TA_SIZE, 
					pTA, 0x00, NULL, 0x00, NULL, &pConnectionContext, &ci);

	gpTDIR->Lock ();
	gpTDIR->DelRef ();

	if (gpTDIR->fIsConnected && (TdiStatus == TDI_MORE_PROCESSING)) {
		RFCOMM_CONNECTION_OBJECT *pConn = GetConnectionByContext (pConnectionContext);
		if (pConn) {
			SVSUTIL_ASSERT (pConn->pAddr);	// This has to be an associated connection!
			SVSUTIL_ASSERT (! pConn->pPacketList);
			SVSUTIL_ASSERT (! pConn->pSendList);
			SVSUTIL_ASSERT (! pConn->pRecvList);

			SVSUTIL_ASSERT ((pConn->eStage == INITED) || (pConn->eStage == OPENING));

			ResetConnection (pConn, TRUE);		// Note - this resets the flow/credits
			TransferOptions (pConn, pConn->pAddr);	// Note - this overwrites MTU

			pConn->hConnect      = hConnection;

			memset (&pConn->BTAddr, 0, sizeof(pConn->BTAddr));
			pConn->BTAddr.addressFamily = AF_BTH;
			pConn->BTAddr.port   = c;
			pConn->BTAddr.btAddr = SET_NAP_SAP(b.NAP, b.SAP);

			pConn->mtu = imtu;

			if (fcreditflow) {
				pConn->fc_credit    = TRUE;
				pConn->iGaveCredits = RFCOMM_PN_CREDIT_MAX;
				pConn->iHaveCredits = icredits;
#if defined (DEBUG_CREDIT_FLOW)
				pConn->iCreditsRecv = icredits;
				pConn->iCreditsSent = RFCOMM_PN_CREDIT_MAX;
#endif
			} else {
				pConn->fc_credit    = FALSE;
				pConn->iGaveCredits = 0;
				pConn->iHaveCredits = 0;
#if defined (DEBUG_CREDIT_FLOW)
				pConn->iCreditsRecv = 0;
				pConn->iCreditsSent = 0;
#endif
			}

			IFDBG(DebugOut (DEBUG_TDI_TRACE, L"+AcceptIncomingCall 0x%08x : negotiated parms mtu = %d, credit fc = %s, gave credits = %d, have credits = %d\n", pConn, pConn->mtu, pConn->fc_credit ? L"on" : L"off", pConn->iGaveCredits, pConn->iHaveCredits));

			pConn->eStage = OPENED;

			gpTDIR->AddRef ();
			gpTDIR->Unlock ();

			ci.cei_rtn(ci.cei_context, TDI_SUCCESS, 0);

			gpTDIR->Lock ();
			gpTDIR->DelRef ();

			return TRUE;
		} else
			ci.cei_rtn(ci.cei_context, TDI_INVALID_CONNECTION, 0);
	} else {
		if (TdiStatus == TDI_MORE_PROCESSING)
			ci.cei_rtn(ci.cei_context, TDI_CANCELLED, 0);

		IFDBG(DebugOut (DEBUG_WARN, L"[TDI] AcceptIncomingCall : AFD doesn't want us :-(\n"));
	}

	return FALSE;
}

DWORD WINAPI AuthenticateOutgoingConnection (LPVOID arg) {
	HANDLE hConnection = (HANDLE)arg;

	IFDBG(DebugOut (DEBUG_TDI_TRACE, L"+AuthenticateOutgoingConnection h = 0x%04x\n", hConnection));
	if (! gpTDIR) {
		IFDBG(DebugOut (DEBUG_ERROR, L"[TDI] AuthenticateOutgoingConnection : ERROR_SERVICE_NOT_ACTIVE\n"));
		return ERROR_SERVICE_NOT_ACTIVE;
	}

	gpTDIR->Lock ();

	if (! gpTDIR->fIsConnected) {
		IFDBG(DebugOut (DEBUG_ERROR, L"[TDI] AuthenticateOutgoingConnection : ERROR_SERVICE_NOT_ACTIVE\n"));
		gpTDIR->Unlock ();
		return ERROR_SERVICE_NOT_ACTIVE;
	}

	RFCOMM_CONNECTION_OBJECT *pConn = GetConnectionByHandle (hConnection);

	if (pConn) {
		SVSUTIL_ASSERT (pConn->pAddr);	// This must be an associated connection!
		SVSUTIL_ASSERT (! pConn->pPacketList);
		SVSUTIL_ASSERT (! pConn->pSendList);
		SVSUTIL_ASSERT (! pConn->pRecvList);
		SVSUTIL_ASSERT (pConn->hConnect == hConnection);
		SVSUTIL_ASSERT (pConn->fAuthenticate || pConn->fEncrypt);

		SVSUTIL_ASSERT (pConn->eStage == OPENING);

		int TdiStatus = TDI_SUCCESS;
		int fAuthenticate = pConn->fAuthenticate;
		int fEncrypt = pConn->fEncrypt;
		BT_ADDR bt = pConn->BTAddr.btAddr;

		gpTDIR->Unlock ();

		if (fAuthenticate && (BthAuthenticate (&bt) != ERROR_SUCCESS))
			TdiStatus = TDI_CONN_REFUSED;

		if (fEncrypt && (TdiStatus == TDI_SUCCESS) && (BthSetEncryption (&bt, TRUE) != ERROR_SUCCESS))
			TdiStatus = TDI_CONN_REFUSED;

		if (! gpTDIR)
			return ERROR_INTERNAL_ERROR;

		gpTDIR->Lock ();
		if (TdiStatus == TDI_SUCCESS)
			ResetConnection (pConn, FALSE);		// Leave credits be - they were set in PN process
		else
			TdiStatus = TDI_CONN_REFUSED;

		SignalConnectionCompleteUp (pConn, TdiStatus);

		if (gpTDIR->fIsConnected && (pConn == GetConnectionByHandle (hConnection)) && (pConn->eStage == OPENED))
			SendMSC (pConn, TDIR_V24_RTC|TDIR_V24_RTR, 0xff);
	} else
		IFDBG(DebugOut (DEBUG_ERROR, L"[TDI] AuthenticateOutgoingConnection : no connection for handle 0x%08x\n", hConnection));

	IFDBG(DebugOut (DEBUG_TDI_TRACE, L"-AuthenticateOutgoingConnection ERROR_SUCCESS\n"));
	gpTDIR->Unlock ();

	return ERROR_SUCCESS;
}


DWORD WINAPI AuthenticateConnectionRequest (LPVOID arg) {
	HANDLE hConnection = (HANDLE)arg;

	IFDBG(DebugOut (DEBUG_TDI_TRACE, L"+AuthenticateConnectionRequest 0x%04x\n", hConnection));
	if (! gpTDIR) {
		IFDBG(DebugOut (DEBUG_ERROR, L"[TDI] AuthenticateConnectionRequest : ERROR_SERVICE_NOT_ACTIVE\n"));
		return ERROR_SERVICE_NOT_ACTIVE;
	}

	gpTDIR->Lock ();

	if (! gpTDIR->fIsConnected) {
		IFDBG(DebugOut (DEBUG_ERROR, L"[TDI] AuthenticateConnectionRequest : ERROR_SERVICE_NOT_ACTIVE\n"));
		gpTDIR->Unlock ();
		return ERROR_SERVICE_NOT_ACTIVE;
	}

	BD_ADDR			b;
	unsigned char	c;
	int				fLocal;
	int             fAcceptConnection = TRUE;

	if (ERROR_SUCCESS == gpTDIR->rfcomm_if.rfcomm_GetChannelAddress (gpTDIR->hRFCOMM, hConnection, &b, &c, &fLocal)) {
		IFDBG(DebugOut (DEBUG_TDI_TRACE, L"Got connection request from %04x%08x 0x%02x\n", b.NAP, b.SAP, c));
		// Find address object...
		RFCOMM_ADDRESS_OBJECT *pAddr = gpTDIR->paolist;
		while (pAddr &&
			(! ((((pAddr->b.NAP == 0) && (pAddr->b.SAP == 0)) || (pAddr->b == b)) && pAddr->fListenOn && pAddr->pEventConnect && (pAddr->ch == c))))
			pAddr = pAddr->pNext;

		if (pAddr) {
			IFDBG(DebugOut (DEBUG_TDI_TRACE, L"Found address object 0x%08x\n", pAddr));
			SVSUTIL_ASSERT (pAddr->fAuthenticate || pAddr->fEncrypt);

			int fAuthenticate = pAddr->fAuthenticate;
			int fEncrypt = pAddr->fEncrypt;
			BT_ADDR bt = SET_NAP_SAP (b.NAP, b.SAP);

			int cPinLength = pAddr->cPinLength;
			unsigned char caPinData[PIN_SIZE];
			memcpy (caPinData, pAddr->caPinData, sizeof(caPinData));

			SVSUTIL_ASSERT ((cPinLength >= 0) && (cPinLength <= PIN_SIZE));

			gpTDIR->Unlock ();

			__try {
				if (cPinLength)
					BthSetPIN (&bt, cPinLength, caPinData);

				if (fAuthenticate && (BthAuthenticate (&bt) != ERROR_SUCCESS))
					fAcceptConnection = FALSE;

				if (fEncrypt && fAcceptConnection && (BthSetEncryption (&bt, TRUE) != ERROR_SUCCESS))
					fAcceptConnection = FALSE;
			} __except (1) {
				IFDBG(DebugOut (DEBUG_ERROR, L"[TDI] exception in security code!\n"));
				fAcceptConnection = FALSE;
			}

			if (! gpTDIR)
				return ERROR_INTERNAL_ERROR;

			gpTDIR->Lock ();
			if (fAcceptConnection && gpTDIR->fIsConnected && (pAddr == GetAddressObject ((HANDLE)pAddr)))
				fAcceptConnection = AcceptIncomingCall (pAddr, hConnection);
			else
				fAcceptConnection = FALSE;
		} else {
			IFDBG(DebugOut (DEBUG_ERROR, L"Address translation failed for connection 0x%08x\n", hConnection));
			fAcceptConnection = FALSE;
		}
	} else {
		IFDBG(DebugOut (DEBUG_ERROR, L"Address translation failed for connection 0x%08x\n", hConnection));
		fAcceptConnection = FALSE;
	}

	if (gpTDIR->fIsConnected) {
		IFDBG(DebugOut (DEBUG_TDI_TRACE, L"AuthenticateConnectionRequest : %s connection\n", fAcceptConnection ? L"Accepting" : L"Declining"));
		HANDLE h = gpTDIR->hRFCOMM;
		RFCOMM_ConnectResponse_In pCallback = gpTDIR->rfcomm_if.rfcomm_ConnectResponse_In;

		gpTDIR->AddRef ();
		gpTDIR->Unlock ();
		__try {
			pCallback (h, NULL, hConnection, fAcceptConnection);
		} __except (1) {
			IFDBG(DebugOut (DEBUG_ERROR, L"[TDI] AuthenticateConnectionRequest Exception in rfcomm_ConnectResponse_In\n"));
		}
		gpTDIR->Lock ();
		gpTDIR->DelRef ();
	}

	if (gpTDIR->fIsConnected && fAcceptConnection) {
		RFCOMM_CONNECTION_OBJECT *pConn = GetConnectionByHandle (hConnection);
		if (pConn)
			SendMSC (pConn, TDIR_V24_RTC|TDIR_V24_RTR, 0xff);
	}

	IFDBG(DebugOut (DEBUG_TDI_TRACE, L"-AuthenticateConnectionRequest ERROR_SUCCESS\n"));
	gpTDIR->Unlock ();

	return ERROR_SUCCESS;
}

//
//	RFCOMM interface
//
static int tdir_connect_request_ind	(void *pUserContext, HANDLE hConnection, BD_ADDR *pba, unsigned char channel) {
	IFDBG(DebugOut (DEBUG_TDI_TRACE, L"+tdir_connect_request_ind\n"));
	if (! gpTDIR) {
		IFDBG(DebugOut (DEBUG_ERROR, L"[TDI] tdir_connect_request_ind : ERROR_SERVICE_NOT_ACTIVE\n"));
		return ERROR_SERVICE_NOT_ACTIVE;
	}

	gpTDIR->Lock ();

	if (! gpTDIR->fIsConnected) {
		IFDBG(DebugOut (DEBUG_ERROR, L"[TDI] tdir_connect_request_ind : ERROR_SERVICE_NOT_ACTIVE\n"));
		gpTDIR->Unlock ();
		return ERROR_SERVICE_NOT_ACTIVE;
	}

	BD_ADDR			b;
	unsigned char	c;
	int				fLocal;
	int             fAcceptConnection = FALSE;
	int				fSkipReply = FALSE;

	int				cPinLength = 0;
	unsigned char	caPinData[PIN_SIZE];

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -