📄 l2cap.cxx
字号:
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 + -