//=============================================================================
//  rRwLock API
//=============================================================================
rRwLock
    rRwLock_create
    (

    )
{
    _rRwLock* lock;

    lock = rpal_memory_alloc( sizeof( *lock ) );

    if( rpal_memory_isValid( lock ) )
    {
        lock->evtCanRead = rEvent_create( TRUE );
        lock->evtCanWrite = rEvent_create( TRUE );
        lock->stateLock = rMutex_create();
        lock->readCount = 0;

        if( !rpal_memory_isValid( lock->evtCanRead ) ||
            !rpal_memory_isValid( lock->evtCanWrite ) ||
            !rpal_memory_isValid( lock->stateLock ) )
        {
            rEvent_free( lock->evtCanRead );
            rEvent_free( lock->evtCanWrite );
            rMutex_free( lock->stateLock );
            rpal_memory_free( lock );
            lock = NULL;
        }
        else
        {
            rEvent_set( lock->evtCanRead );
        }
    }

    return (rRwLock)lock;
}
Ejemplo n.º 2
0
static RVOID
    shutdownCollectors
    (

    )
{
    RU32 i = 0;

    if( !rEvent_wait( g_hbs_state.isTimeToStop, 0 ) )
    {
        rpal_debug_info( "signaling to collectors to stop." );
        rEvent_set( g_hbs_state.isTimeToStop );

        if( NULL != g_hbs_state.hThreadPool )
        {
            rpal_debug_info( "destroying collector thread pool." );
            rThreadPool_destroy( g_hbs_state.hThreadPool, TRUE );
            g_hbs_state.hThreadPool = NULL;

            for( i = 0; i < ARRAY_N_ELEM( g_collectors ); i++ )
            {
                if( g_collectors[ i ].isEnabled )
                {
                    rpal_debug_info( "cleaning up collector %d.", i );
                    g_collectors[ i ].cleanup( &g_hbs_state, g_collectors[ i ].conf );
                    rSequence_free( g_collectors[ i ].conf );
                    g_collectors[ i ].conf = NULL;
                }
            }
        }
    }
}
RBOOL
    rRwLock_read_unlock
    (
        rRwLock lock
    )
{
    RBOOL isSuccess = FALSE;
    _rRwLock* lck = (_rRwLock*)lock;

    if( rpal_memory_isValid( lock ) )
    {
        if( rMutex_lock( lck->stateLock ) )
        {
            lck->readCount--;

            if( 0 == lck->readCount )
            {
                rEvent_set( lck->evtCanWrite );
            }

            rMutex_unlock( lck->stateLock );

            isSuccess = TRUE;
        }
    }

    return isSuccess;
}
Ejemplo n.º 4
0
BOOL
    ctrlHandler
    (
        DWORD type
    )
{
    BOOL isHandled = FALSE;

    static RU32 isHasBeenSignaled = 0;
    
    UNREFERENCED_PARAMETER( type );

    if( 0 == rInterlocked_set32( &isHasBeenSignaled, 1 ) )
    {
        // We handle all events the same way, cleanly exit
    
        rpal_debug_info( "terminating rpHCP." );
        rpHostCommonPlatformLib_stop();
    
        rEvent_set( g_timeToQuit );
    
        isHandled = TRUE;
    }

    return isHandled;
}
Ejemplo n.º 5
0
RBOOL
    stopAllModules
    (

    )
{
    RBOOL isSuccess = TRUE;

    RU32 moduleIndex = 0;

    for( moduleIndex = 0; moduleIndex < RP_HCP_CONTEXT_MAX_MODULES; moduleIndex++ )
    {
        rpal_debug_info( "stopping module at %d", moduleIndex );

        if( 0 != g_hcpContext.modules[ moduleIndex ].hThread )
        {
            if( rEvent_set( g_hcpContext.modules[ moduleIndex ].isTimeToStop ) &&
                rpal_thread_wait( g_hcpContext.modules[ moduleIndex ].hThread, RP_HCP_CONTEXT_MODULE_TIMEOUT ) )
            {
                _cleanupModuleEntry( &( g_hcpContext.modules[ moduleIndex ] ) );

                rpal_debug_info( "finished stopping module." );
            }
            else
            {
                isSuccess = FALSE;
            }
        }
    }

    rpal_debug_info( "finished stopping all modules" );

    return isSuccess;
}
Ejemplo n.º 6
0
RBOOL
    rpHostCommonPlatformLib_unload
    (
        RU8 moduleId
    )
{
    RBOOL isSuccess = FALSE;

    RU32 moduleIndex = 0;

    for( moduleIndex = 0; moduleIndex < RP_HCP_CONTEXT_MAX_MODULES; moduleIndex++ )
    {
        if( moduleId == g_hcpContext.modules[ moduleIndex ].id )
        {
            if( rEvent_set( g_hcpContext.modules[ moduleIndex ].isTimeToStop ) &&
                rpal_thread_wait( g_hcpContext.modules[ moduleIndex ].hThread, (30*1000) ) )
            {
                isSuccess = TRUE;
#ifdef RPAL_PLATFORM_WINDOWS
                FreeLibrary( (HMODULE)g_hcpContext.modules[ moduleIndex ].hModule );
#elif defined( RPAL_PLATFORM_LINUX ) || defined( RPAL_PLATFORM_MACOSX )
                dlclose( g_hcpContext.modules[ moduleIndex ].hModule );
#endif
                rEvent_free( g_hcpContext.modules[ moduleIndex ].context.isTimeToStop );
                rpal_thread_free( g_hcpContext.modules[ moduleIndex ].hThread );
            }

            break;
        }
    }

    return isSuccess;
}
Ejemplo n.º 7
0
RBOOL
    stopBeacons
    (

    )
{
    RBOOL isSuccess = FALSE;

    if( NULL != g_hcpContext.isBeaconTimeToStop )
    {
        rEvent_set( g_hcpContext.isBeaconTimeToStop );

        if( 0 != g_hcpContext.hBeaconThread )
        {
            rpal_thread_wait( g_hcpContext.hBeaconThread, MSEC_FROM_SEC( 40 ) );
            rpal_thread_free( g_hcpContext.hBeaconThread );

            isSuccess = TRUE;
        }

        rEvent_free( g_hcpContext.isBeaconTimeToStop );
        g_hcpContext.isBeaconTimeToStop = NULL;
    }

    return isSuccess;
}
Ejemplo n.º 8
0
RPRIVATE_TESTABLE
RBOOL 
    unloadModule
    (
        rpHCPContext* hcpContext,
        rSequence seq
    )
{
    RBOOL isSuccess = FALSE;

    RpHcp_ModuleId moduleId = (RU8)(-1);
    RU32 moduleIndex = (RU32)(-1);

    if( NULL != seq &&
        NULL != hcpContext )
    {
        if( rSequence_getRU8( seq, 
                              RP_TAGS_HCP_MODULE_ID, 
                              &moduleId ) )
        {
            for( moduleIndex = 0; moduleIndex < RP_HCP_CONTEXT_MAX_MODULES; moduleIndex++ )
            {
                if( moduleId == hcpContext->modules[ moduleIndex ].id )
                {
                    break;
                }
            }
        }
    }

    if( (RU32)(-1) != moduleIndex &&
        RP_HCP_CONTEXT_MAX_MODULES != moduleIndex )
    {
#ifdef RP_HCP_LOCAL_LOAD
        if( hcpContext->modules[ moduleIndex ].isOsLoaded )
        {
            // We do not unload modules loaded by the OS in debug since
            // they are used to debug modules during development.
            return FALSE;
        }
#endif
        if( rEvent_set( hcpContext->modules[ moduleIndex ].isTimeToStop ) &&
            rpal_thread_wait( hcpContext->modules[ moduleIndex ].hThread, ( 30 * 1000 ) ) )
        {
            isSuccess = TRUE;

            _cleanupModuleEntry( &( hcpContext->modules[ moduleIndex ] ) );
        }
    }

    return isSuccess;
}
Ejemplo n.º 9
0
void
    ctrlHandler
    (
        int sigNum
    )
{
    static RU32 isHasBeenSignaled = 0;
    
    if( 0 == rInterlocked_set32( &isHasBeenSignaled, 1 ) )
    {
        rpal_debug_info( "terminating rpHCP." );
        rpHostCommonPlatformLib_stop();
        rEvent_set( g_timeToQuit );
    }
}
RBOOL
    rRwLock_write_unlock
    (
        rRwLock lock
    )
{
    RBOOL isSuccess = FALSE;
    _rRwLock* lck = (_rRwLock*)lock;

    if( rpal_memory_isValid( lock ) )
    {
        rEvent_set( lck->evtCanRead );
        rMutex_unlock( lck->stateLock );
        isSuccess = TRUE;
    }

    return isSuccess;
}
Ejemplo n.º 11
0
static
VOID WINAPI 
    SvcCtrlHandler
    (
        DWORD fdwControl
    )
{
    switch( fdwControl )
    {
        case SERVICE_CONTROL_STOP:
        case SERVICE_CONTROL_SHUTDOWN:

            if( g_svc_status.dwCurrentState != SERVICE_RUNNING )
                break;

            /*
            * Perform tasks necessary to stop the service here
            */

            g_svc_status.dwControlsAccepted = 0;
            g_svc_status.dwCurrentState = SERVICE_STOP_PENDING;
            g_svc_status.dwWin32ExitCode = 0;
            g_svc_status.dwCheckPoint = 2;

            SetServiceStatus( g_svc_status_handle, &g_svc_status );

            rpal_debug_info( "terminating rpHCP." );
            rpHostCommonPlatformLib_stop();

            rEvent_set( g_timeToQuit );

            break;

        default:
            break;
    }
}
Ejemplo n.º 12
0
//=============================================================================
//  Entry Point
//=============================================================================
RU32
RPAL_THREAD_FUNC
    RpHcpI_mainThread
    (
        rEvent isTimeToStop
    )
{
    RU32 ret = 0;

    RU64 nextBeaconTime = 0;

    rList cloudMessages = NULL;
    rSequence msg = NULL;
    rList newConfigurations = NULL;
    rList newNotifications = NULL;
    RPU8 newConfigurationHash = NULL;
    RU32 newHashSize = 0;
    rSequence staticConfig = NULL;
    RU8* tmpBuffer = NULL;
    RU32 tmpSize = 0;

    FORCE_LINK_THAT( HCP_IFACE );

    CryptoLib_init();

    getPrivileges();

    // This is the event for the collectors, it is different than the
    // hbs proper event so that we can restart the collectors without
    // signaling hbs as a whole.
    if( NULL == ( g_hbs_state.isTimeToStop = rEvent_create( TRUE ) ) )
    {
        return (RU32)-1;
    }

    // By default, no collectors are running
    rEvent_set( g_hbs_state.isTimeToStop );

    // We attempt to load some initial config from the serialized
    // rSequence that can be patched in this binary.
    if( NULL != ( staticConfig = getStaticConfig() ) )
    {
        if( rSequence_getBUFFER( staticConfig, RP_TAGS_HBS_ROOT_PUBLIC_KEY, &tmpBuffer, &tmpSize ) )
        {
            hbs_cloud_pub_key = rpal_memory_duplicate( tmpBuffer, tmpSize );
            if( NULL == hbs_cloud_pub_key )
            {
                hbs_cloud_pub_key = hbs_cloud_default_pub_key;
            }
            rpal_debug_info( "loading hbs root public key from static config" );
        }

        if( rSequence_getRU32( staticConfig, RP_TAGS_MAX_QUEUE_SIZE, &g_hbs_state.maxQueueNum ) )
        {
            rpal_debug_info( "loading max queue size from static config" );
        }
        else
        {
            g_hbs_state.maxQueueNum = HBS_EXFIL_QUEUE_MAX_NUM;
        }

        if( rSequence_getRU32( staticConfig, RP_TAGS_MAX_SIZE, &g_hbs_state.maxQueueSize ) )
        {
            rpal_debug_info( "loading max queue num from static config" );
        }
        else
        {
            g_hbs_state.maxQueueSize = HBS_EXFIL_QUEUE_MAX_SIZE;
        }

        rSequence_free( staticConfig );
    }
    else
    {
        hbs_cloud_pub_key = hbs_cloud_default_pub_key;
        g_hbs_state.maxQueueNum = HBS_EXFIL_QUEUE_MAX_NUM;
        g_hbs_state.maxQueueSize = HBS_EXFIL_QUEUE_MAX_SIZE;
    }

    if( !rQueue_create( &g_hbs_state.outQueue, freeExfilEvent, g_hbs_state.maxQueueNum ) )
    {
        rEvent_free( g_hbs_state.isTimeToStop );
        return (RU32)-1;
    }

    // We simply enqueue a message to let the cloud know we're starting
    sendStartupEvent();

    while( !rEvent_wait( isTimeToStop, (RU32)nextBeaconTime ) )
    {
        nextBeaconTime = MSEC_FROM_SEC( HBS_DEFAULT_BEACON_TIMEOUT + 
                         ( rpal_rand() % HBS_DEFAULT_BEACON_TIMEOUT_FUZZ ) );

        if( NULL != ( cloudMessages = beaconHome() ) )
        {
            while( rList_getSEQUENCE( cloudMessages, RP_TAGS_MESSAGE, &msg ) )
            {
                // Cloud message indicating next requested beacon time, as a Seconds delta
                if( rSequence_getTIMEDELTA( msg, RP_TAGS_TIMEDELTA, &nextBeaconTime ) )
                {
                    nextBeaconTime = MSEC_FROM_SEC( nextBeaconTime );
                    rpal_debug_info( "received set_next_beacon" );
                }

                if( NULL == newConfigurations &&
                    rSequence_getLIST( msg, RP_TAGS_HBS_CONFIGURATIONS, &newConfigurations ) )
                {
                    rpal_debug_info( "received a new profile" );

                    if( rSequence_getBUFFER( msg, RP_TAGS_HASH, &newConfigurationHash, &newHashSize ) &&
                        newHashSize == CRYPTOLIB_HASH_SIZE )
                    {
                        newConfigurations = rList_duplicate( newConfigurations );
                        rpal_memory_memcpy( &( g_hbs_state.currentConfigHash ), 
                                            newConfigurationHash, 
                                            CRYPTOLIB_HASH_SIZE );
                        g_hbs_state.isProfilePresent = TRUE;
                    }
                    else
                    {
                        newConfigurations = NULL;
                        rpal_debug_error( "profile hash received is invalid" );
                    }
                }

                if( NULL == newNotifications &&
                    rSequence_getLIST( msg, RP_TAGS_HBS_CLOUD_NOTIFICATIONS, &newNotifications ) )
                {
                    rpal_debug_info( "received cloud events" );
                    newNotifications = rList_duplicate( newNotifications );
                }
            }

            rList_free( cloudMessages );
        }

        // If this is the initial boot and we have no profile yet, we'll load a dummy
        // blank profile and use our defaults.
        if( NULL == newConfigurations &&
            !g_hbs_state.isProfilePresent &&
            !rEvent_wait( isTimeToStop, 0 ) )
        {
            newConfigurations = rList_new( RP_TAGS_HCP_MODULES, RPCM_SEQUENCE );
            rpal_debug_info( "setting empty profile" );
        }

        if( NULL != newConfigurations )
        {
            // We try to be as responsive as possible when asked to quit
            // so if we happen to have received the signal during a beacon
            // we will action the quit instead of the config change.
            if( !rEvent_wait( isTimeToStop, 0 ) )
            {
                rpal_debug_info( "begining sensor update on new profile" );
                shutdownCollectors();

                updateCollectorConfigs( newConfigurations );
                rList_free( newConfigurations );
                newConfigurations = NULL;

                startCollectors();
            }
            else
            {
                rList_free( newConfigurations );
            }

            newConfigurations = NULL;
        }

        if( NULL != newNotifications )
        {
            if( !rEvent_wait( isTimeToStop, 0 ) )
            {
                publishCloudNotifications( newNotifications );
            }

            rList_free( newNotifications );

            newNotifications = NULL;
        }
    }

    // We issue one last beacon indicating we are stopping
    sendShutdownEvent();

    // Shutdown everything
    shutdownCollectors();

    // Cleanup the last few resources
    rEvent_free( g_hbs_state.isTimeToStop );
    rQueue_free( g_hbs_state.outQueue );

    CryptoLib_deinit();

    if( hbs_cloud_default_pub_key != hbs_cloud_pub_key &&
        NULL != hbs_cloud_pub_key )
    {
        rpal_memory_free( hbs_cloud_pub_key );
        hbs_cloud_pub_key = NULL;
    }

    return ret;
}