// ----------------------------------------------------------------------------
// CWmDrmDlaDefaultHttpManager::Stop
// This method should be used instead of Cancel.
// ----------------------------------------------------------------------------
void CWmDrmDlaDefaultHttpManager::Stop()
    {
    LOGFN( "CWmDrmDlaDefaultHttpManager::Stop" );
    // Make sure Stop was not called from a callback
    ASSERT( !iInCallback );

    if ( IsActive() )
        {
        // We are still establishing the connection, cancel the active object
        Cancel();
        }
    else
        {
        // The active object is not active - we are past the setup phase
        if ( iTransactionOpen )
            {
            iHttpTransaction.Cancel();

            // Only generate the callback if there was a transaction going on,
            // otherwise the client will get a callback without previously
            // calling StartL
            HandleDownloadComplete( KErrCancel );
            }
        }
	// Close the HTTP session in use
    iHttpSession.Close();

    CleanupConnection();
    DeleteUsernamePassword();
    iState = EConstructed;
    }
// ----------------------------------------------------------------------------
// CWmDrmDlaDefaultHttpManager::CleanupTransaction
// ----------------------------------------------------------------------------
void CWmDrmDlaDefaultHttpManager::CleanupTransaction()
    {
    LOGFN( "CWmDrmDlaDefaultHttpManager::CleanupTransaction" );
    if ( iBody )
        {
        iBody->ReleaseData();
        iBody = NULL;
        }

    // Release HTTP transaction & session resources
    delete iSrcAddress;
    iSrcAddress = NULL;

    TInt nofheaders = iHdrValues.Count();
    for ( TInt i = 0; i < nofheaders; i++ )
        {
        delete iHdrValues[i];
        }

    // set to empty
    iHdrValues.Reset();
    iHdrFields.Reset();

    iHttpTransaction.Close();

    if ( !iKeepAlive )
        {
        CleanupConnection();
        iState = ESubmit == iState ? EConstructed : iState;
        }
    else if ( ESubmit == iState )
        {
        // end of a transaction
        iState = EOpen;
        }
    else
        {
        // do nothing. This is to get rid of a PC-Lint warning
        }

    iTransactionOpen = EFalse;
    }
// ----------------------------------------------------------------------------
// CWmDrmDlaDefaultHttpManager::DoStartL
// ----------------------------------------------------------------------------
void CWmDrmDlaDefaultHttpManager::DoStartL(
    const TDesC8& aUrl,
    const RArray<CWmDrmDlaDefaultHttpManager::THeader>& aHeaders )
    {
    LOGFN( "CWmDrmDlaDefaultHttpManager::DoStartL" );
    CleanupTransaction();

    // Store callers URL
    iSrcAddress = aUrl.AllocL();

    // Store headers
    TInt nofheaders = aHeaders.Count();
    for ( TInt i = 0; i < nofheaders; i++ )
        {
        iHdrFields.AppendL( aHeaders[i].iField );
        iHdrValues.AppendL( aHeaders[i].iVal.AllocL() );
        }

    if ( (iState == EOpen) && iKeepAlive )
        {
        TConnectionInfo connectionInfo;
        TRAPD(err, GetConnectionInfoL(connectionInfo) );
        if ( err || ( connectionInfo.iIapId != iIapNumber &&
             iIapNumber != 0 && connectionInfo.iIapId != 0 ) )
            {
            CleanupConnection();
            iState = EStart;
            }
        }
    else
        {
        iState = EConstructed == iState ? EStart : EOpen;
        }

    iError = KErrNone;
    iCredentialsOk = ETrue;

    CompleteSelf();
    }
Exemplo n.º 4
0
DWORD
CNdasEventPublisher::OnTaskStart()
{
	_ASSERTE(NULL != m_hSemQueue && "Don't forget to call initialize().");

	// Queue Semaphore, Terminating Thread, Pipe Instances(MAX...)
	HANDLE hWaitHandles[2 + MAX_NDAS_EVENT_PIPE_INSTANCES];
	hWaitHandles[0] = m_hTaskTerminateEvent;
	hWaitHandles[1] = m_hSemQueue;

	//
	// initial pipe instance
	//
	m_PipeData.clear();
	BOOL fSuccess = AcceptNewConnection();
	if (!fSuccess) {
		DPErrorEx(_T("Creating a first pipe instance failed: "));
		return -1;
	}

	BOOL bTerminate(FALSE);

	while (FALSE == bTerminate) {

		DWORD dwWaitHandles = 2 + m_PipeData.size();
		for (DWORD i = 0; i < m_PipeData.size(); ++i) {
			hWaitHandles[i + 2] = m_PipeData[i]->overlapped.hEvent;
		}

		DWORD dwWaitResult = ::WaitForMultipleObjects(
			dwWaitHandles,
			hWaitHandles,
			FALSE,
			m_dwPeriod);


		if (dwWaitResult == WAIT_OBJECT_0) 
		{
			//
			// Terminate Thread
			//
			bTerminate = TRUE;
		} 
		else if (dwWaitResult == WAIT_OBJECT_0 + 1) 
		{
			//
			// Event Message is queued
			//
			while (TRUE) {
				m_queueLock.Lock();
				bool bEmpty = m_EventMessageQueue.empty();
				if (bEmpty) {
					m_queueLock.Unlock();
					break;
				}
				NDAS_EVENT_MESSAGE message = m_EventMessageQueue.front();
				m_EventMessageQueue.pop();
				m_queueLock.Unlock();
				Publish(&message);
			}

		} 
		else if (dwWaitResult >= WAIT_OBJECT_0 + 2 && 
			dwWaitResult < WAIT_OBJECT_0 + 2 + m_PipeData.size())
		{
			DWORD dwPipe = dwWaitResult - WAIT_OBJECT_0 - 2;

			DPInfo(_FT("Event Client %d\n"), dwPipe);

			CLIENT_DATA* pCurClientData = m_PipeData[dwPipe];

			DPInfo(_FT("Connected: %d\n"), pCurClientData->bConnected);

			fSuccess = ::ResetEvent(pCurClientData->overlapped.hEvent);
			_ASSERT(fSuccess);

			if (!pCurClientData->bConnected) {
				
				//
				// create another instance
				//
				fSuccess = AcceptNewConnection();
				if (!fSuccess) {
					DPWarningEx(_FT("Creating another pipe instance failed: "));
					DPWarning(_FT("No more event subscribers can be accepted.\n"));
				}

				// AcceptNewConnection will invalidate pCurClientData;

				pCurClientData = m_PipeData.at(dwPipe);

				//
				// Accepting connection
				//
				pCurClientData->bConnected = TRUE;
				fSuccess = ::ResetEvent(pCurClientData->overlapped.hEvent);
				_ASSERT(fSuccess);
				
				//
				// Send a version event for connected client
				//
				fSuccess = SendVersionInfo(
					pCurClientData->hPipe, 
					&pCurClientData->overlapped);

				//
				// Any failure will disconnect the client
				//
				if (!fSuccess && ERROR_IO_PENDING != ::GetLastError()) {
					ClientDataVector::iterator itr = m_PipeData.begin();
					CleanupConnection(pCurClientData);
					while (itr != m_PipeData.end()) {
						if ((CLIENT_DATA*)*itr == pCurClientData) {
							m_PipeData.erase(itr);
							break;
						}
						++itr;
					}
					DPInfo(_FT("Accepted removed event subscriber.\n"));
				} else {
					DPInfo(_FT("Accepted new event subscriber.\n"));
				}

			} else {
			}
			// ignore other status
		} else if (WAIT_TIMEOUT == dwWaitResult) {
			NDAS_EVENT_MESSAGE msg = {0};
			msg.EventType = NDAS_EVENT_TYPE_PERIODIC;
			Publish(&msg);
		} else 
		{
			//
			// Error
			//
		}

	}

	//
	// TODO: Add cleanup
	//
	DWORD nPipeData = m_PipeData.size();
	ClientDataVector::iterator itr = m_PipeData.begin();
	while (itr != m_PipeData.end()) {
		CleanupConnection(*itr);
		++itr;
	}
	m_PipeData.clear();

	_tprintf(TEXT("Terminating Publisher Thread...\n"));
	return 0;
}
Exemplo n.º 5
0
void 
CNdasEventPublisher::Publish(const PNDAS_EVENT_MESSAGE pMessage)
{
	DPInfo(_FT("Publishing Event: %s\n"), 
		NdasEventTypeString(pMessage->EventType));

	//
	// sent the message to the connected pipes
	//
	for (ClientDataVector::iterator itr = m_PipeData.begin(); 
		itr != m_PipeData.end();) 
		//
		// do not forward the iterator here when erasing some 
		// elements 
		// itr2 = v.erase(itr); 
		// itr2 has a forwarded iterator from itr
		//
	{
		CLIENT_DATA* pClientData = *itr;
		if (pClientData->bConnected) {

			DWORD cbWritten;

			BOOL fSuccess = ::WriteFile(
				pClientData->hPipe,
				pMessage,
				sizeof(NDAS_EVENT_MESSAGE),
				&cbWritten,
				&pClientData->overlapped);

			if (!fSuccess && ERROR_IO_PENDING != ::GetLastError()) {
				
				DPErrorEx(_FT("Writing to a pipe failed: "));
				DPInfo(_FT("Detaching an event subscriber.\n"));
				
				CleanupConnection(pClientData);
				//
				// erasing an element will automatically
				// forward the vector 
				// (actually, itr remains the same, but the itr is
				// a next elemen)
				itr = m_PipeData.erase(itr);

				//
				// create another instance
				//
				fSuccess = AcceptNewConnection();
				if (!fSuccess) {
					DPWarningEx(_FT("Creating another pipe instance failed: "));
					DPWarning(_FT("No more event subscribers can be accepted.\n"));
				}

			} else {
				//
				// forward the iterator if we did erase
				//
				DPInfo(_FT("Event written to a pipe %p.\n"), (*itr)->hPipe);
				++itr;
			}
		} else {
			//
			// forward the iterator if not connected
			//
			++itr;
		}
	}	
}