📄 sdpbase.cxx
字号:
iRes = pCallbackConfig(hL2CAP, pCall, cid, mtu, 0xffff, NULL, 0, NULL);
} __except (1) {
IFDBG(DebugOut(DEBUG_ERROR,L"Exception in l2ca_ConfigReq_In\r\n"));
}
IFDBG(DebugOut(DEBUG_SDP_CALLBACK,L"Came from l2ca_ConfigReq_In\r\n"));
if (iRes != ERROR_SUCCESS) {
sdp_lCallAborted(pCall, iRes);
}
}
gpSDP->Lock();
gpSDP->DelRef();
gpSDP->Unlock();
return ERROR_SUCCESS;
}
static int sdp_ConnectReq_Out(void *pCallContext, unsigned short cid, unsigned short result, unsigned short status) {
IFDBG(DebugOut(DEBUG_SDP_TRACE,L"sdp_ConnectReq_Out(0x%08x,%d,%d,%d)\r\n",cid,result,status));
if (result)
return sdp_lCallAborted(pCallContext,ERROR_CONNECTION_UNAVAIL);
if (! gpSDP)
return ERROR_SERVICE_NOT_ACTIVE;
gpSDP->Lock();
if (gpSDP->eStage != Connected) {
gpSDP->Unlock();
return ERROR_SERVICE_NOT_ACTIVE;
}
Call *pCall = VerifyCall((Call *)pCallContext,CALL_SDP_ACCEPT_CONNECT);
if (! pCall) {
gpSDP->Unlock();
return ERROR_NOT_FOUND;
}
SVSUTIL_ASSERT(VerifyLink(pCall->pLink));
Link *pLink = pCall->pLink;
SVSUTIL_ASSERT(pLink->fStage == NONE);
SVSUTIL_ASSERT(! pLink->cid);
SVSUTIL_ASSERT(pLink->psm);
pLink->fStage = CONNECTED;
pLink->cid = cid;
unsigned short mtu = pLink->inMTU;
HANDLE hL2CAP = gpSDP->hL2CAP;
L2CA_ConfigReq_In pCallback = gpSDP->l2cap_if.l2ca_ConfigReq_In;
IFDBG(DebugOut(DEBUG_SDP_CALLBACK,L"Calling into l2ca_ConfigReq_In\r\n"));
gpSDP->AddRef();
gpSDP->Unlock();
int iRes = ERROR_INTERNAL_ERROR;
__try {
iRes = pCallback(hL2CAP, pCallContext, cid, mtu, 0xffff, NULL, 0, NULL);
} __except (1) {
IFDBG(DebugOut(DEBUG_ERROR,L"Exception in l2ca_ConfigReq_In\r\n"));
}
if (iRes != ERROR_SUCCESS)
sdp_lCallAborted(pCallContext, iRes);
gpSDP->Lock();
gpSDP->DelRef();
IFDBG(DebugOut(DEBUG_SDP_CALLBACK,L"Came from l2ca_ConfigReq_In\r\n"));
gpSDP->Unlock();
return ERROR_SUCCESS;
}
static int sdp_DataDown_Out(void *pCallContext, unsigned short result) {
IFDBG(DebugOut(DEBUG_SDP_TRACE,L"sdp_DataDown_Out(0x%08x,%d)\r\n",pCallContext,result));
if (! gpSDP)
return ERROR_SERVICE_NOT_ACTIVE;
gpSDP->Lock();
if (gpSDP->eStage != Connected) {
gpSDP->Unlock();
return ERROR_SERVICE_NOT_ACTIVE;
}
Call *pCall = VerifyCall((Call *) pCallContext,CALL_SDP_SEARCH_WORKER);
if (! pCall) {
gpSDP->Unlock();
return ERROR_NOT_FOUND;
}
SVSUTIL_ASSERT(VerifyLink(pCall->pLink));
gpSDP->Unlock();
return ERROR_SUCCESS;
}
static int sdp_Disconnect_Out(void *pCallContext, unsigned short result) {
IFDBG(DebugOut(DEBUG_SDP_TRACE,L"sdp_Disconnect_Out(0x%08x,%d)\r\n",pCallContext,result));
if (! gpSDP)
return ERROR_SERVICE_NOT_ACTIVE;
gpSDP->Lock();
Call *pCall = pCallContext ? VerifyCall((Call*) pCallContext,CALL_SDP_DISCONNECT) : NULL;
if (pCall)
NotifySdpClientOfCompletion(pCall,result);
gpSDP->Unlock();
return ERROR_SUCCESS;
}
// These are just stubs - they do nothing
static int sdp_ConfigResponse_Out(void *pCallContext, unsigned short result) {
return ERROR_SUCCESS;
}
static int sdp_ConnectResponse_Out(void *pCallContext, unsigned short result) {
return ERROR_SUCCESS;
}
//**************************************************************
// Device Driver init and deinit functions
//**************************************************************
int sdp_InitializeOnce(void) {
IFDBG(DebugOut(DEBUG_SDP_INIT | DEBUG_SDP_TRACE,L"sdp_InitializeOnce()\r\n"));
SVSUTIL_ASSERT(! gpSDP && !gpSdpReadBuffer);
if (gpSDP) {
IFDBG(DebugOut(DEBUG_ERROR,L"sdp_InitializeOnce:: ERROR_ALREADY_EXISTS\r\n"));
return ERROR_ALREADY_EXISTS;
}
gpSDP = CreateNewSDP();
if (gpSDP) {
gpSdpReadBuffer = (unsigned char*) g_funcAlloc(MAX_MTU_SIZE,g_pvAllocData);
if (gpSdpReadBuffer) {
IFDBG(DebugOut(DEBUG_SDP_INIT, L"sdp_InitializeOnce:: ERROR_SUCCESS\n"));
return ERROR_SUCCESS;
}
delete gpSDP;
gpSDP = NULL;
}
IFDBG(DebugOut(DEBUG_ERROR, L"sdp_InitializeOnce:: ERROR_OUTOFMEMORY\n"));
return ERROR_OUTOFMEMORY;
}
int sdp_CreateDriverInstance(void) {
int iErr;
IFDBG(DebugOut(DEBUG_SDP_INIT | DEBUG_SDP_TRACE,L"sdp_CreateDriverInstance()\r\n"));
if (! gpSDP) {
IFDBG(DebugOut(DEBUG_ERROR, L"sdp_CreateDriverInstance:: ERROR_SERVICE_DOES_NOT_EXIST\n"));
return ERROR_SERVICE_DOES_NOT_EXIST;
}
gpSDP->Lock();
if (gpSDP->eStage != JustCreated) {
IFDBG(DebugOut(DEBUG_ERROR, L"sdp_CreateDriverInstance:: ERROR_SERVICE_ALREADY_RUNNING\n"));
gpSDP->Unlock();
return ERROR_SERVICE_ALREADY_RUNNING;
}
SVSUTIL_ASSERT(!gpSDP->pfmdLinks && !gpSDP->pfmdSdpConnections &&
!gpSDP->pfmdCallQueue && !gpSDP->pfmdBuffers);
gpSDP->eStage = Initializing;
// Setup gpSDP.
gpSDP->pfmdLinks = svsutil_AllocFixedMemDescr(sizeof(Link), SDP_SCALE);
gpSDP->pfmdCalls = svsutil_AllocFixedMemDescr(sizeof(Call), SDP_SCALE);
gpSDP->pfmdSdpConnections = svsutil_AllocFixedMemDescr(sizeof(SdpConnection), SDP_SCALE);
gpSDP->pfmdCallQueue = svsutil_AllocFixedMemDescr(sizeof(CallQueue), SDP_SCALE);
gpSDP->pfmdBuffers = svsutil_AllocFixedMemDescr(sizeof(BD_BUFFER), SDP_SCALE);
if (!pSdpDB) {
pSdpDB = CreateNewSdpDatabase();
if (pSdpDB && (STATUS_SUCCESS != pSdpDB->Init())) {
delete pSdpDB;
pSdpDB = NULL;
}
}
if (! (gpSDP->pfmdLinks && gpSDP->pfmdCalls && gpSDP->pfmdSdpConnections &&
gpSDP->pfmdCallQueue && gpSDP->pfmdBuffers && gpSDP->pfmdBuffers &&
pSdpDB)) {
IFDBG(DebugOut(DEBUG_ERROR,L"sdp_CreateDriverInstance: ERROR_OUTOFMEMORY\r\n"));
CleanupSDPState();
gpSDP->Unlock();
return ERROR_OUTOFMEMORY;
}
// Configure L2CAP
L2CAP_EVENT_INDICATION lei;
memset(&lei, 0, sizeof(lei));
lei.l2ca_ConfigInd = sdp_ConfigInd;
lei.l2ca_ConnectInd = sdp_ConnectInd;
lei.l2ca_DataUpInd = sdp_DataUpInd;
lei.l2ca_DisconnectInd = sdp_DisconnectInd;
lei.l2ca_StackEvent = sdp_lStackEvent;
L2CAP_CALLBACKS lc;
memset(&lc, 0, sizeof(lc));
lc.l2ca_ConfigReq_Out = sdp_ConfigReq_Out;
lc.l2ca_ConfigResponse_Out = sdp_ConfigResponse_Out;
lc.l2ca_ConnectReq_Out = sdp_ConnectReq_Out;
lc.l2ca_ConnectResponse_Out = sdp_ConnectResponse_Out;
lc.l2ca_DataDown_Out = sdp_DataDown_Out;
lc.l2ca_Disconnect_Out = sdp_Disconnect_Out;
lc.l2ca_CallAborted = sdp_lCallAborted;
if (ERROR_SUCCESS != (iErr = L2CAP_EstablishDeviceContext (gpSDP, PSM_SDP, &lei, &lc, &gpSDP->l2cap_if,&gpSDP->cDataHeaders,&gpSDP->cDataTrailers,&gpSDP->hL2CAP))) {
IFDBG((DEBUG_ERROR,L"sdp_CreateDriverInstance could not plug into L2CAP, exiting\r\n"));
CleanupSDPState();
gpSDP->Unlock();
return iErr;
}
if (! (gpSDP->l2cap_if.l2ca_ConnectReq_In && gpSDP->l2cap_if.l2ca_ConfigReq_In &&
gpSDP->l2cap_if.l2ca_ConfigResponse_In && gpSDP->l2cap_if.l2ca_Disconnect_In &&
gpSDP->l2cap_if.l2ca_ConnectResponse_In && gpSDP->l2cap_if.l2ca_AbortCall &&
gpSDP->l2cap_if.l2ca_DataDown_In)) {
IFDBG(DebugOut(DEBUG_ERROR,L"sdp_CreateDriverInstance fails because not all functions required by SDP are exposed by the L2CAP layer\r\n"));
L2CAP_CloseDeviceContext (gpSDP->hL2CAP);
CleanupSDPState();
gpSDP->Unlock();
return iErr;
}
#if 0 // Currently this reg param is unused
HKEY hk;
if (ERROR_SUCCESS == RegOpenKeyEx (HKEY_BASE, g_SdpBaseRegKey, 0, KEY_READ, &hk)) {
DWORD dwSize = sizeof(gpSDP->dwSdpIdle);
DWORD dwType = REG_DWORD;
RegQueryValueEx(hk, g_SdpLinkIdle, NULL, &dwType, (LPBYTE)&gpSDP->dwSdpIdle, &dwSize);
if ((dwSize != sizeof(gpSDP->dwSdpIdle)) || (dwType != REG_DWORD))
gpSDP->dwSdpIdle = SDP_DEFAULT_LINK_TIMEOUT_MS;
IFDBG(DebugOut(DEBUG_SDP_INIT,L"SdpLinkIdle time = %d ms\r\n",gpSDP->dwSdpIdle));
RegCloseKey(hk);
}
#endif
gpSDP->eStage = Disconnected;
GetConnectionState();
IFDBG(DebugOut(DEBUG_SDP_INIT,L"sdp_CreateDriverInstance returns ERROR_SUCCESS\r\n"));
gpSDP->Unlock();
return ERROR_SUCCESS;
}
int sdp_CloseDriverInstance (void) {
IFDBG(DebugOut(DEBUG_SDP_INIT | DEBUG_SDP_TRACE,L"sdp_CloseDriverInstance()\r\n"));
if (! gpSDP) {
IFDBG(DebugOut(DEBUG_ERROR,L"sdp_CloseDriverInstance: ERROR_SERVICE_NOT_ACTIVE\r\n"));
return ERROR_SERVICE_NOT_ACTIVE;
}
gpSDP->Lock();
if ((gpSDP->eStage == JustCreated) || (gpSDP->eStage == ShuttingDown)) {
IFDBG(DebugOut(DEBUG_ERROR, L"SDP Close Driver Instance:: ERROR_SERVICE_NOT_ACTIVE\n"));
gpSDP->Unlock();
return ERROR_SERVICE_NOT_ACTIVE;
}
gpSDP->eStage = ShuttingDown;
while (gpSDP->pCalls) {
NotifySdpClientOfCompletion(gpSDP->pCalls,ERROR_CANCELLED);
}
while (gpSDP->pLinks) {
SVSUTIL_ASSERT(gpSDP->pLinks->pCallQueue == NULL);
SdpDisconnect(gpSDP->pLinks,NULL);
}
if (gpSDP->hL2CAP) {
while (gpSDP->GetRefCount() > 1) {
IFDBG(DebugOut (DEBUG_SDP_TRACE, L"Waiting for ref count in sdp_CloseDriverInstance\n"));
gpSDP->Unlock();
Sleep(200);
gpSDP->Lock();
}
L2CAP_CloseDeviceContext(gpSDP->hL2CAP);
}
while (gpSDP->pContexts) {
SDP_CONTEXT *pThis = gpSDP->pContexts;
gpSDP->pContexts = pThis->pNext;
if (pThis->ei.sdp_StackEvent) {
BT_LAYER_STACK_EVENT_IND pCallback = pThis->ei.sdp_StackEvent;
void *pUserContext = pThis->pUserContext;
IFDBG(DebugOut(DEBUG_SDP_TRACE, L"Going into StackEvent notification(stack down)\r\n"));
pThis->AddRef();
gpSDP->Unlock();
__try {
pCallback(pUserContext, BTH_STACK_DOWN, NULL);
} __except(1) {
IFDBG(DebugOut(DEBUG_ERROR, L"Exception in higher layer code\r\n"));
}
gpSDP->Lock();
pThis->DelRef();
IFDBG(DebugOut(DEBUG_SDP_TRACE, L"Came back StackEvent notification\r\n"));
}
while (pThis->GetRefCount() > 1) {
IFDBG(DebugOut (DEBUG_SDP_TRACE, L"Waiting for ref count in sdp_CloseDriverInstance\n"));
gpSDP->Unlock();
Sleep(100);
gpSDP->Lock();
}
delete pThis;
}
SVSUTIL_ASSERT(gpSDP->eStage == ShuttingDown);
CleanupSDPState();
gpSDP->Unlock();
return ERROR_SUCCESS;
}
int sdp_UninitializeOnce(void) {
IFDBG(DebugOut(DEBUG_SDP_INIT | DEBUG_SDP_TRACE,L"sdp_UninitializeOnce()\r\n"));
SVSUTIL_ASSERT(gpSDP);
if (! gpSDP) {
IFDBG(DebugOut(DEBUG_ERROR, L"SDP uninit:: ERROR_SERVICE_DOES_NOT_EXIST\n"));
return ERROR_SERVICE_DOES_NOT_EXIST;
}
gpSDP->Lock();
if (gpSDP->eStage != JustCreated) {
IFDBG(DebugOut(DEBUG_ERROR, L"SDP uninit:: ERROR_DEVICE_IN_USE\n"));
gpSDP->Unlock();
return ERROR_DEVICE_IN_USE;
}
if (pSdpDB) {
delete pSdpDB;
pSdpDB = NULL;
}
if (gpSdpReadBuffer) {
g_funcFree(gpSdpReadBuffer,g_pvAllocData);
gpSdpReadBuffer = NULL;
}
if (gpSpdConnectionLocal) {
DeleteSdpConnection(gpSpdConnectionLocal);
gpSpdConnectionLocal = NULL;
}
SDP *pSDP = gpSDP;
gpSDP = NULL;
pSDP->Unlock();
delete pSDP;
IFDBG(DebugOut(DEBUG_SDP_INIT, L"SDP uninit:: ERROR_SUCCESS\n");)
return ERROR_SUCCESS;
}
static int SdpCreateConnection(Call *pCall, BD_ADDR *pba) {
SVSUTIL_ASSERT(gpSDP->IsLocked());
SVSUTIL_ASSERT(!pCall->pLink);
Link *pLink = AllocLink();
if (!pLink) {
IFDBG(DebugOut(DEBUG_ERROR,L"sdp_Connect:: ERROR_OUTOFMEMORY\r\n"));
return ERROR_OUTOFMEMORY;
}
pLink->pNext = gpSDP->pLinks;
gpSDP->pLinks = pLink;
pCall->pLink = pLink;
pLink->cid = 0;
pLink->b = *pba;
pLink->fStage = NONE;
pLink->inMTU = DEFAULT_IN_MTU_SIZE;
pLink->fIncoming = FALSE;
HANDLE hL2CAP = gpSDP->hL2CAP;
L2CA_ConnectReq_In pCallbackConnect = gpSDP->l2cap_if.l2ca_ConnectReq_In;
int iRes = ERROR_INTERNAL_ERROR;
IFDBG(DebugOut(DEBUG_SDP_CALLBACK,L"Calling into l2ca_ConnectReq_In\r\n"));
gpSDP->AddRef();
gpSDP->Unlock();
__try {
iRes = pCallbackConnect(hL2CAP, pCall, PSM_SDP, pba);
} __except(1) {
IFDBG(DebugOut(DEBUG_ERROR,L"Exception in l2ca_ConnectReq_In!!!\r\n"));
}
gpSDP->Lock();
gpSDP->DelRef();
IFDBG(DebugOut(DEBUG_SDP_CALLBACK,L"came from l2ca_ConnectReq_In\r\n"));
return iRes;
}
//******************************************************************
// Replaced functions from NT SDP layer class.
//******************************************************************
unsigned long
SdpConnection::SendInitialRequestToServer(void) {
// Client data has request to send, rawParametersLength doesn't count PDU or continuation state info.
return Write(u.Client.pRequest,u.Client.rawParametersLength + sizeof(SdpPDU) + sizeof(UCHAR));
}
// Called by functions in btsdp.cpp, this will send request if there's nothing busy or queue it otherwise.
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -