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

📄 l2cap.cxx

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

	IFDBG(DebugOut (DEBUG_L2CAP_TRACE, L"hci_disconnection_complete_event: ERROR_SUCCESS\n"));
	gpL2CAP->Unlock ();
	return ERROR_SUCCESS;
}

static int hci_create_connection_out (void *pCallContext, unsigned char status) {
	IFDBG(DebugOut (DEBUG_L2CAP_TRACE, L"hci_create_connection_out: status = %d\n", status));

	if (! gpL2CAP) {
		IFDBG(DebugOut (DEBUG_ERROR, L"hci_create_connection_out: ERROR_SERVICE_NOT_ACTIVE\n"));
		return ERROR_SERVICE_NOT_ACTIVE;
	}

	gpL2CAP->Lock ();

	if (gpL2CAP->eStage != Connected) {
		IFDBG(DebugOut (DEBUG_ERROR, L"hci_create_connection_out: ERROR_SERVICE_NOT_ACTIVE\n"));
		gpL2CAP->Unlock ();
		return ERROR_SERVICE_NOT_ACTIVE;
	}

	CallContext *pCall = VerifyCall ((CallContext *)pCallContext);

	if (! pCall) {
		IFDBG(DebugOut (DEBUG_ERROR, L"hci_create_connection_out: ERROR_NOT_FOUND\n"));
		gpL2CAP->Unlock ();
		return ERROR_NOT_FOUND;
	}

	SVSUTIL_ASSERT (VerifyPhys (pCall->u.pPhysLink));
	SVSUTIL_ASSERT (pCall->eWhat == CALL_PHYS_CONNECT);
	SVSUTIL_ASSERT (pCall->eType == CALL_CTX_INTERNAL);
	SVSUTIL_ASSERT (pCall->pOwner == NULL);
	SVSUTIL_ASSERT (! pCall->fKeepOnAbort);

	PhysLink *pLink = pCall->u.pPhysLink;

	if (status) {
		if (pLink->eStage == STARTING)
			DisconnectPhysicalLink (pLink, FALSE, StatusToError (status, ERROR_INTERNAL_ERROR), NULL);
		else
			IFDBG(DebugOut (DEBUG_WARN, L"hci_create_connection_out : failed with %d but allowing link to %04x%08x exist (it's UP)\n", status, pLink->b.NAP, pLink->b.SAP));
	}

	IFDBG(DebugOut (DEBUG_L2CAP_TRACE, L"hci_create_connection_out: ERROR_SUCCESS\n"));
	gpL2CAP->Unlock ();
	return ERROR_SUCCESS;
}

static int hci_connection_complete_event
(
void			*pUserContext,
void			*pCallContext,
unsigned char	status,
unsigned short	connection_handle,
BD_ADDR			*pba,
unsigned char	link_type,
unsigned char	encryption_mode
) {
	SVSUTIL_ASSERT (pUserContext == gpL2CAP);

	IFDBG(DebugOut (DEBUG_L2CAP_TRACE, L"hci_connection_complete_event: status = %d\n", status));

	if (! gpL2CAP) {
		IFDBG(DebugOut (DEBUG_ERROR, L"hci_connection_complete_event: ERROR_SERVICE_NOT_ACTIVE\n"));
		return ERROR_SERVICE_NOT_ACTIVE;
	}

	gpL2CAP->Lock ();

	if (gpL2CAP->eStage != Connected) {
		IFDBG(DebugOut (DEBUG_ERROR, L"hci_connection_complete_event: ERROR_SERVICE_NOT_ACTIVE\n"));
		gpL2CAP->Unlock ();
		return ERROR_SERVICE_NOT_ACTIVE;
	}

	CallContext *pCall = VerifyCall ((CallContext *)pCallContext);

	if (! pCall) {
		IFDBG(DebugOut (DEBUG_ERROR, L"hci_connection_complete_event: ERROR_NOT_FOUND\n"));
		gpL2CAP->Unlock ();
		return ERROR_NOT_FOUND;
	}

	SVSUTIL_ASSERT (VerifyPhys (pCall->u.pPhysLink));
	SVSUTIL_ASSERT ((pCall->eWhat == CALL_PHYS_CONNECT) || (pCall->eWhat == CALL_PHYS_ACCEPT));
	SVSUTIL_ASSERT (pCall->eType == CALL_CTX_INTERNAL);
	SVSUTIL_ASSERT (pCall->pOwner == NULL);
	SVSUTIL_ASSERT (! pCall->fKeepOnAbort);

	PhysLink *pLink = pCall->u.pPhysLink;

	SVSUTIL_ASSERT (pLink->b == *pba);

	if (status) {
		int iError = StatusToError (status, ERROR_INTERNAL_ERROR);
		int fRetry = FALSE;
		switch (status) {
		case BT_ERROR_NO_CONNECTION:
		case BT_ERROR_HARDWARE_FAILURE:
		case BT_ERROR_MAX_NUMBER_OF_CONNECTIONS:
		case BT_ERROR_MAX_NUMBER_OF_ACL_CONNECTIONS:
		case BT_ERROR_HOST_REJECTED_LIMITED_RESOURCES:
		case BT_ERROR_OETC_LOW_RESOURCES:
		case BT_ERROR_UNSUPPORTED_REMOTE_FEATURE:
			fRetry = TRUE;
		}

		DisconnectPhysicalLink (pLink, fRetry, iError, NULL);
		IFDBG(DebugOut (DEBUG_ERROR, L"hci_connection_complete_event : no connection, status = %d\n", status));
		gpL2CAP->Unlock ();
		return ERROR_SUCCESS;
	}

	DeleteCallContext (pCall);

	SVSUTIL_ASSERT (link_type == 1);
	SVSUTIL_ASSERT (pLink->h == BT_HCI_INVALID_HANDLE);

	pLink->h = connection_handle;
	pLink->eStage = UP;
	pLink->iConnectionAttempts = 0;
	pLink->iPingsSent = 0;
	pLink->iTransmissionProblems = 0;
	pLink->dwTimeOutCookie = 0;

	// Now do the thing for L2CAP connections...
#if defined (DEBUG) || defined (_DEBUG)
	{
		LogLink *pLog = pLink->pLogLinks;
		while (pLog) {
			SVSUTIL_ASSERT (pLog->eStage == STARTING_PHYS);
			pLog = pLog->pNext;
		}
	}
#endif

	if (! pLink->pLogLinks)
		ScheduleTimeout (pLink, gpL2CAP->dwConnectIdle);

	// If we have link policy, enable it.
	WriteLinkPolicy (connection_handle);

	// Do logical connections
	while ((gpL2CAP->eStage == Connected) && (pLink == VerifyPhys (pLink))) {
		LogLink *pLog = pLink->pLogLinks;
		while (pLog && (pLog->eStage != STARTING_PHYS))
			pLog = pLog->pNext;

		if (! pLog)
			break;

		CallContext *pCall = FindCall (pLog, CALL_LOG_CONNECT_REQ);
		if (pCall)
			SendConnectionRequest (pCall, TRUE);
		else {
			IFDBG(DebugOut (DEBUG_ERROR, L"Orphaned logical connection in hci_connection_complete_event\n"));
			DisconnectLogicalLink (pLog, ERROR_INTERNAL_ERROR, FALSE);
		}
	}

	//	Send pings
	while ((gpL2CAP->eStage == Connected) && (pLink == VerifyPhys (pLink))) {
		CallContext *pCall = gpL2CAP->pCalls;
		while (pCall && ((pCall->eWhat != CALL_PHYS_PING) || (! pCall->pData)))
			pCall = pCall->pNext;

		if (pCall) {
			ScheduleTimeout (pCall, gpL2CAP->RTX);

			unsigned char *pBuf = (unsigned char *)pCall->pData;
			int cSize = pCall->cData;

			pCall->pData = NULL;
			pCall->cData = 0;

			int iRes = WriteDataDown (connection_handle, pCall, cSize, pBuf);

			if ((iRes != ERROR_SUCCESS) && VerifyCall (pCall))
				CancelCall (pCall, iRes);
			
			g_funcFree (pBuf, g_pvFreeData);
		} else
			break;
	}

	IFDBG(DebugOut (DEBUG_L2CAP_TRACE, L"hci_connection_complete_event : ERROR_SUCCESS\n"));
	gpL2CAP->Unlock ();

	return ERROR_SUCCESS;
}

static int hci_connection_request_event
(
void			*pUserContext,
void			*pCallContext,
BD_ADDR			*pba,
unsigned int	class_of_device,
unsigned char	link_type
) {
	SVSUTIL_ASSERT (pUserContext == gpL2CAP);
	SVSUTIL_ASSERT (! pCallContext);

	IFDBG(DebugOut (DEBUG_L2CAP_TRACE, L"hci_connection_request_event: %04x%08x cod = 0x%08x link = %d\n", pba->NAP, pba->SAP, class_of_device, link_type));

	if (! gpL2CAP) {
		IFDBG(DebugOut (DEBUG_ERROR, L"hci_connection_request_event: ERROR_SERVICE_NOT_ACTIVE\n"));
		return ERROR_SERVICE_NOT_ACTIVE;
	}

	gpL2CAP->Lock ();

	if (gpL2CAP->eStage != Connected) {
		IFDBG(DebugOut (DEBUG_ERROR, L"hci_connection_request_event: ERROR_SERVICE_NOT_ACTIVE\n"));
		gpL2CAP->Unlock ();
		return ERROR_SERVICE_NOT_ACTIVE;
	}

	PhysLink *pLink = NULL;
	if (link_type == 1) {
		pLink = FindPhys (pba);
		if (! pLink) {
			pLink = CreateNewPhysLink ();
			if (pLink) {
				pLink->b = *pba;
				pLink->pNext = gpL2CAP->pPhysLinks;
				gpL2CAP->pPhysLinks = pLink;
			}
		}
	}

	if (pLink) {
		int iRes = ERROR_INTERNAL_ERROR;

		CallContext *pCall = AllocCallContext (CALL_CTX_INTERNAL, CALL_PHYS_ACCEPT, pLink, NULL, NULL);
		HCI_AcceptConnectionRequest_In pHCICall = gpL2CAP->hci_if.hci_AcceptConnectionRequest_In;
		HANDLE hHCI = gpL2CAP->hHCI;

		if (hHCI && pCall) {
			IFDBG(DebugOut (DEBUG_L2CAP_CALLBACK, L"Entering hci_AcceptConnectionRequest_In\n"));
			gpL2CAP->AddRef ();
			gpL2CAP->Unlock ();
			__try {
				iRes = pHCICall (hHCI, pCall, pba, gpL2CAP->bRole); // role == 0 => Become master...
			} __except (1) {
				IFDBG(DebugOut (DEBUG_ERROR, L"Exception in hci_AcceptConnectionRequest_In\n"));
			}
			gpL2CAP->Lock ();
			gpL2CAP->DelRef ();
			IFDBG(DebugOut (DEBUG_L2CAP_CALLBACK, L"Came from hci_AcceptConnectionRequest_In\n"));
		} else if (! pCall) {
			IFDBG(DebugOut (DEBUG_ERROR, L" : ERROR_OUTOFMEMORY\n"));
			iRes = ERROR_OUTOFMEMORY;
		} else
			IFDBG(DebugOut (DEBUG_ERROR, L"HCI disconnected!\n"));

		if (iRes != ERROR_SUCCESS) {
			DisconnectPhysicalLink (pLink, TRUE, iRes, NULL);
			pLink = NULL;
		}
	}

	if (! pLink) {	// Reject for no resources...
		HCI_RejectConnectionRequest_In pHCICall = gpL2CAP->hci_if.hci_RejectConnectionRequest_In;
		HANDLE hHCI = gpL2CAP->hHCI;

		int iRes = ERROR_INTERNAL_ERROR;

		if (hHCI) {
			IFDBG(DebugOut (DEBUG_L2CAP_CALLBACK, L"Entering hci_RejectConnectionRequest_In\n"));
			gpL2CAP->AddRef ();
			gpL2CAP->Unlock ();
			__try {
				iRes = pHCICall (hHCI, NULL, pba, BT_ERROR_HOST_REJECTED_LIMITED_RESOURCES);
			} __except (1) {
				IFDBG(DebugOut (DEBUG_ERROR, L"Exception in hci_RejectConnectionRequest_In\n"));
			}
			gpL2CAP->Lock ();
			gpL2CAP->DelRef ();
		} else
			IFDBG(DebugOut (DEBUG_ERROR, L"HCI disconnected!\n"));
	}

	gpL2CAP->Unlock ();

	return ERROR_SUCCESS;
}

static int hci_accept_connection_request_out (void *pCallContext, unsigned char status) {
	IFDBG(DebugOut (DEBUG_L2CAP_TRACE, L"hci_accept_connection_request_out: status = %d\n", status));

	if (! gpL2CAP) {
		IFDBG(DebugOut (DEBUG_ERROR, L"hci_accept_connection_request_out: ERROR_SERVICE_NOT_ACTIVE\n"));
		return ERROR_SERVICE_NOT_ACTIVE;
	}

	gpL2CAP->Lock ();

	if (gpL2CAP->eStage != Connected) {
		IFDBG(DebugOut (DEBUG_ERROR, L"hci_accept_connection_request_out: ERROR_SERVICE_NOT_ACTIVE\n"));
		gpL2CAP->Unlock ();
		return ERROR_SERVICE_NOT_ACTIVE;
	}

	CallContext *pCall = VerifyCall ((CallContext *)pCallContext);

	if (! pCall) {
		IFDBG(DebugOut (DEBUG_ERROR, L"hci_connection_complete_event: ERROR_NOT_FOUND\n"));
		gpL2CAP->Unlock ();
		return ERROR_NOT_FOUND;
	}

	SVSUTIL_ASSERT (VerifyPhys (pCall->u.pPhysLink));
	SVSUTIL_ASSERT (pCall->eWhat == CALL_PHYS_ACCEPT);
	SVSUTIL_ASSERT (pCall->eType == CALL_CTX_INTERNAL);
	SVSUTIL_ASSERT (pCall->pOwner == NULL);
	SVSUTIL_ASSERT (! pCall->fKeepOnAbort);

	PhysLink *pLink = pCall->u.pPhysLink;

	if (status) {
		int iError = StatusToError (status, ERROR_INTERNAL_ERROR);
		int fRetry = FALSE;
		switch (status) {
		case BT_ERROR_NO_CONNECTION:
		case BT_ERROR_HARDWARE_FAILURE:
		case BT_ERROR_MAX_NUMBER_OF_CONNECTIONS:
		case BT_ERROR_MAX_NUMBER_OF_ACL_CONNECTIONS:
		case BT_ERROR_HOST_REJECTED_LIMITED_RESOURCES:
		case BT_ERROR_HOST_TIMEOUT:
		case BT_ERROR_OETC_LOW_RESOURCES:
		case BT_ERROR_UNSUPPORTED_REMOTE_FEATURE:
		case BT_ERROR_UNSPECIFIED_ERROR:
			fRetry = TRUE;
		}

		DisconnectPhysicalLink (pLink, fRetry, iError, NULL);
		IFDBG(DebugOut (DEBUG_ERROR, L"hci_accept_connection_request_out - orphaned call\n"));
		gpL2CAP->Unlock ();
		return ERROR_SUCCESS;
	}

	IFDBG(DebugOut (DEBUG_L2CAP_TRACE, L"hci_accept_connection_request_out : ERROR_SUCCESS\n"));
	gpL2CAP->Unlock ();

	return ERROR_SUCCESS;
}

static int hci_reject_connection_request_out (void *pNull, unsigned char status) {
	SVSUTIL_ASSERT (pNull == NULL);
	SVSUTIL_ASSERT (status == 0);
	return ERROR_SUCCESS;
}

static int hci_write_scan_enable_out (void *pNull, unsigned char status) {
	SVSUTIL_ASSERT (pNull == NULL);
	SVSUTIL_ASSERT (status == 0);
	return ERROR_SUCCESS;
}

static int hci_pin_code_request_negative_reply_out (void *pNull, unsigned char status, BD_ADDR *pba) {
	SVSUTIL_ASSERT (pNull == NULL);
	SVSUTIL_ASSERT (status == 0);
	return ERROR_SUCCESS;
}

static int hci_pin_code_request_reply_out (void *pNull, unsigned char status, BD_ADDR *pba) {
	SVSUTIL_ASSERT (pNull == NULL);
	SVSUTIL_ASSERT (status == 0);
	return ERROR_SUCCESS;
}

static int hci_link_key_request_negative_reply_out (void *pNull, unsigned char status, BD_ADDR *pba) {
	SVSUTIL_ASSERT (pNull == NULL);
	SVSUTIL_ASSERT (status == 0);
	return ERROR_SUCCESS;
}

static int hci_link_key_request_reply_out (void *pNull, unsigned char status, BD_ADDR *pba) {
	SVSUTIL_ASSERT (pNull == NULL);
	SVSUTIL_ASSERT (status == 0);
	return ERROR_SUCCESS;
}

static int hci_data_packet_up (void *pUserContext, unsigned short connection_handle, BD_BUFFER *pBuffer) {
	SVSUTIL_ASSERT (pUserContext == gpL2CAP);

	IFDBG(DebugOut (DEBUG_L2CAP_TRACE, L"hci_data_packet_up: h = 0x%04x\n", connection_handle));

	if (! gpL2CAP) {
		IFDBG(DebugOut (DEBUG_ERROR, L"hci_connection_request_event: ERROR_SERVICE_NOT_ACTIVE\n"));
		return ERROR_SERVICE_NOT_ACTIVE;
	}

	gpL2CAP->Lock ();

	IFDBG(DebugOut (DEBUG_L2CAP_PACKETS, L"Data Packet :: connection 0x%04x %d bytes\n", connection_handle, BufferTotal (pBuffer)));
	IFDBG(DumpBuff (DEBUG_L2CAP_PACKETS, pBuffer->pBuffer + pBuffer->cStart, BufferTotal (pBuffer)));

	if (gpL2CAP->eStage != Connected) {
		IFDBG(DebugOut (DEBUG_ERROR, L"hci_connection_request_event: ERROR_SERVICE_NOT_ACTIVE\n"));

		if (pBuffer->pFree)
			pBuffer->pFree (pBuffer);

		gpL2CAP->Unlock ();
		return ERROR_SERVICE_NOT_ACTIVE;
	}

	// Gotta be L2CAP packet - do quick sanity check.
	PhysLink *pPhys = FindPhys (connection_handle);

	if ((! pPhys) || (pPhys->eStage != UP)) {
		IFDBG(DebugOut (DEBUG_ERROR, L"hci_data_packet_up - orphaned call\n"));

		if (pBuffer->pFree)
			pBuffer->pFree (pBuffer);

		gpL2CAP->Unlock ();
		return ERROR_INTERNAL_ERROR;
	}

	unsigned short length = 0xffff;
	unsigned short cid = 0xffff;
	if ((! BufferGetShort (pBuffer, &length)) || (! BufferGetShort (pBuffer, &cid)) || (BufferTotal(pBuffer) != length) || (! length)) {
		IFDBG(DebugOut (DEBUG_ERROR, L"hci_data_packet_up - malformed packet (length = 0x%04x, cid = 0x%04x, buffer bytes = 0x%04x)\n", cid, length, BufferTotal (pBuffer)));
		RegisterTransmissionError (pPhys);

		if (pBuffer->pFree)
			pBuffer->pFree (pBuffer);

		gpL2CAP->Unlock ();
		return ERROR_INVALID_DATA;
	}

	if (cid != 0x0001) {
		LogLink *pLog = FindCID (cid, pPhys);
		L2CAP_CONTEXT *pOwner = pLog ? VerifyContext (pLog->pOwner) : NULL;
		if ((! pLog) || (pLog->eStage != UP) || (! pOwner)) {
			IFDBG(DebugOut (DEBUG_ERROR, L"Wrong CID - no connection or not UP!\n"));
			if (pBuffer->pFree)
				pBuffer->pFree (pBuffer);

			gpL2CAP->Unlock ();
			return ERROR_INVALID_DATA;
		}

		IFDBG(DebugOut (DEBUG_L2CAP_PACKETS, L"Got data packet for cid 0x%04x\n", cid));

		L2CA_DataUpInd pCallback = pOwner->ei.l2ca_DataUpInd;
		void *pUserContext = pOwner->pUserContext;

		IFDBG(DebugOut (DEBUG_L2CAP_CALLBACK, L"hci_data_packet_up : routing packet up\n"));
		pOwner->AddRef ();
		gpL2CAP->Unlock ();
		int iRes = ERROR_INTERNAL_ERROR;
		__try {
			iRes = pCallback (pUserContext, cid, pBuffer);
		} __except(1) {
			IFDBG(DebugOut (DEBUG_ERROR, L"hci_data_packet_up :: exception while processing callback cid = 0x%04x\n", cid));
		}
		gpL2CAP->Lo

⌨️ 快捷键说明

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