ANSC_STATUS
BbhmDiagipStop
    (
        ANSC_HANDLE                 hThisObject
    )
{
    ANSC_STATUS                     returnStatus = ANSC_STATUS_SUCCESS;
    PBBHM_DIAG_IP_PING_OBJECT       pMyObject    = (PBBHM_DIAG_IP_PING_OBJECT     )hThisObject;
    PBBHM_IP_PING_PROPERTY          pProperty    = (PBBHM_IP_PING_PROPERTY        )&pMyObject->Property;
    PBBHM_IP_PING_TDO_OBJECT        pStateTimer  = (PBBHM_IP_PING_TDO_OBJECT      )pMyObject->hStateTimer;
    PBBHM_IP_PING_SINK_OBJECT       pSink        = (PBBHM_IP_PING_SINK_OBJECT     )pMyObject->hSinkObject;
    PANSC_XSOCKET_OBJECT            pSocket      = NULL;
    PDSLH_PING_INFO                 pDslhDiagInfo= (PDSLH_PING_INFO               )pMyObject->hDslhDiagInfo;
    PSINGLE_LINK_ENTRY              pSLinkEntry  = NULL;
    PBBHM_IP_PING_ECHO_ENTRY        pMEchoEntry  = NULL;
    SLIST_HEADER                    MiddleResult;
    ULONG                           i            = 0;
    ULONG                           MaxRetrieve  = 10;
    ULONG                           nRead        = 0;

    if ( pMyObject->bActive )
    {
        ULONG                       ulMin = 0;
        ULONG                       ulMax = 0;
        ULONG                       ulSum = 0;
        ULONG                       ulTime;

        pStateTimer->Stop((ANSC_HANDLE)pStateTimer);
        pStateTimer->SetStopTime((ANSC_HANDLE)pStateTimer, AnscGetTickInMilliSeconds());

        returnStatus =
            pMyObject->CalculateResult
                (
                    (ANSC_HANDLE)pMyObject
                );

        for (i = 0; i < MaxRetrieve; i++)
        {
            AnscAcquireLock(&pMyObject->MiddleResultLock);
            MiddleResult = pMyObject->MiddleResult;
            AnscReleaseLock(&pMyObject->MiddleResultLock);
            if (MiddleResult.Depth == 0)
            {
                break;
            }
            AnscSleep(100);
        }

        AnscAcquireLock(&pMyObject->MiddleResultLock);

        nRead = pMyObject->MiddleResult.Depth;
        pSLinkEntry = AnscSListPopEntry(&pMyObject->MiddleResult);
        while ( pSLinkEntry )
        {
            pMEchoEntry = (PBBHM_IP_PING_ECHO_ENTRY)ACCESS_BBHM_IP_PING_ECHO_ENTRY(pSLinkEntry);
            pSLinkEntry = AnscSListPopEntry(&pMyObject->MiddleResult);

            ulTime = pMEchoEntry->StopTime - pMEchoEntry->StartTime;

            /* calculate min, max, sum */
            if ( ulSum == 0 )
            {
                ulMin = ulMax = ulSum = ulTime;
            }
            else
            {
                if ( ulMin > ulTime )
                {
                    ulMin = ulTime;
                }

                if ( ulMax < ulTime )
                {
                    ulMax = ulTime;
                }

                ulSum += ulTime;
            }

            AnscFreeMemory(pMEchoEntry);
        }

        AnscReleaseLock(&pMyObject->MiddleResultLock);

        if ( nRead != 0 )
        {
            pProperty->AvgRTT   = ulSum/nRead;
            pProperty->MinRTT   = ulMin;
            pProperty->MaxRTT   = ulMax;
        }

        if ( pSink )
        {
            pSocket = (PANSC_XSOCKET_OBJECT             )pSink->GetXsocket((ANSC_HANDLE)pSink);
            pSocket->Close((ANSC_HANDLE)pSocket);
        }
    }

    switch ( pMyObject->GetStatus((ANSC_HANDLE)pMyObject) )
    {
        case  BBHM_IP_PING_STATUS_COMPLETE:

                pDslhDiagInfo->DiagnosticState = DSLH_DIAG_STATE_TYPE_Complete;

                break;

        case  BBHM_IP_PING_STATUS_ABORT:

                pDslhDiagInfo->DiagnosticState = DSLH_DIAG_STATE_TYPE_PING_Error_Internal;

                break;

        case  BBHM_IP_PING_STATUS_STOP:

                pDslhDiagInfo->DiagnosticState = DSLH_DIAG_STATE_TYPE_Complete;

                break;

        case  BBHM_IP_PING_STATUS_ERROR_HostName:

                pDslhDiagInfo->DiagnosticState = DSLH_DIAG_STATE_TYPE_Error_HostName;

                break;

        case  BBHM_IP_PING_STATUS_TIMEOUT:

                pMyObject->SetMaxRTT((ANSC_HANDLE)pMyObject, 0);
                pMyObject->SetMinRTT((ANSC_HANDLE)pMyObject, 0);
                pDslhDiagInfo->DiagnosticState = DSLH_DIAG_STATE_TYPE_Complete;

                break;

        default:

                return  returnStatus;
    }

    pMyObject->bResultQueryRunning     = FALSE;
    pDslhDiagInfo->SuccessCount        = nRead;
    pDslhDiagInfo->FailureCount        = pProperty->PktsSent - nRead;
    pDslhDiagInfo->AverageResponseTime = pProperty->AvgRTT;
    pDslhDiagInfo->MinimumResponseTime = pProperty->MinRTT;
    pDslhDiagInfo->MaximumResponseTime = pProperty->MaxRTT;

    return  returnStatus;
}