// ----------------------------------------------------------------------------------
// CSSYChannel::GetPropertyL()
// ----------------------------------------------------------------------------------
//  
void CSSYChannel::GetPropertyL( const TSensrvChannelId aChannelId,
                                    TSensrvProperty& aProperty )
    {
    SSY_TRACE_IN();
    SSY_TRACE( EExtended, "ORIENTATIONSSY:ChannelId %d", iChannelInfo.iChannelId ); 

    if ( ChannelId() != aChannelId )
        {
        SSY_TRACE( EError, "ORIENTATIONSSY:ERROR: GetPropertyL wrong channelId!" );
        User::Leave( KErrArgument );
        }
    
    // try first common sensor properties
    TInt ret = iSensorProperties->GetProperty( aProperty );

    if ( ret != KErrNone )
        {
        // then try the channel properties
        ret = iChannelProperties->GetProperty( aProperty );
        }

    if ( ret != KErrNone )
        {
        SSY_TRACE( EError, "ORIENTATIONSSY:ERROR: Property is not supported: 0x%x ", aProperty.GetPropertyId() );
        User::Leave( KErrNotSupported );
        }

    SSY_TRACE_OUT();
    }
/**
 * HandlePropertyChange is called from backend, to indicate a change in property
 */
void CMagnetometerSensorSym::HandlePropertyChange(CSensrvChannel &/*aChannel*/, const TSensrvProperty &aChangedProperty)
    {
    if(aChangedProperty.GetPropertyId() != KSensrvPropCalibrationLevel)
        {
        // Do nothing, if calibration property has not changed
        return;
        }
    TInt calibrationlevel;
    aChangedProperty.GetValue(calibrationlevel);
    // As Qt requires calibration level in qreal but symbian provides in enum
    // It has been agreed with DS Team that the following mechanism will be
    // used till discussions with qt mobility are complete
    iCalibrationLevel = (1.0/3.0) * calibrationlevel;
    }
void CMagnetometer::PropertyChanged(CSensrvChannel& aChannel, const TSensrvProperty& aChangedProperty)
{
    TSensrvChannelInfo info = aChannel.GetChannelInfo();

    if (info.iChannelType == KSensrvChannelTypeIdMagnetometerXYZAxisData &&
            aChangedProperty.GetPropertyId() == KSensrvPropCalibrationLevel)
    {
        TInt calibration = 0;
        aChangedProperty.GetValue(calibration);

        iCalibration = calibration == 0? ENone :
                       calibration == 1? ELow :
                       calibration == 2? EModerate :
                       calibration == 3? EHigh : ENone;
    }
}
// ---------------------------------------------------------------------------
// CSsyReferencePropertyProvider::GetPropertyL
// ---------------------------------------------------------------------------
//
void CSsyReferencePropertyProvider::GetPropertyL( 
    const TSensrvChannelId aChannelId,
    TSensrvProperty& aProperty )
    {
    COMPONENT_TRACE( ( _L( "SSY Reference Plugin - CSsyReferencePropertyProvider::GetPropertyL()" ) ) );
    
    if ( iChannel.ChannelId() != aChannelId && aChannelId != 0 )
        {
        User::Leave( KErrArgument );
        }
    else
        {
        // Search property. Leaves with KErrNotFound if property is not found
        aProperty = iChannel.FindPropertyL( 
                        aProperty.GetPropertyId(), 
                        aProperty.PropertyItemIndex(),
                        aProperty.GetArrayIndex() );
        }

    COMPONENT_TRACE( ( _L( "SSY Reference Plugin - CSsyReferencePropertyProvider::GetPropertyL() - return" ) ) );
    }
// ---------------------------------------------------------------------------
// CSsyReferenceControl::FindPropertyL
// ---------------------------------------------------------------------------
//
void CSsyReferenceControl::FindPropertyL( 
    const TSensrvPropertyId aPropertyId, 
    const TInt aArrayIndex,
    TSensrvProperty& aProperty )
    {
    COMPONENT_TRACE( ( _L( "SSY Reference Plugin - CSsyReferenceControl::FindPropertyL()" ) ) );
    TSensrvProperty* property = NULL;
    TBool propertyFound( EFalse );

    // Search property
    for ( TInt i = 0; i < iProperties.Count() && !propertyFound; i++ )
        {
        property = static_cast<TSensrvProperty*>( &iProperties[i] );

        // Compare property IDs
        if ( property->GetPropertyId() == aPropertyId )
            {
            // Correct property ID is found, now check is it array type of property.
            // Either array indexes must match or propertys array index has to be array info
            if ( ( property->GetArrayIndex() == aArrayIndex ) || 
                 ( ( property->GetArrayIndex() == ESensrvArrayPropertyInfo ) && 
                   ( ESensrvSingleProperty == aArrayIndex ) ) )
                {
                // Correct array index found
                propertyFound = ETrue;    
                }
            }
        }

    // Leave if not found
    if ( !propertyFound )
        {
        User::Leave( KErrNotFound );
        }

    aProperty = *property;

    COMPONENT_TRACE( ( _L( "SSY Reference Plugin - CSsyReferenceControl::FindPropertyL() - return" ) ) );
    }
// ----------------------------------------------------------------------------------
// CSSYChannel::CheckPropertyDependenciesL()
// ----------------------------------------------------------------------------------
//    
void CSSYChannel::CheckPropertyDependenciesL( const TSensrvChannelId aChannelId, 
                                              const TSensrvProperty& aProperty,
                                              RSensrvChannelList& aAffectedChannels  )
    {
    SSY_TRACE_IN();
    SSY_TRACE( EExtended, "ORIENTATIONSSY:ChannelId %d", iChannelInfo.iChannelId ); 

    if ( ChannelId() != aChannelId )
        {
        SSY_TRACE( EError, "ORIENTATIONSSY:ERROR: CheckPropertyDependenciesL wrong channelId!" );
        User::Leave( KErrArgument );
        }

    CSSYProperty* propertyPtr = iSensorProperties;
    TSensrvProperty property = aProperty;

    // try first common sensor properties
    TInt ret = iSensorProperties->GetProperty( property );

    if ( ret != KErrNone )
        {
        propertyPtr = iChannelProperties;

        // then try the channel properties
        ret = iChannelProperties->GetProperty( property );        
        }    

    if ( ret != KErrNone )
        {
        SSY_TRACE( EError, "ORIENTATIONSSY:ERROR: Property is not supported: 0x%x ", aProperty.GetPropertyId() );
        User::Leave( KErrNotFound );
        }

    propertyPtr->GetAffectedChannels( aAffectedChannels );

    SSY_TRACE_OUT();
    }
// ---------------------------------------------------------------------------
// Adds property to the end of the queue
// ---------------------------------------------------------------------------
//
TInt CSensrvPropertyQueue::Append( const TSensrvProperty& aProperty )
    {
    COMPONENT_TRACE( ( _L( "Sensor Server - CSensrvPropertyQueue::Append(Property ID:%d)" ), aProperty.GetPropertyId() ) );

    TInt err(KErrNone);

    // Allocate linkable transaction pointer in same heap as queue
    TLinkablePropertyPtr* newPtr = reinterpret_cast<TLinkablePropertyPtr*>(iHeap->Alloc(sizeof(TLinkablePropertyPtr)));
    
    if (newPtr)
        {
        Mem::Copy(&(newPtr->iProperty), &aProperty, sizeof(TSensrvProperty));
        iPropertyPtrList.AddLast(*newPtr);                
        }
    else
        {
        ERROR_TRACE( ( _L( "Sensor Server - CCSensrvPropertyQueue::Append - ERROR: No memory to add item" ) ) );
        err = KErrNoMemory;
        }

    COMPONENT_TRACE( ( _L( "Sensor Server - CSensrvPropertyQueue::Append - return %d" ), err ) );
    
    return err;
    }
// ----------------------------------------------------------------------------------
// CSSYChannel::SetPropertyL()
// ----------------------------------------------------------------------------------
//    
void CSSYChannel::SetPropertyL( const TSensrvChannelId aChannelId,
                                    const TSensrvProperty& aProperty )
    {
    SSY_TRACE_IN();
    SSY_TRACE( EExtended, "ORIENTATIONSSY:ChannelId %d", iChannelInfo.iChannelId ); 

    if ( ChannelId() != aChannelId )
        {
        SSY_TRACE( EError, "ORIENTATIONSSY:ERROR: SetPropertyL wrong channelId!" );
        User::Leave( KErrArgument );
        }

    TBool valueChanged( ETrue );
    RSensrvChannelList affectedChannels;
    TInt valueInt( 0 );

    // try first common sensor properties
    TInt ret = iSensorProperties->SetProperty( aProperty, affectedChannels );

    if ( ret == KErrNotFound )
        {
        // then try the channel properties
        ret = iChannelProperties->SetProperty( aProperty, affectedChannels );        
        }

    if ( ret != KErrNone && ret != KErrAlreadyExists )
        {
        SSY_TRACE( EError, "ORIENTATIONSSY:ERROR: Property is not supported or it's readonly: 0x%x ", aProperty.GetPropertyId() );
        User::Leave( KErrNotSupported );
        }

    if ( ret == KErrAlreadyExists )
        {
        // client tried to set the same value that the property already has, lets just return without doing anything
        // but informing the "change" via the callback
        valueChanged = EFalse;
        }

    // do something if the value was really changed
    if ( valueChanged )
        {
        aProperty.GetValue( valueInt );

        // These are ReadOnly values, cannot change these
        if ( ( aProperty.GetPropertyId() == KSensrvPropIdDataRate ) ||  
             ( aProperty.GetPropertyId() == KSensrvPropIdAvailability ) ||   
             ( aProperty.GetPropertyId() == KSensrvPropIdMeasureRange ) || 
             ( aProperty.GetPropertyId() == KSensrvPropIdChannelDataFormat ) || 
             ( aProperty.GetPropertyId() == KSensrvPropIdChannelAccuracy ) )
            {
            SSY_TRACE( EError, "ORIENTATIONSSY:ERROR: Setting the property is not supported: 0x%x ", aProperty.GetPropertyId() );
            User::Leave( KErrNotSupported );
            }
        }

    // we call the callback function to inform that property was changed, even if it was not actually changed
    iCallback->PropertyChanged( iChannelInfo.iChannelId, affectedChannels, aProperty );

    affectedChannels.Reset();

    SSY_TRACE_OUT();
    }