📄 sdpbase.cxx
字号:
unsigned long SdpConnection::SendOrQueueRequest() {
Call *pCall = (Call *) pCallContext;
Link *pLink = pCall->pLink;
int iErr = STATUS_PENDING;
CallQueue *pCallQueue;
SVSUTIL_ASSERT(gpSDP->IsLocked());
SVSUTIL_ASSERT(VerifyCall(pCall,CALL_SDP_SEARCH));
SVSUTIL_ASSERT(VerifyLink(pLink));
if (! (pCallQueue = AddItemToCallQueue(pLink,pCall))) {
return ERROR_OUTOFMEMORY;
}
if (pCallQueue == pLink->pCallQueue && !pLink->fCallCanceled)
iErr = SendInitialRequestToServer();
return iErr;
}
NTSTATUS
SdpConnection::Write(
void *pBuffer,
unsigned long length
)
{
SVSUTIL_ASSERT(gpSDP->IsLocked());
Call *pCall = (Call *) pCallContext;
SVSUTIL_ASSERT(VerifyCall(pCall,CALL_SDP_SEARCH_WORKER));
SVSUTIL_ASSERT(VerifyLink(pCall->pLink));
#if defined (DEBUG) || defined (_DEBUG)
// call we're about to service better be first on send queue.
if (pCall->fWhat & CALL_SDP_SEARCH)
SVSUTIL_ASSERT(pCall->pLink->pCallQueue->pCall == pCall);
#endif
return SendData(pCall,(unsigned char*)pBuffer,length);
}
BOOL SdpConnection::IsClient() {
return ! ((Call*) pCallContext)->pLink->fIncoming;
}
BOOL SdpConnection::IsServer() {
return ((Call*) pCallContext)->pLink->fIncoming;
}
// Code that relies on CSemaphore locking mechanism is from NT port, and is always wrapped
// in the SDP CritSec. Put ASSERTS in to be sure
BOOLEAN CSemaphore::ReleaseSem(KPRIORITY Increment,LONG Adjustment, BOOLEAN bWait) {
SVSUTIL_ASSERT(gpSDP && gpSDP->IsLocked());
return TRUE;
}
void CSemaphore::AcquireSem() {
SVSUTIL_ASSERT(gpSDP && gpSDP->IsLocked());
}
// Required to map status codes returned by NT SDP layer
static int MapStatusToErrorCode(int status) {
switch (status) {
case ERROR_SUCCESS:
return ERROR_SUCCESS;
case ERROR_INVALID_PARAMETER:
case STATUS_UNSUCCESSFUL:
case STATUS_INVALID_PARAMETER:
case STATUS_DEVICE_PROTOCOL_ERROR:
case STATUS_INVALID_NETWORK_RESPONSE:
return ERROR_INVALID_PARAMETER;
case ERROR_NOT_FOUND:
case STATUS_NOT_FOUND:
return ERROR_NOT_FOUND;
case ERROR_OUTOFMEMORY:
case STATUS_INSUFFICIENT_RESOURCES:
return ERROR_OUTOFMEMORY;
default:
SVSUTIL_ASSERT(0);
}
return status;
}
//******************************************************************
// SDP Interface
//******************************************************************
// AddRecord and RemoveRecord run totally locally, no need
// to have them be Asyncronous. Since they run locally we only need to make
// sure SDP stack is running since we don't use lower L2CAP layers in these calls.
static int sdp_AddRecord(HANDLE hDeviceContext, UCHAR *pStream, unsigned long streamSize, HANDLE *pRecordHandle) {
int iRet;
IFDBG(DebugOut(DEBUG_SDP_TRACE,L"sdp_AddRecord(0x%08x,0x%08x,%d)\r\n",hDeviceContext,pStream,streamSize));
if (! gpSDP) {
IFDBG(DebugOut(DEBUG_WARN,L"sdp_AddRecord returns ERROR_SERVICE_NOT_ACTIVE\r\n"));
return ERROR_SERVICE_NOT_ACTIVE;
}
gpSDP->Lock();
if (!gpSDP->IsStackRunning()) {
gpSDP->Unlock();
return ERROR_SERVICE_NOT_ACTIVE;
}
if (!VerifyContext((SDP_CONTEXT*) hDeviceContext) || !pStream || streamSize == 0 || !pRecordHandle)
iRet = ERROR_INVALID_PARAMETER;
else {
#if defined (UNDER_CE)
// if *pRecordHandle is non NULL, then treat it as an update and not add record.
iRet = *pRecordHandle ? pSdpDB->UpdateRecord(pStream,streamSize,*pRecordHandle) : pSdpDB->AddRecord(pStream,streamSize,pRecordHandle);
if (iRet != ERROR_SUCCESS)
*pRecordHandle = 0;
#else // WINCE_EMULATION
iRet = pSdpDB->AddRecord(pStream,streamSize,pRecordHandle);
#endif // UNDER_CE
}
gpSDP->Unlock();
#if defined (UNDER_CE)
IFDBG(DebugOut(DEBUG_SDP_TRACE,L"sdpAddRecord returns 0x%08x, *pRecordHandle=0x%08x\r\n",iRet,*pRecordHandle));
#endif
return MapStatusToErrorCode(iRet);
}
static int sdp_RemoveRecord(HANDLE hDeviceContext, HANDLE hRecordHandle) {
int iRet;
unsigned long iRemovedRecord;
IFDBG(DebugOut(DEBUG_SDP_TRACE,L"sdp_RemoveRecord(0x%08x,0x%08x)\r\n",hDeviceContext,hRecordHandle));
if (! gpSDP) {
IFDBG(DebugOut(DEBUG_WARN,L"sdp_RemoveRecord ERROR_SERVICE_NOT_ACTIVE\r\n"));
return ERROR_SERVICE_NOT_ACTIVE;
}
gpSDP->Lock();
if (!gpSDP->IsStackRunning()) {
gpSDP->Unlock();
return ERROR_SERVICE_NOT_ACTIVE;
}
if (!VerifyContext((SDP_CONTEXT*) hDeviceContext))
iRet = ERROR_INVALID_PARAMETER;
else
iRet = pSdpDB->RemoveRecord(hRecordHandle,&iRemovedRecord);
gpSDP->Unlock();
IFDBG(DebugOut(DEBUG_SDP_TRACE,L"sdpRemoveRecord returns 0x%08x\r\n",iRet));
return MapStatusToErrorCode(iRet);
}
static int SdpDisconnect(Link *pLink, Call *pCall) {
SVSUTIL_ASSERT( VerifyLink(pLink));
HANDLE hL2CAP = gpSDP->hL2CAP;
L2CA_Disconnect_In pCallback = gpSDP->l2cap_if.l2ca_Disconnect_In;
unsigned short cid = pLink->cid;
int iRes = ERROR_INTERNAL_ERROR;
IFDBG(DebugOut(DEBUG_SDP_CALLBACK,L"Entering l2ca_Disconnect_In, cid = 0x%04x\r\n",pLink->cid));
gpSDP->AddRef();
gpSDP->Unlock();
__try {
iRes = pCallback (hL2CAP, pCall, cid);
} __except (1) {
IFDBG(DebugOut(DEBUG_ERROR,L"Exception in l2ca_Disconnect_In\r\n"));
}
gpSDP->Lock();
gpSDP->DelRef();
IFDBG(DebugOut(DEBUG_SDP_CALLBACK,L"Finished with l2ca_Disconnect_In\r\n");)
DeleteLink(pLink);
return iRes;
}
static int sdp_Connect_In(HANDLE hDeviceContext, void *pCallContext, BD_ADDR *pba) {
IFDBG(DebugOut(DEBUG_SDP_TRACE,L"sdp_Connect_In(0x%08x,0x%08x,0x%08x 0x%04)\r\n",
hDeviceContext,pCallContext,pba->NAP,pba->SAP));
if (! gpSDP) {
IFDBG(DebugOut(DEBUG_ERROR,L"sdp_Connect_In: ERROR_SERVICE_NOT_ACTIVE\r\n"));
return ERROR_SERVICE_NOT_ACTIVE;
}
gpSDP->Lock();
if (gpSDP->eStage != Connected) {
IFDBG(DebugOut(DEBUG_ERROR,L"sdp_Connect_In: ERROR_SERVICE_NOT_ACTIVE\r\n"));
gpSDP->Unlock();
return ERROR_SERVICE_NOT_ACTIVE;
}
SDP_CONTEXT *pContext = VerifyContext((SDP_CONTEXT*) hDeviceContext);
if (!pContext || !pba) {
IFDBG(DebugOut(DEBUG_ERROR,L"sdp_Connect_In: ERROR_INVALID_PARAMETER\r\n"));
gpSDP->Unlock();
return ERROR_INVALID_PARAMETER;
}
Link *pLink = FindLink(pba,TRUE);
if (pLink) {
IFDBG(DebugOut(DEBUG_SDP_PACKETS,L"sdp_Connect_In: already connected\r\n"));
pLink->AddRef();
if (pLink->fStage == UP) {
NotifyConnect(pContext,pCallContext,ERROR_SUCCESS,pLink->cid);
gpSDP->Unlock();
return ERROR_SUCCESS;
}
// if link hasn't been established we alloc the call but don't try to fire up connection.
}
Call *pCall = AllocCall(CALL_SDP_CONNECT,pLink,pContext,pCallContext);
if (!pCall) {
IFDBG(DebugOut(DEBUG_ERROR,L"sdp_Connect_In: ERROR_OUTOFMEMORY\r\n"));
if (pLink)
pLink->DelRef();
gpSDP->Unlock();
return ERROR_OUTOFMEMORY;
}
int iRes = ERROR_SUCCESS;
if (!pLink) {
iRes = SdpCreateConnection(pCall,pba);
if (iRes != ERROR_SUCCESS) {
// Since we gave up CritSec in SdpCreateConnection need to make sure call is still around.
if (VerifyCall(pCall))
DeleteCall(pCall);
}
}
IFDBG(DebugOut(DEBUG_SDP_TRACE,L"sdp_Connect_In: iRes = 0x%08x\r\n",iRes));
gpSDP->Unlock();
return iRes;
}
static int sdp_Disconnect_In(HANDLE hDeviceContext, void *pCallContext, unsigned short cid) {
int iRes = ERROR_SUCCESS;
IFDBG(DebugOut(DEBUG_SDP_TRACE,L"sdp_Disconnect_In(0x%08x,0x%08x,0x%04x)\r\n",
hDeviceContext,pCallContext,cid));
if (! gpSDP) {
IFDBG(DebugOut(DEBUG_ERROR,L"sdp_Disconnect_In: ERROR_SERVICE_NOT_ACTIVE\r\n"));
return ERROR_SERVICE_NOT_ACTIVE;
}
gpSDP->Lock();
if (gpSDP->eStage != Connected) {
IFDBG(DebugOut(DEBUG_ERROR,L"sdp_Disconnect_In: ERROR_SERVICE_NOT_ACTIVE\r\n"));
gpSDP->Unlock();
return ERROR_SERVICE_NOT_ACTIVE;
}
SDP_CONTEXT *pOwner = VerifyContext((SDP_CONTEXT*) hDeviceContext);
Link *pLink = pOwner ? FindLink(cid) : NULL;
if (!pOwner || !pLink) {
IFDBG(DebugOut(DEBUG_ERROR,L"sdp_Disconnect_In: ERROR_INVALID_PARAMETER\r\n"));
gpSDP->Unlock();
return ERROR_INVALID_PARAMETER;
}
SVSUTIL_ASSERT(!pLink->fIncoming);
pLink->DelRef();
if (pLink->GetRefCount() > 0) {
IFDBG(DebugOut(DEBUG_SDP_PACKETS,L"sdp_Disconnect_In: cid 0x%04x has extra references\r\n",cid));
NotifyDisconnect(pOwner,pCallContext,ERROR_SUCCESS);
}
else {
IFDBG(DebugOut(DEBUG_SDP_PACKETS,L"sdp_Disconnect_In: cid 0x%04x has last ref removed, deleting\r\n",cid));
Call *pCall = AllocCall(CALL_SDP_DISCONNECT,NULL, pOwner, pCallContext);
// If are OOM we still do disconnect, but won't be able to call sdp_Disconnect_Out.
iRes = SdpDisconnect(pLink,pCall);
if (iRes != ERROR_SUCCESS && pCall && VerifyCall(pCall))
DeleteCall(pCall);
if (!pCall)
iRes = ERROR_OUTOFMEMORY;
}
IFDBG(DebugOut(DEBUG_SDP_TRACE,L"sdp_Disconnect_In: 0x%08x\r\n",iRes));
gpSDP->Unlock();
return iRes;
}
static int sdp_ServiceSearch_In(HANDLE hDeviceContext, void *pCallContext, unsigned short cid,
SdpQueryUuid* pUUIDs, unsigned short cMaxHandles) {
IFDBG(DebugOut(DEBUG_SDP_TRACE,L"sdp_ServiceSearch_In(0x%08x,0x%08x,0x%08x,%d)\r\n",
hDeviceContext,pCallContext,pUUIDs,cMaxHandles));
if (! gpSDP) {
IFDBG(DebugOut(DEBUG_ERROR,L"sdp_ServiceSearch_In: ERROR_SERVICE_NOT_ACTIVE\r\n"));
return ERROR_SERVICE_NOT_ACTIVE;
}
gpSDP->Lock();
if (gpSDP->eStage != Connected) {
IFDBG(DebugOut(DEBUG_ERROR,L"sdp_ServiceSearch_In: ERROR_SERVICE_NOT_ACTIVE\r\n"));
gpSDP->Unlock();
return ERROR_SERVICE_NOT_ACTIVE;
}
SDP_CONTEXT *pContext = VerifyContext((SDP_CONTEXT*) hDeviceContext);
Link *pLink = (pContext && cid) ? FindLink(cid) : NULL;
// for VerifyCall to be legit, as soon as we take down link we must invalidate the call (or use a flag to do this,
// let mem be freed by caller function). Also currently this allows calls to be queued even if not connected,
// need to make sure this case is handled both on connection and if connection fails.
if (!pContext || (cid && (!pLink || pLink->fStage != UP))) {
IFDBG(DebugOut(DEBUG_ERROR,L"sdp_ServiceSearch_In: ERROR_INVALID_PARAMETER\r\n"));
gpSDP->Unlock();
return ERROR_INVALID_PARAMETER;
}
Call *pCall = NULL;
SdpConnection *pSdpConn = NULL;
SdpServiceSearch searchInfo;
if (cid) {
pCall = AllocCall(CALL_SDP_SERVICE_SEARCH, pLink, pContext,pCallContext);
if (!pCall) {
IFDBG(DebugOut(DEBUG_ERROR,L"sdp_ServiceSearch_In: ERROR_OUTOFMEMORY\r\n"));
gpSDP->Unlock();
return ERROR_OUTOFMEMORY;
}
pSdpConn = AllocSdpConnection(pCall);
}
else {
pSdpConn = GetLocalSDPConn();
if (!pSdpConn) {
IFDBG(DebugOut(DEBUG_ERROR,L"sdp_ServiceSearch_In: ERROR_OUTOFMEMORY\r\n"));
gpSDP->Unlock();
return ERROR_OUTOFMEMORY;
}
}
searchInfo.uuids = pUUIDs;
searchInfo.cMaxHandles = cMaxHandles;
int iRes = SdpInterface::ServiceSearch(pSdpConn,&searchInfo,(cid == 0));
if (iRes == STATUS_PENDING) {
SVSUTIL_ASSERT(cid);
iRes = ERROR_SUCCESS;
}
if (!cid) {
unsigned short cReturnedHandles;
if (iRes == ERROR_SUCCESS)
cReturnedHandles = pSdpConn->u.Client.ServiceSearch.totalRecordCount;
else
cReturnedHandles = 0;
NotifyServiceSearch(pContext,pCallContext,iRes,cReturnedHandles,pSdpConn->pClientBuf);
ResetSdpConnection(pSdpConn);
}
else if (iRes != ERROR_SUCCESS) {
IFDBG(DebugOut(DEBUG_ERROR,L"sdp_ServiceSearch_In: SdpInterface::ServiceSearch fails, 0x%08x\r\n",iRes));
#if defined (DEBUG) || defined (_DEBUG)
pCall->pSdpConnection->fClientNotified = TRUE;
#endif
DeleteCall(pCall);
}
gpSDP->Unlock();
IFDBG(DebugOut(DEBUG_SDP_TRACE,L"sdp_ServiceSearch_In: 0x%08x\r\n",iRes));
return MapStatusToErrorCode(iRes);
}
static int sdp_AttributeSearch_In(HANDLE hDeviceContext, void *pCallContext, unsigned short cid, unsigned long recordHandle, SdpAttributeRange *pAttribRange, int numAttributes) {
IFDBG(DebugOut(DEBUG_SDP_TRACE,L"sdp_AttributeSearch_In(0x%08x,0x%08x,0x%08x,0x%08x,0x%04x,0x%08x,%d )\r\n",
hDeviceContext,pCallContext,recordHandle,cid,pAttribRange,numAttributes));
if (! gpSDP) {
IFDBG(DebugOut(DEBUG_ERROR,L"sdp_AttributeSearch_In: ERROR_SERVICE_NOT_ACTIVE\r\n"));
return ERROR_SERVICE_NOT_ACTIVE;
}
gpSDP->Lock();
if (gpSDP->eStage != Connected) {
IFDBG(DebugOut(DEBUG_ERROR,L"sdp_AttributeSearch_In: ERROR_SERVICE_NOT_ACTIVE\r\n"));
gpSDP->Unlock();
return ERROR_SERVICE_NOT_ACTIVE;
}
SDP_CONTEXT *pContext = VerifyContext((SDP_CONTEXT*) hDeviceContext);
Link *pLink = (pContext && cid) ? FindLink(cid) : NULL;
if (!pContext || (cid && (!pLink || pLink->fStage != UP))) {
IFDBG(DebugOut(DEBUG_ERROR,L"sdp_AttributeSearch_In: ERROR_INVALID_PARAMETER\r\n"));
gpSDP->Unlock();
return ERROR_INVALID_PARAMETER;
}
Call *pCall = NULL;
SdpConnection *pSdpConn = NULL;
SdpAttributeSearch searchInfo;
if (cid) {
pCall = AllocCall(CALL_SDP_ATTRIBUTE_SEARCH, pLink, pContext,pCallContext);
if (!pCall) {
IFDBG(DebugOut(DEBUG_ERROR,L"sdp_AttributeSearch_In: ERROR_OUTOFMEMORY\r\n"));
gpSDP->Unlock();
return ERROR_OUTOFMEMORY;
}
pSdpConn = AllocSdpConnection(pCall);
}
else {
pSdpConn = GetLocalSDPConn();
if (!pSdpConn) {
IFDBG(DebugOut(DEBUG_ERROR,L"sdp_AttributeSearch_In: ERROR_OUTOFMEMORY\r\n"));
gpSDP->Unlock();
return ERROR_OUTOFMEMORY;
}
}
searchInfo.range = pAttribRange;
searchInfo.numAttrib
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -