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

📄 tdi.cxx

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

	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));
			if (pAddr->fAuthenticate || pAddr->fEncrypt) {
				IFDBG(DebugOut (DEBUG_TDI_TRACE, L"Address object 0x%08x requires authentication\n", pAddr));
				SVSCookie cookie = btutil_ScheduleEvent (AuthenticateConnectionRequest, hConnection, 0);
				if (cookie)
					fSkipReply = TRUE;
				else {
					IFDBG(DebugOut (DEBUG_ERROR, L"[TDI] Could not create authentication thread in tdir_connect_request_ind\n"));
				}
			} else {
				cPinLength = pAddr->cPinLength;
				memcpy (caPinData, pAddr->caPinData, sizeof(caPinData));

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

				fAcceptConnection = AcceptIncomingCall (pAddr, hConnection);
			}
		} else
			IFDBG(DebugOut (DEBUG_ERROR, L"Address translation failed for connection 0x%08x\n", hConnection));
	} else
		IFDBG(DebugOut (DEBUG_ERROR, L"Address translation failed for connection 0x%08x\n", hConnection));

	if (gpTDIR->fIsConnected && (! fSkipReply)) {
		IFDBG(DebugOut (DEBUG_TDI_TRACE, L"tdir_connect_request_ind : %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 {
			if (fAcceptConnection && cPinLength) {
				bt_addr bt = SET_NAP_SAP (b.NAP, b.SAP);
				BthSetPIN (&bt, cPinLength, caPinData);
			}

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

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

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

	return ERROR_SUCCESS;
}

static int ConnectEntrySDP(RFCOMM_CONNECTION_OBJECT *pC) {
	IFDBG(DebugOut (DEBUG_TDI_TRACE, L"[TDIR] ConnectEntrySDP : 0x%08x\n", pC));

	int iErr = ERROR_INTERNAL_ERROR;

	BD_ADDR b;
	b.NAP = GET_NAP(pC->BTAddr.btAddr);
	b.SAP = GET_SAP(pC->BTAddr.btAddr);

	HANDLE h = gpTDIR->hSDP;
	SDP_Connect_In pCallback = gpTDIR->sdp_if.sdp_Connect_In;
	gpTDIR->AddRef ();
	gpTDIR->Unlock ();

	__try {
		iErr = pCallback (h, pC, &b);
	} __except (1) {
		IFDBG(DebugOut (DEBUG_ERROR, L"[TDIR] : exception in ConnectEntrySDP!\n"));
	}

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

	if (!GetConnectionObject ((HANDLE)pC) || (!gpTDIR->fIsConnected && (iErr == ERROR_SUCCESS)))
		iErr = ERROR_OPERATION_ABORTED;

	return iErr;
}

static int ConnectEntryRFCOMM(RFCOMM_CONNECTION_OBJECT *pC) {
	IFDBG(DebugOut (DEBUG_TDI_TRACE, L"[TDIR] ConnectEntryRFCOMM : 0x%08x\n", pC));

	SVSUTIL_ASSERT (! pC->hConnect);

	int iErr = ERROR_INTERNAL_ERROR;

	HANDLE hConnect = NULL;
	HANDLE h = gpTDIR->hRFCOMM;
	RFCOMM_CreateChannel pCallback = gpTDIR->rfcomm_if.rfcomm_CreateChannel;

	unsigned char chPort = (unsigned char)pC->BTAddr.port;
	bt_addr bt = pC->BTAddr.btAddr;

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

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

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

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

		BD_ADDR b;

		b.NAP = GET_NAP(bt);
		b.SAP = GET_SAP(bt);

		iErr = pCallback (h, &b, chPort, &hConnect);
	} __except (1) {
		IFDBG(DebugOut (DEBUG_ERROR, L"[TDIR] : exception in ConnectEntryRFCOMM!\n"));
	}

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

#if defined (DEBUG) || defined (_DEBUG)
	if (hConnect) {
		RFCOMM_CONNECTION_OBJECT *pC2 = gpTDIR->pcolist;
		while (pC2) {
			SVSUTIL_ASSERT ((pC2 == pC) || (pC2->hConnect != hConnect));
			pC2 = pC2->pNext;
		}
	}
#endif

	pC = GetConnectionObject ((HANDLE)pC);

	if (hConnect && gpTDIR->fIsConnected && pC && (iErr == ERROR_SUCCESS)) {
		IFDBG(DebugOut (DEBUG_TDI_TRACE, L"[TDIR] ConnectEntryRFCOMM : object 0x%08x handle 0x%08x channel = %d\n", pC, hConnect, chPort));

		pC->hConnect = hConnect;

		int n1 = pC->mtu;

		RFCOMM_PNREQ_In pCallback2 = gpTDIR->rfcomm_if.rfcomm_PNREQ_In;
		gpTDIR->AddRef ();
		gpTDIR->Unlock ();

		iErr = ERROR_INTERNAL_ERROR;

		__try {
			iErr = pCallback2 (h, pC, hConnect, TDIR_PRI, n1, RFCOMM_PN_CREDIT_IN, RFCOMM_PN_CREDIT_MAX);
		} __except (1) {
			IFDBG(DebugOut (DEBUG_ERROR, L"[TDIR] : exception in rfcomm_CreateChannel!\n"));
		}

		gpTDIR->Lock ();
		gpTDIR->DelRef ();
		if (gpTDIR->fIsInitialized)
			pC = GetConnectionObject ((HANDLE)pC);
		else
			pC = NULL;
	}

	if (! pC)
		iErr = ERROR_OPERATION_ABORTED;

	return iErr;
}


void SDPDisconnect(unsigned short cid)  {
	HANDLE h = gpTDIR->hSDP;
	SDP_Disconnect_In  pCallback = gpTDIR->sdp_if.sdp_Disconnect_In;

	SVSUTIL_ASSERT(gpTDIR->IsLocked());

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

	__try {
		pCallback (h,NULL,cid);
	} __except (1) {
		IFDBG(DebugOut (DEBUG_ERROR, L"[TDIR] : exception in sdp_disconnect_in!\n"));
	}

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



static int tdir_data_up_ind (void *pUserContext, HANDLE hConnection, BD_BUFFER *pba, int additional_credits) {
	IFDBG(DebugOut (DEBUG_TDI_TRACE, L"+tdir_data_up_ind, data = %d, extra credits = %d\n", BufferTotal (pba), additional_credits));
	if (! gpTDIR) {
		IFDBG(DebugOut (DEBUG_ERROR, L"[TDI] tdir_data_up_ind : ERROR_SERVICE_NOT_ACTIVE\n"));
		return ERROR_SERVICE_NOT_ACTIVE;
	}

	gpTDIR->Lock ();

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

		if ((! pba->fMustCopy) && pba->pFree)
			pba->pFree (pba);

		gpTDIR->Unlock ();
		return ERROR_SERVICE_NOT_ACTIVE;
	}

#if defined (DEBUG_PEER_SYNCHRONIZATION)
	PeerDebugData pd;
	PeerDebugData *ppd = NULL;
	if (BufferTotal (pba) >= sizeof(pd)) {
		memcpy (&pd, pba->pBuffer + pba->cEnd - sizeof(pd), sizeof(pd));
		if (pd.magic == DEBUG_PEER_MAGIC) {
			pba->cEnd -= sizeof(pd);
			ppd = &pd;
		}
	}

	if (! ppd) {
		IFDBG(DebugOut (DEBUG_ERROR, L"[TDI] tdir_data_up_ind : mismatch of peer debug builds!\n"));
		SVSUTIL_ASSERT (0);
	}
#endif

	int fDataAccepted = FALSE;

	//	Try to satisfy outstanding RECVs first...

	int cBytes = BufferTotal (pba);
	RFCOMM_CONNECTION_OBJECT *pConn = GetConnectionByHandle (hConnection);

	if ((cBytes > 0) && pConn && pConn->fc_credit)
		--pConn->iGaveCredits;

#if defined (DEBUG_CREDIT_FLOW)
	if (pConn && (cBytes > 0))
		++pConn->iPacketsRecv;

	if (pConn && pConn->fc_credit) {
		pConn->iCreditsRecv += additional_credits;
		// Credit Invariants

		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 + additional_credits != (pConn->iCreditsRecv - pConn->iPacketsSent)) {
			RETAILMSG(1, (L"Bluetooth TDI Credit mismatch: HaveCredits = %d (incl %d addtl) Total CreditsRecv = %d Total PacketsSent = %d\n", pConn->iHaveCredits + additional_credits, additional_credits, pConn->iCreditsRecv, pConn->iPacketsSent));
			SVSUTIL_ASSERT (0);
		}
	}
#endif

#if defined (DEBUG_PEER_SYNCHRONIZATION) && defined (DEBUG_CREDIT_FLOW)
	if (ppd && pConn) {
		SVSUTIL_ASSERT (ppd->iPacketsSent == pConn->iPacketsRecv);
		SVSUTIL_ASSERT (ppd->iCreditsSent == pConn->iCreditsRecv);
	}
#endif

	while (gpTDIR->fIsConnected && (cBytes > 0) && pConn && pConn->pRecvList && pConn->pRecvList->pNdisBuffer) {
		SVSUTIL_ASSERT (! pConn->pRecvList->pBuffer);

		NDIS_BUFFER *pNdis = pConn->pRecvList->pNdisBuffer;

		DWORD dwPerms = SetProcPermissions (pConn->pRecvList->dwPerms);
		BOOL  bkm = SetKMode (TRUE);

		int cBytesToTransfer = QueryNdisSize (pNdis);
		if (cBytes < cBytesToTransfer)
			cBytesToTransfer = cBytes;

		SVSUTIL_ASSERT (pConn->pRecvList->iNdisUsed == 0);

		uint StartOffset = 0;
		CopyFlatToNdis (pNdis, pba->pBuffer + pba->cStart, cBytesToTransfer, &StartOffset);

		SetKMode (bkm);
		SetProcPermissions (dwPerms);

		pba->cStart += cBytesToTransfer;
		pConn->pRecvList->iNdisUsed = cBytesToTransfer;

		cBytes = BufferTotal (pba);

		RFCOMM_RECEIVE_OBJECT *pThis = pConn->pRecvList;
		pConn->pRecvList = pConn->pRecvList->pNext;

		PBT_RECV_COMPLETE		pRecvEvent = pThis->pRecvEvent;
		void					*pRecvContext = pThis->pRecvContext;
		int						iNdisUsed = pThis->iNdisUsed;

		delete pThis;

		IFDBG(DebugOut (DEBUG_TDI_PACKETS, L"tdir_data_up_ind 0x%08x :: satisfied read request for %d bytes\n", pConn, iNdisUsed));

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

		pRecvEvent (pRecvContext, TDI_SUCCESS, iNdisUsed);

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

		if (gpTDIR->fIsInitialized)
			pConn = GetConnectionByHandle (hConnection);
		else
			pConn = NULL;
	}

	SVSUTIL_ASSERT (cBytes >= 0);

	if (gpTDIR->fIsConnected && (cBytes > 0) && pConn && pConn->pAddr &&
								((pConn->irecvd + cBytes) <= GetQuota (pConn))) {
		SVSUTIL_ASSERT ((! pConn->pRecvList) || pConn->pRecvList->pBuffer);

		RFCOMM_RECEIVE_OBJECT *pRecv = new RFCOMM_RECEIVE_OBJECT;
		if (pRecv) {
			memset (pRecv, 0, sizeof(*pRecv));
			pRecv->pBuffer = pba->fMustCopy ? BufferCopy (pba) : pba;
			if (! pConn->pRecvList)
				pConn->pRecvList = pRecv;
			else {
				RFCOMM_RECEIVE_OBJECT *pRP = pConn->pRecvList;
				while (pRP->pNext)
					pRP = pRP->pNext;
				pRP->pNext = pRecv;
			}

			fDataAccepted = TRUE;
			pConn->irecvd += cBytes;

			if (pConn->pAddr && (! pConn->cbDataIndicated)) {
			    // If we need to queue any data, we indicate it first.
				// Only indicate the first time since we are using the same data.

				pConn->cbDataIndicated = cBytes;
			    EventRcvBuffer     EventRecvCompleteInfo;    
				int                BytesTaken = 0;

				void *pEventReceiveContext = pConn->pAddr->pEventReceiveContext;
				void *pConnectionContext = pConn->pConnectionContext;
				PRcvEvent pEventReceive = pConn->pAddr->pEventReceive;

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

				TDI_STATUS TdiStatus = pEventReceive (pEventReceiveContext, pConnectionContext,
					0, cBytes, cBytes, (unsigned int *)&BytesTaken, NULL, &EventRecvCompleteInfo);

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

				IFDBG(DebugOut (DEBUG_TDI_PACKETS, L"tdir_data_up_ind 0x%08x :: indicated %d bytes\n", pConn, cBytes));

				SVSUTIL_ASSERT (TdiStatus == TDI_NOT_ACCEPTED);
				SVSUTIL_ASSERT (BytesTaken == 0);

				if (gpTDIR->fIsInitialized)
					pConn = GetConnectionByHandle (hConnection);
				else
					pConn = NULL;
			} else {
				IFDBG(DebugOut (DEBUG_TDI_PACKETS, L"tdir_data_up_ind 0x%08x :: data already indicated, stored %d bytes\n", pConn, cBytes));
			}

			if (pConn && (pConn->irecvd > pConn->xon_lim) && (! pConn->fc_local) && (! pConn->fc_credit)) {
				IFDBG(DebugOut (DEBUG_TDI_PACKETS, L"Switching flow off for connection 0x%08x\n", pConn));

				pConn->fc_local = TRUE;
				SendMSC (pConn, TDIR_V24_RTC|TDIR_V24_RTR, 0xff);
			}
		} else {
			IFDBG(DebugOut (DEBUG_ERROR, L"[TDIR] tdir_data_up_ind :: OOM !\n"));
		}
	}
#if defined (DEBUG) || defined (_DEBUG) || defined (RETAILLOG)
	else if (cBytes != 0) {
		IFDBG(DebugOut (DEBUG_ERROR, L"[TDI] Data came to nonexistent connection 0x%08x or overflow!\n", hConnection));
		if (gpTDIR->fIsConnected && pConn)
			IFDBG(DebugOut (DEBUG_ERROR, L"[TDI] Overflow details: received so far: %d, quota %d, bytes to queue %d\n", pConn->irecvd, GetQuota (pConn), cBytes));
	}
#endif

	if (! fDataAccepted) {
		if ((! pba->fMustCopy) && pba->pFree)
			pba->pFree (pba);
	}

	if (pConn && (pConn == GetConnectionByHandle (hConnection)) && pConn->fc_credit) {
		pConn->iHaveCredits += additional_credits;
		if (pConn->iHaveCredits - additional_credits <= 0)
			SendData (pConn);

		if (gpTDIR->fIsInitialized)
			pConn = GetConnectionByHandle (hConnection);
		else
			pConn = NULL;
	}

	if (pConn && pConn->fc_credit)
		SendCredits (pConn);

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

	return ERROR_SUCCESS;
}

static int tdir_disconnect_ind (void *pUserContext, HANDLE hConnection) {
	IFDBG(DebugOut (DEBUG_TDI_TRACE, L"+tdir_disconnect_ind\n"));
	if (! gpTDIR) {
		IFDBG(DebugOut (DEBUG_ERROR, L"[TDI] tdir_disconnect_ind : ERROR_SERVICE_NOT_ACTIVE\n"));
		return ERROR_SERVICE_NOT_ACTIVE;
	}

	gpTDIR->Lock ();

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

	ExtractPN (hConnection, NULL, NULL, NULL);

	RFCOMM_CONNECTION_OBJECT *pC = GetConnectionByHandle (hConnection);

	if (pC) {
		pC->hConnect = NULL;
		SignalConnectionLoss (pC, TDI_GRACEFUL_DISC, FALSE);
	} else
		IFDBG(DebugOut (DEBUG_WARN, L"[TDI] tdir_disconnect_ind : connection for handle 0x%08x not found or in process of being closed!\n", hConnection));

	IFDBG(DebugOut (DEBUG_TDI_TRACE, L"-tdir_disconnect_ind 0x%08x ERROR_SUCCESS\n", pC));
	gpTDIR->Unlock ();

	return ERROR_SUCCESS;
}

static int tdir_msc_ind (void *pUserContext, HANDLE hConnection, unsigned char v24, unsigned char bs) {
	IFDBG(D

⌨️ 快捷键说明

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