void CJavaDebugAgentDriver::ClientDisconnected(CTcpServerHandler* aHandler)
{
    TInt handlerPos = iHandlers.Find(aHandler);
    if (handlerPos >= 0) {
        TInetAddr remote;
        RSocket* socket = aHandler->Socket();
        socket->LocalName(remote);

        // Delete a matching KeepAlive object. It doesn't matter which one.
        // Ideally we shouldn't create more than one KeepAlive per address
        // but we normally have no more than one client, so it's doesn't
        // really matter.
        for (TInt i = 0; i<iKeepAliveList.Count(); i++)
        {
            if (remote.Match(iKeepAliveList[i]->Address()))
            {
                delete iKeepAliveList[i];
                iKeepAliveList.Remove(i);
                break;
            }
        }

        // It's not obvious how we can recover from the situation when
        // we can't this handler to iDeadHandlers array. It's not safe
        // to delete the handler here because this callback is invoked 
        // by the handler, and it may access its this pointer after this
        // callback has returned. It that case, let's leave it in iHandlers
        // array. It screws things up but at least we don't leak memory.
        // Hopefully, this won't happen too often...
        if (iDeadHandlers.Append(aHandler) == KErrNone)
        {
            iHandlers.Remove(handlerPos);
            if (iHandlers.Count() == 0) {
                // It was our last client
                SetState(iServer ? EListening : EDisconnected);
            }
            // Schedule callback on a clean stack where we can safely
            // delete the handler
            iAsyncCleanup->CallBack();
        }
    }
    
    //Dima: Cleanup on start in InitL conflicts with installation
    //seemingly due to errors in Installer (ECOM framework panics
    //on loading midp2installerplugin.dll on installation after cleanup)
    //so we clean up on client disconnect.
    if (IsAutoCleanEnabled())
    {
        Log(_L("Cleaning up old data..."));
        iEngine->Cleanup();
        Log(_L("Done cleaning..."));
    }
}
// Notifications from CTcpServerHandler
void CJavaDebugAgentDriver::ClientConnected(CTcpServerHandler* aHandler)
{
    if (iHandlers.Append(aHandler) == KErrNone)
    {
        if (iKeepAlivePeriod > 0)
        {
            TInetAddr local;
            TInetAddr remote;
            aHandler->Socket()->LocalName(local);
            aHandler->Socket()->RemoteName(remote);

            // No ping for local connections (as in case of debugging over
            // Bluetooth)
            if (!local.Match(remote))
            {
                TRAPD(err, InitKeepAliveL(&remote));
                if (err == KErrNone)
                {
                    iLog->Log(_S("Starting keep-alive timer"));
                }
                else
                {
                    // Ignore the error, it shoudn't be fatal
                    iLog->LogFormat(_S("Keep-alive error %d"),err);
                }
            }
        }

        if (iHandlers.Count() == 1) 
        {
            // First client
            SetState(EConnected);
        }
    }
    else
    {
        // This connection will work but we will leak some memory.
        // Suggest the user to restart the application
        iLog->Log(_S("Internal error. Please restart debug agent."));
    }
}
Esempio n. 3
0
//-- compares 2 IP addresses, for array search.
TBool IPAddrIsEqual(const TInetAddr& aFirst, const TInetAddr& aSecond)
    {
    return aFirst.Match(aSecond);
    }