bool AiaStoreAlert()

in ports/Storage/src/aia_storage_config.c [201:308]


bool AiaStoreAlert( const char* alertToken, size_t alertTokenLen,
                    AiaTimepointSeconds_t scheduledTime,
                    AiaDurationMs_t duration, uint8_t alertType )
{
    if( !alertToken )
    {
        AiaLogError( "Null alertToken" );
        return false;
    }
    if( alertTokenLen != AIA_ALERT_TOKEN_CHARS )
    {
        AiaLogError( "Invalid alert token length" );
        return false;
    }

    size_t allAlertsBytes = AiaGetAlertsSize();
    size_t alertsBytesWithNewAlert =
        allAlertsBytes + AIA_SIZE_OF_ALERT_IN_BYTES;
    size_t startingOffset = allAlertsBytes;
    size_t bytePosition;
    bool updatingExistingAlert = false;

    /**
     * Load all alerts from persistent storage. Allocated additional space
     * for a new alert though in case the token we are trying to insert does
     * not exist in persistent storage yet.
     */
    uint8_t* allAlertsBuffer = AiaCalloc( 1, alertsBytesWithNewAlert );
    if( !allAlertsBuffer )
    {
        AiaLogError( "AiaCalloc failed, bytes=%zu.", alertsBytesWithNewAlert );
        return false;
    }

    if( !AiaLoadAlerts( allAlertsBuffer, allAlertsBytes ) )
    {
        AiaLogError( "AiaLoadBlob failed" );
        AiaFree( allAlertsBuffer );
        return false;
    }

    /** Go through the tokens to find the first empty or matching one */
    for( bytePosition = 0; bytePosition < alertsBytesWithNewAlert;
         bytePosition += AIA_SIZE_OF_ALERT_IN_BYTES )
    {
        startingOffset = bytePosition;
        if( '\0' == allAlertsBuffer[ bytePosition ] )
        {
            /** Found an empty token */
            break;
        }
        else
        {
            /** Check if this token matches with what we are trying to insert */
            if( !strncmp( (const char*)allAlertsBuffer + bytePosition,
                          alertToken, alertTokenLen ) )
            {
                updatingExistingAlert = true;
                break;
            }
        }
    }

    /* Check if we have reached the alerts storage limit */
    if( startingOffset == alertsBytesWithNewAlert )
    {
        AiaLogError(
            "AiaStoreAlert failed: Maximum number of local alerts to store "
            "reached." );
        AiaFree( allAlertsBuffer );
        return false;
    }

    /** Write the new alert token */
    uint8_t* newAlertOffset = allAlertsBuffer + startingOffset;
    memcpy( newAlertOffset, alertToken, alertTokenLen );

    /** Write the other fields: scheduledTime, duration, alertType */
    bytePosition = alertTokenLen;
    for( size_t i = 0; i < sizeof( AiaTimepointSeconds_t );
         ++i, bytePosition++ )
    {
        newAlertOffset[ bytePosition ] = ( scheduledTime >> ( i * 8 ) );
    }
    for( size_t i = 0; i < sizeof( AiaDurationMs_t ); ++i, bytePosition++ )
    {
        newAlertOffset[ bytePosition ] = ( duration >> ( i * 8 ) );
    }
    for( size_t i = 0; i < sizeof( uint8_t ); ++i, bytePosition++ )
    {
        newAlertOffset[ bytePosition ] = ( alertType >> ( i * 8 ) );
    }

    /** Store the new blob in persistent storage */
    size_t storeSize =
        ( updatingExistingAlert ? allAlertsBytes : alertsBytesWithNewAlert );
    /** Store the new blob in persistent storage */
    if( !AiaStoreBlob( AIA_ALL_ALERTS_STORAGE_KEY_V0, allAlertsBuffer,
                       storeSize ) )
    {
        AiaLogError( "AiaStoreBlob failed" );
        AiaFree( allAlertsBuffer );
        return false;
    }

    AiaFree( allAlertsBuffer );
    return true;
}