TSensrvPropertyType CSensorBackendSym::propertyType(TSensrvPropertyId aPropertyId, TInt &errId)
    {
    TSensrvProperty propertyType;
    //Getting the property to check the type
    TRAPD(err, iBackendData.iSensorChannel->GetPropertyL(aPropertyId, ESensrvSingleProperty, propertyType));
    if(err != KErrNone)
        {
        errId = err;
        }
    //Find the type of property
    return propertyType.PropertyType();
    }
/**
 * Second phase constructor
 * Initialize the backend resources
 */
void CAccelerometerSensorSym::ConstructL()
{
    //Initialize the backend resources
    InitializeL();

    TInt err;
    TSensrvProperty unitProperty;
    TRAP(err, iBackendData.iSensorChannel->GetPropertyL(KSensrvPropIdChannelUnit, ESensrvSingleProperty, unitProperty));
    if(err == KErrNone)
    {
        unitProperty.GetValue(iUnit);
    }
}
/**
 * Overriding this method in rotation sensor to hard code value of 
 * mesurement range from -180 to 180 as Qt wants
 * Symbian provides measurement range from 0 to 359
 */
void CRotationSensorSym::GetMeasurementrangeAndAccuracy()
    {
    TReal accuracy = 0;
    TSensrvProperty accuracyProperty;
    TRAPD(err, iBackendData.iSensorChannel->GetPropertyL(KSensrvPropIdChannelAccuracy, ESensrvSingleProperty, accuracyProperty));
    if(err == KErrNone)
        {
        accuracyProperty.GetValue(accuracy);
        }
    // Hard coding values -180 and 180 as Qt expects y and z axis
    // values range from -180 to 180.
    addOutputRange(KMinimumRange, KMaximumRange, accuracy);
    }
/**
 * 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;
    }
// ----------------------------------------------------------------------------------
// 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();
    }
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" ) ) );
    }
void CMagnetometer::ConstructL()
{
    CSensrvChannelFinder* sensorChannelFinder = CSensrvChannelFinder::NewLC();

    RSensrvChannelInfoList channelInfoList;
    CleanupClosePushL(channelInfoList);

    TSensrvChannelInfo mySearchConditions;
    mySearchConditions.iChannelType = KSensrvChannelTypeIdMagnetometerXYZAxisData;

    sensorChannelFinder->FindChannelsL(channelInfoList, mySearchConditions);

    TSensrvChannelInfo channelInfo;

    if (channelInfoList.Count() > 0)
        channelInfo = channelInfoList[0];
    else
        User::Leave(KErrNotFound);

    CleanupStack::PopAndDestroy(&channelInfoList);
    CleanupStack::PopAndDestroy(sensorChannelFinder);

    iSensorChannel = CSensrvChannel::NewL(channelInfo);
    iSensorChannel->OpenChannelL();

    // Get current calibration value
    TSensrvProperty property;
    iSensorChannel->GetPropertyL(KSensrvPropCalibrationLevel, KSensrvItemIndexNone, property);
    TInt calibration = 0;
    property.GetValue(calibration);

    iCalibration = calibration == 0? ENone :
                   calibration == 1? ELow :
                   calibration == 2? EModerate :
                   calibration == 3? EHigh : ENone;

    iSensorChannel->SetPropertyListenerL(this);
}
// ----------------------------------------------------------------------------------
// 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();
    }
TInt CSensorBackendSym::SetProperty(TSensrvPropertyId aPropertyId, TSensrvPropertyType aPropertyType, TSensrvArrayIndex aArrayIndex, TReal aValue)
    {
    //Creating property object
    TSensrvProperty prop;   
    //Set property Id
    prop.SetPropertyId(aPropertyId);
    //Set Index of property
    prop.SetItemIndex(-1);
    //Set value depending on type of property
    if(aPropertyType == ESensrvRealProperty)
        {
        prop.SetValue(aValue);
        }
    else if(aPropertyType == ESensrvIntProperty)
        {
        prop.SetValue((TInt)aValue);
        }
    //Set array Index
    prop.SetArrayIndex(aArrayIndex);
    //Setting the property
    return iBackendData.iSensorChannel->SetProperty(prop);
    }
// ---------------------------------------------------------------------------
// 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;
    }
void CAccelerometerSensorSym::start()
{
    TSensrvProperty dataFormatProperty;
    TInt err;
    CSensorBackendSym::start();
    TRAP(err, iBackendData.iSensorChannel->GetPropertyL(KSensrvPropIdChannelDataFormat, ESensrvSingleProperty, dataFormatProperty));
    if(err == KErrNone)
    {
        TSensrvProperty scaleRangeProperty;
        TRAP(err, iBackendData.iSensorChannel->GetPropertyL(KSensrvPropIdScaledRange, KSensrvItemIndexNone, scaleRangeProperty));
        if(err == KErrNone)
        {
            if(scaleRangeProperty.GetArrayIndex() == ESensrvSingleProperty)
            {
                if(scaleRangeProperty.PropertyType() == ESensrvIntProperty)
                {
                    scaleRangeProperty.GetMaxValue(iScaleRange);
                }
                else if(scaleRangeProperty.PropertyType() == ESensrvRealProperty)
                {
                    TReal realScale;
                    scaleRangeProperty.GetMaxValue(realScale);
                    iScaleRange = realScale;
                }
            }
            else if(scaleRangeProperty.GetArrayIndex() == ESensrvArrayPropertyInfo)
            {
                TInt index;
                if(scaleRangeProperty.PropertyType() == ESensrvIntProperty)
                {
                    scaleRangeProperty.GetValue(index);
                }
                else if(scaleRangeProperty.PropertyType() == ESensrvRealProperty)
                {
                    TReal realIndex;
                    scaleRangeProperty.GetValue(realIndex);
                    index = realIndex;
                }
                TRAP(err, iBackendData.iSensorChannel->GetPropertyL(KSensrvPropIdScaledRange, KSensrvItemIndexNone, index, scaleRangeProperty));
                if(err == KErrNone)
                {
                    if(scaleRangeProperty.PropertyType() == ESensrvIntProperty)
                    {
                        scaleRangeProperty.GetMaxValue(iScaleRange);
                    }
                    else if(scaleRangeProperty.PropertyType() == ESensrvRealProperty)
                    {
                        TReal realScaleRange;
                        scaleRangeProperty.GetMaxValue(realScaleRange);
                        iScaleRange = realScaleRange;
                    }
                }
            }
        }
    }
}
// ----------------------------------------------------------------------------------
// 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();
    }
/**
 * start is overridden to allow retrieving initial calibration property before
 * and to set the required value type flags
 */
void CMagnetometerSensorSym::start()
    {
    if(sensor())
        {
        // Initialize the values
        iReading.setX(0);
        iReading.setY(0);
        iReading.setZ(0);
        // Set the required type of values
        QVariant v = sensor()->property("returnGeoValues");
        iReturnGeoValues = (v.isValid() && v.toBool()); // if the property isn't set it's false
        }
    TInt err;
    // get current property value for calibration and set it to reading
    TSensrvProperty calibration;
    TRAP(err, iBackendData.iSensorChannel->GetPropertyL(KSensrvPropCalibrationLevel, ESensrvSingleProperty, calibration));
    // If error in getting the calibration level, continue to start the sensor
    // as it is not a fatal error
    if ( err == KErrNone )
        {
        TInt calibrationVal;
        calibration.GetValue(calibrationVal);
        iCalibrationLevel = calibrationVal * (1.0/3.0);
        }
    // Call backend start
    CSensorBackendSym::start();


    TSensrvProperty dataFormatProperty;
    TRAP(err, iBackendData.iSensorChannel->GetPropertyL(KSensrvPropIdChannelDataFormat, ESensrvSingleProperty, dataFormatProperty));
    if(err == KErrNone)
        {
        TInt dataFormat;
        dataFormatProperty.GetValue(dataFormat);
        if(dataFormat == ESensrvChannelDataFormatScaled)
            {
            TSensrvProperty scaleRangeProperty;
            TRAP(err, iBackendData.iSensorChannel->GetPropertyL(KSensrvPropIdScaledRange, KSensrvItemIndexNone, scaleRangeProperty));
            if(err == KErrNone)
                {
                if(scaleRangeProperty.GetArrayIndex() == ESensrvSingleProperty)
                    {
                    if(scaleRangeProperty.PropertyType() == ESensrvIntProperty)
                        {
                        scaleRangeProperty.GetMaxValue(iScaleRange);
                        }
                    else if(scaleRangeProperty.PropertyType() == ESensrvRealProperty)
                        {
                        TReal realScale;
                        scaleRangeProperty.GetMaxValue(realScale);
                        iScaleRange = realScale;
                        }
                    }
                else if(scaleRangeProperty.GetArrayIndex() == ESensrvArrayPropertyInfo)
                    {
                    TInt index;
                    if(scaleRangeProperty.PropertyType() == ESensrvIntProperty)
                        {
                        scaleRangeProperty.GetValue(index);
                        }
                    else if(scaleRangeProperty.PropertyType() == ESensrvRealProperty)
                        {
                        TReal realIndex;
                        scaleRangeProperty.GetValue(realIndex);
                        index = realIndex;
                        }
                    TRAP(err, iBackendData.iSensorChannel->GetPropertyL(KSensrvPropIdScaledRange, KSensrvItemIndexNone, index, scaleRangeProperty));
                    if(err == KErrNone)
                        {
                        if(scaleRangeProperty.PropertyType() == ESensrvIntProperty)
                            {
                            scaleRangeProperty.GetMaxValue(iScaleRange);
                            }
                        else if(scaleRangeProperty.PropertyType() == ESensrvRealProperty)
                            {
                            TReal realScaleRange;
                            scaleRangeProperty.GetMaxValue(realScaleRange);
                            iScaleRange = realScaleRange;
                            }
                        }
                    }
                }
            }
        }
    }