📄 obmain.cxx
字号:
memset (pServ, 0, sizeof(*pServ));
//if the serviceID = 0
//load up the client dll by the serviceid
if (! pServ->Load (iLen, (unsigned char *)serviceid)) {
pServ->Unload ();
svsutil_FreeFixed (pServ, pfmdServers);
IFDBG(svslog_DebugOut (VERBOSE_OUTPUT_PACKETS, L"[OBEX] GlobalData::ServiceRequest: packet 0x%08x fails with SERVICEUNAVAIL (no server)\n", pConn->uiCurrentTransaction));
SendTrivialResponse (pConn, OBEX_STAT_SERVICEUNAVAIL | OBEX_OP_ISFINAL);
SVSUTIL_ASSERT (! IsLocked ());
return;
}
pServ->pNext = pservList;
pservList = pServ;
}
SVSUTIL_ASSERT (pServ);
if (pServ->CanUseConnection (pConn))
{
//NOTE: the transaction ID *MUST* be set by DispatchCall
// in this one special case (where CID is INVALID!)
pServ->DispatchCall (OBEX_INVALID_CID, pConn, &p);
}
else {
IFDBG(svslog_DebugOut (VERBOSE_OUTPUT_PACKETS, L"[OBEX] GlobalData::ServiceRequest: packet 0x%08x fails with SERVICEUNAVAIL (server won't serve)\n", pConn->uiCurrentTransaction));
SendTrivialResponse (pConn, OBEX_STAT_SERVICEUNAVAIL | OBEX_OP_ISFINAL);
}
IFDBG(svslog_DebugOut (VERBOSE_OUTPUT_PACKETS, L"[OBEX] -GlobalData::ServiceRequest\n"));
SVSUTIL_ASSERT (! IsLocked ());
}
DWORD WINAPI GlobalData::Compact (LPVOID pVoid) {
IFDBG(svslog_DebugOut (VERBOSE_OUTPUT_MAINTAIN, L"GlobalData::Compact - entered\n"));
if (! gpState)
return 0;
gpState->Lock ();
if (gpState->fState != RUNNING) {
gpState->Unlock ();
return 0;
}
//
// Compaction pass on all structures.
//
// Close long inactive connections.
int tickNow = GetTickCount ();
if (gpState->uiOBEX_CONNECTION_TIMEOUT) {
for ( ; ; ) {
int fResume = FALSE;
Connection *pConn = gpState->pconnList;
while (pConn) {
if ((! pConn->uiCurrentTransaction) &&
(tickNow - pConn->tickLastActive > (int)gpState->uiOBEX_CONNECTION_TIMEOUT)) {
IFDBG(svslog_DebugOut (VERBOSE_OUTPUT_MAINTAIN, L"[OBEX] GlobalData::Compact: retiring connection %d\n", pConn->s));
gpState->CloseConnection (pConn);
if (gpState->fState != RUNNING) {
gpState->Unlock ();
return 0;
}
fResume = TRUE;
break;
}
pConn = pConn->pNext;
}
if (! fResume)
break;
}
}
for ( ; ; ) {
int fResume = FALSE;
Server *pParent = NULL;
Server *pServ = gpState->pservList;
while (pServ) {
if ((! pServ->iCallRef) &&
(tickNow - pServ->tickLastActive > (int)gpState->uiOBEX_SERVER_TIMEOUT)) {
Association *pA = gpState->passocList;
while (pA) {
if (pA->pServer == pServ)
break;
pA = pA->pNext;
}
if (! pA) {
IFDBG(svslog_DebugOut (VERBOSE_OUTPUT_MAINTAIN, L"[OBEX] GlobalData::Compact: retiring server %s\n", pServ->szName));
if (pParent)
pParent->pNext = pServ->pNext;
else
gpState->pservList = gpState->pservList->pNext;
pServ->pNext = NULL;
pServ->Unload ();
if (gpState->fState != RUNNING) {
gpState->Unlock ();
return 0;
}
svsutil_FreeFixed (pServ, gpState->pfmdServers);
fResume = TRUE;
break;
}
}
pParent = pServ;
pServ = pServ->pNext;
}
if (! fResume)
break;
}
if ((! gpState->pconnList) && (! gpState->pservList)) {
gpState->fMaintain = FALSE; // just exit... or
IFDBG(svslog_DebugOut (VERBOSE_OUTPUT_MAINTAIN, L"[OBEX] GlobalData::Compact - exited\n"));
} else { // schedule forward...
gpState->pThreads->ScheduleEvent (Compact, NULL, gpState->uiOBEX_MAINT_PERIOD);
IFDBG(svslog_DebugOut (VERBOSE_OUTPUT_MAINTAIN, L"[OBEX] GlobalData::Compact - rescheduled\n"));
}
gpState->Unlock();
return 0;
}
int GlobalData::SendTrivialResponse (Connection *pConn, int iResponse) {
IFDBG(svslog_DebugOut (VERBOSE_OUTPUT_PACKETS, L"[OBEX] GlobalData::SendTrivialResponse - response 0x%02x\n", iResponse));
SVSUTIL_ASSERT (pConn->uiCurrentTransaction);
SVSUTIL_ASSERT (pConn->pBuffer);
SVSUTIL_ASSERT (pConn->cBufSize >= 3);
SVSUTIL_ASSERT (pConn->cFilled == pConn->cBufSize);
SOCKET s = pConn->s;
pConn->uiCurrentTransaction = 0; // We are responding...
pConn->cBufSize = pConn->cFilled = 0;
obex_Free (pConn->pBuffer);
pConn->pBuffer = NULL;
gpState->Unlock ();
char x[3];
x[0] = (char)iResponse; // Response
x[1] = 0; // Length
x[2] = 3;
IFDBG(svslog_DumpBuff (VERBOSE_OUTPUT_PACKETS, (unsigned char *)x, 3));
return send(s, x, 3, 0);
}
HRESULT GlobalData::CloseConnection (Connection *pConn) {
IFDBG(svslog_DebugOut (VERBOSE_OUTPUT_PROTOCOL, L"[OBEX] GlobalData::CloseConnection\n"));
SVSUTIL_ASSERT (gpState->IsLocked ());
// Free resources
closesocket (pConn->s);
pConn->s = INVALID_SOCKET;
if (pConn->pBuffer)
obex_Free (pConn->pBuffer);
pConn->pBuffer = NULL;
pConn->cFilled = 0;
pConn->cBufSize = 0;
pConn->cPeekFilled = 0;
//
// Take it out of the list
//
Connection *pParent = NULL;
Connection *pRun = pconnList;
while (pRun) {
if (pConn == pRun)
break;
pParent = pRun;
pRun = pRun->pNext;
}
if (! pRun) {
SVSUTIL_ASSERT (0);
return E_FAIL;
}
if (! pParent)
pconnList = pconnList->pNext;
else
pParent->pNext = pRun->pNext;
// Clean up associations, notify servers
for ( ; ; ) {
Association *pAssocParent = NULL;
Association *pA = passocList;
while (pA) {
if (pA->pConn == pConn) {
IFDBG(svslog_DebugOut (VERBOSE_OUTPUT_PROTOCOL, L"[OBEX] GlobalData::CloseConnection : closing association to %s\n", pA->pServer->szName));
if (! pAssocParent)
passocList = passocList->pNext;
else
pAssocParent->pNext = pA->pNext;
Server *pServ = pA->pServer;
unsigned int uiCId = pA->uiConnectionId;
svsutil_FreeFixed (pA, pfmdAssociations);
pA->uiTransactionId = pConn->uiCurrentTransaction;
pServ->DispatchCall (uiCId, NULL, NULL);
SVSUTIL_ASSERT (! gpState->IsLocked());
gpState->Lock ();
break;
}
pAssocParent = pA;
pA = pA->pNext;
}
if (! pA)
break;
}
svsutil_FreeFixed (pConn, gpState->pfmdConnections);
IFDBG(svslog_DebugOut (VERBOSE_OUTPUT_PROTOCOL, L"[OBEX] -GlobalData::CloseConnection\n"));
return S_OK;
}
void GlobalData::SetMaintain(void) {
if (! fMaintain) {
IFDBG(svslog_DebugOut (VERBOSE_OUTPUT_MAINTAIN, L"[OBEX] GlobalData::SetMaintain :: scheduling maintenance\n"));
fMaintain = TRUE;
pThreads->ScheduleEvent (Compact, NULL, uiOBEX_MAINT_PERIOD);
}
}
#define SOCKET_CREATION_ATTEMPTS 20
#ifndef SDK_BUILD
//
// AddressFamily
//
int AddressFamily::Start (int af, int iPort) {
IFDBG(svslog_DebugOut (VERBOSE_OUTPUT_MAINTAIN, L"[OBEX] GlobalData::Start :: TCP/IP\n"));
SVSUTIL_ASSERT (gpState->IsLocked ());
SOCKET sl;
ADDRINFO aiHints, *aiAddrInfo, *AI;
char portBuffer[21];
int i;
_itoa(iPort, portBuffer, 10);
memset(&aiHints, 0, sizeof(aiHints));
aiHints.ai_family = af;
aiHints.ai_socktype = SOCK_STREAM;
aiHints.ai_flags = AI_NUMERICHOST | AI_PASSIVE;
BOOL fGotValidBinding = FALSE;
//use getaddrinfo for fetching addrinfo
if(0 != getaddrinfo(NULL,portBuffer,&aiHints, &aiAddrInfo))
{
IFDBG(svslog_DebugOut (VERBOSE_OUTPUT_ERRORS, L"[OBEX] AddressFamily::error with getaddrinfo! (%d)\n", WSAGetLastError()));
return FALSE;
}
for (i = 0, AI = aiAddrInfo; AI != NULL; AI = AI->ai_next, i++)
{
// Highly unlikely, but check anyway.
if (i == FD_SETSIZE) {
IFDBG(svslog_DebugOut (VERBOSE_OUTPUT_ERRORS, L"[OBEX] Too many addresses given\n"));
break;
}
// Make sure we're not beyond the OBEX_MAXPORTS
if(cSockets >= OBEX_MAXPORTS) {
ASSERT(FALSE);
IFDBG(svslog_DebugOut (VERBOSE_OUTPUT_ERRORS, L"[OBEX] Too many address Families\n"));
break;
}
// we only support PF_INET and PF_INET6 here
if ((AI->ai_family != PF_INET) && (AI->ai_family != PF_INET6))
continue;
// Open a socket with the correct address family for this address.
sl = aSocket[cSockets] = socket(AI->ai_family, AI->ai_socktype, AI->ai_protocol);
if (sl == INVALID_SOCKET){
IFDBG(svslog_DebugOut (VERBOSE_OUTPUT_ERRORS, L"[OBEX] Too many addresses given\n"));
continue;
}
//bind the socket
if (bind (sl, AI->ai_addr, AI->ai_addrlen))
{
IFDBG(svslog_DebugOut (VERBOSE_OUTPUT_ERRORS, L"[OBEX] AddressFamily::Start: bind failed (ecode=%d)!\n", WSAGetLastError()));
closesocket (sl);
continue;
}
if (listen (sl, 5)) {
IFDBG(svslog_DebugOut (VERBOSE_OUTPUT_ERRORS, L"[OBEX] AddressFamily::Start::Listen failed (ecode=%d)!\n", WSAGetLastError()));
closesocket (sl);
continue;
}
if (! hThread)
hThread = CreateThread (NULL, 0, ThreadListen, (void *)this, 0, NULL);
if (! hThread)
{
IFDBG(svslog_DebugOut (VERBOSE_OUTPUT_ERRORS, L"[OBEX] AddressFamily::Start failed to create thread (error=0x%08x (%d))\n", GetLastError(), GetLastError ()));
closesocket (sl);
continue;
}
SVSUTIL_ASSERT (cSockets < OBEX_MAXPORTS);
addFam[cSockets] = AI->ai_family;
PREFAST_SUPPRESS(394, "this is checked at the beginning of the for loop to make sure < OBEX_MAXPORT")
++cSockets;
fGotValidBinding = TRUE;
IFDBG(svslog_DebugOut (VERBOSE_OUTPUT_INIT, L"[OBEX] AddressFamily::Start - successfully started af %d port %d\n", af, iPort));
}
freeaddrinfo(aiAddrInfo);
return fGotValidBinding;
}
#endif
int AddressFamily::Start (int af) {
IFDBG(svslog_DebugOut (VERBOSE_OUTPUT_MAINTAIN, L"[OBEX] GlobalData::Start :: Bluetooth\n"));
SVSUTIL_ASSERT (gpState->IsLocked ());
SVSUTIL_ASSERT (cSockets < OBEX_MAXPORTS);
addFam[cSockets] = af;
SOCKET sl;
for(int i=0; i < SOCKET_CREATION_ATTEMPTS; i++) {
sl = aSocket[cSockets] = socket (af, SOCK_STREAM, BTHPROTO_RFCOMM);
if(sl != INVALID_SOCKET)
break;
else {
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -