<commit_before>/*
 * #%L
 * %%
 * Copyright (C) 2011 - 2013 BMW Car IT GmbH
 * %%
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 * #L%
 */
#include "joynr/PrivateCopyAssign.h"
#include <gtest/gtest.h>
#include <gmock/gmock.h>
#include "tests/utils/MockObjects.h"
#include <QString>
#include "joynr/LibjoynrSettings.h"
#include "joynr/OnChangeWithKeepAliveSubscriptionQos.h"
#include "joynr/tests/TestLocationUpdateSelectiveBroadcastFilterParameters.h"

#include "joynr/types/GpsLocation.h"
#include "libjoynr/subscription/SubscriptionBroadcastListener.h"

using namespace ::testing;
using ::testing::InSequence;

using namespace joynr;
using namespace joynr::tests;

/**
  * Is an integration test. Tests from Provider -> PublicationManager
  */
class BroadcastPublicationTest : public ::testing::Test {
public:
    BroadcastPublicationTest() :
        gpsLocation1(1.1, 2.2, 3.3, types::GpsFixEnum::MODE2D, 0.0, 0.0, 0.0, 0.0, 444, 444, 444),
        speed1(100),
        providerParticipantId("providerParticipantId"),
        proxyParticipantId("proxyParticipantId"),
        subscriptionId("subscriptionId"),
        publicationManager(NULL),
        publicationSender(NULL),
        request(NULL),
        provider(new MockTestProvider),
        requestCaller(new testRequestCaller(provider)),
        filter1(new MockLocationUpdatedSelectiveFilter),
        filter2(new MockLocationUpdatedSelectiveFilter)
    {
    }

    void SetUp(){
        //remove stored subscriptions
        QFile::remove(LibjoynrSettings::DEFAULT_BROADCASTSUBSCRIPTIONREQUEST_STORAGE_FILENAME());
        publicationManager = new PublicationManager();
        subscriptionBroadcastListener =
                new SubscriptionBroadcastListener(subscriptionId, *publicationManager);
        publicationSender = new MockPublicationSender();
        request = new BroadcastSubscriptionRequest();

        request->setSubscribeToName("locationUpdateSelective");
        request->setSubscriptionId(subscriptionId);

        auto subscriptionQos =
                QSharedPointer<OnChangeSubscriptionQos>(new OnChangeWithKeepAliveSubscriptionQos(
                    80, // validity_ms
                    100, // minInterval_ms
                    200, // maxInterval_ms
                    80 // alertInterval_ms
        ));
        request->setQos(subscriptionQos);
        request->setFilterParameters(filterParameters);

        requestCaller->registerBroadcastListener(
                    "locationUpdateSelective",
                    subscriptionBroadcastListener);

        publicationManager->add(
                    proxyParticipantId,
                    providerParticipantId,
                    requestCaller,
                    request,
                    publicationSender);

        publicationManager->addBroadcastFilter(filter1);
        publicationManager->addBroadcastFilter(filter2);
    }

    void TearDown(){
        delete publicationSender;

        // The filter objects' destructors aren't executed at the end of the test, because gmock seems
        // to still hold a reference internally. This leads to gmock reporting an error about leaked
        // mock objects when leaving the scope of the test.
        // --> Delete the pointers manually.

        delete filter1.data();
        filter1.clear();

        delete filter2.data();
        filter2.clear();
    }

protected:
    types::GpsLocation gpsLocation1;
    double speed1;

    QString providerParticipantId;
    QString proxyParticipantId;
    QString subscriptionId;
    PublicationManager* publicationManager;
    MockPublicationSender* publicationSender;
    BroadcastSubscriptionRequest* request;
    SubscriptionBroadcastListener* subscriptionBroadcastListener;

    QSharedPointer<MockTestProvider> provider;
    QSharedPointer<RequestCaller> requestCaller;
    TestLocationUpdateSelectiveBroadcastFilterParameters filterParameters;
    QSharedPointer<MockLocationUpdatedSelectiveFilter> filter1;
    QSharedPointer<MockLocationUpdatedSelectiveFilter> filter2;

private:
    DISALLOW_COPY_AND_ASSIGN(BroadcastPublicationTest);
};

/**
  * Trigger:    An event occurs.
  * Expected:   The registered filter objects are called correctly.
  */
TEST_F(BroadcastPublicationTest, call_BroadcastFilterOnEventTriggered) {

    // It's only guaranteed that all filters are executed when they return true
    // (When not returning true, filter chain execution is interrupted)
    ON_CALL(*filter1, filter(Eq(gpsLocation1), Eq(filterParameters))).WillByDefault(Return(true));
    ON_CALL(*filter2, filter(Eq(gpsLocation1), Eq(filterParameters))).WillByDefault(Return(true));

    EXPECT_CALL(*filter1, filter(Eq(gpsLocation1), Eq(filterParameters)));
    EXPECT_CALL(*filter2, filter(Eq(gpsLocation1), Eq(filterParameters)));

    provider->locationUpdateSelectiveEventOccured(gpsLocation1);
}
<commit_msg>[cpp] Integration test: Publication is (not) sent when event triggered<commit_after>/*
 * #%L
 * %%
 * Copyright (C) 2011 - 2013 BMW Car IT GmbH
 * %%
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 * #L%
 */
#include "joynr/PrivateCopyAssign.h"
#include <gtest/gtest.h>
#include <gmock/gmock.h>
#include "tests/utils/MockObjects.h"
#include <QString>
#include "joynr/LibjoynrSettings.h"
#include "joynr/OnChangeWithKeepAliveSubscriptionQos.h"
#include "joynr/tests/TestLocationUpdateSelectiveBroadcastFilterParameters.h"

#include "joynr/types/GpsLocation.h"
#include "libjoynr/subscription/SubscriptionBroadcastListener.h"

using namespace ::testing;
using ::testing::InSequence;

using namespace joynr;
using namespace joynr::tests;

/**
  * Is an integration test. Tests from Provider -> PublicationManager
  */
class BroadcastPublicationTest : public ::testing::Test {
public:
    BroadcastPublicationTest() :
        gpsLocation1(1.1, 2.2, 3.3, types::GpsFixEnum::MODE2D, 0.0, 0.0, 0.0, 0.0, 444, 444, 444),
        speed1(100),
        providerParticipantId("providerParticipantId"),
        proxyParticipantId("proxyParticipantId"),
        subscriptionId("subscriptionId"),
        publicationManager(NULL),
        publicationSender(NULL),
        request(NULL),
        provider(new MockTestProvider),
        requestCaller(new testRequestCaller(provider)),
        filter1(new MockLocationUpdatedSelectiveFilter),
        filter2(new MockLocationUpdatedSelectiveFilter)
    {
    }

    void SetUp(){
        //remove stored subscriptions
        QFile::remove(LibjoynrSettings::DEFAULT_BROADCASTSUBSCRIPTIONREQUEST_STORAGE_FILENAME());
        publicationManager = new PublicationManager();
        subscriptionBroadcastListener =
                new SubscriptionBroadcastListener(subscriptionId, *publicationManager);
        publicationSender = new MockPublicationSender();
        request = new BroadcastSubscriptionRequest();

        request->setSubscribeToName("locationUpdateSelective");
        request->setSubscriptionId(subscriptionId);

        auto subscriptionQos =
                QSharedPointer<OnChangeSubscriptionQos>(new OnChangeWithKeepAliveSubscriptionQos(
                    80, // validity_ms
                    100, // minInterval_ms
                    200, // maxInterval_ms
                    80 // alertInterval_ms
        ));
        request->setQos(subscriptionQos);
        request->setFilterParameters(filterParameters);

        requestCaller->registerBroadcastListener(
                    "locationUpdateSelective",
                    subscriptionBroadcastListener);

        publicationManager->add(
                    proxyParticipantId,
                    providerParticipantId,
                    requestCaller,
                    request,
                    publicationSender);

        publicationManager->addBroadcastFilter(filter1);
        publicationManager->addBroadcastFilter(filter2);
    }

    void TearDown(){
        delete publicationSender;

        // The filter objects' destructors aren't executed at the end of the test, because gmock seems
        // to still hold a reference internally. This leads to gmock reporting an error about leaked
        // mock objects when leaving the scope of the test.
        // --> Delete the pointers manually.

        delete filter1.data();
        filter1.clear();

        delete filter2.data();
        filter2.clear();
    }

protected:
    types::GpsLocation gpsLocation1;
    double speed1;

    QString providerParticipantId;
    QString proxyParticipantId;
    QString subscriptionId;
    PublicationManager* publicationManager;
    MockPublicationSender* publicationSender;
    BroadcastSubscriptionRequest* request;
    SubscriptionBroadcastListener* subscriptionBroadcastListener;

    QSharedPointer<MockTestProvider> provider;
    QSharedPointer<RequestCaller> requestCaller;
    TestLocationUpdateSelectiveBroadcastFilterParameters filterParameters;
    QSharedPointer<MockLocationUpdatedSelectiveFilter> filter1;
    QSharedPointer<MockLocationUpdatedSelectiveFilter> filter2;

private:
    DISALLOW_COPY_AND_ASSIGN(BroadcastPublicationTest);
};

/**
  * Trigger:    An event occurs.
  * Expected:   The registered filter objects are called correctly.
  */
TEST_F(BroadcastPublicationTest, call_BroadcastFilterOnEventTriggered) {

    // It's only guaranteed that all filters are executed when they return true
    // (When not returning true, filter chain execution is interrupted)
    ON_CALL(*filter1, filter(Eq(gpsLocation1), Eq(filterParameters))).WillByDefault(Return(true));
    ON_CALL(*filter2, filter(Eq(gpsLocation1), Eq(filterParameters))).WillByDefault(Return(true));

    EXPECT_CALL(*filter1, filter(Eq(gpsLocation1), Eq(filterParameters)));
    EXPECT_CALL(*filter2, filter(Eq(gpsLocation1), Eq(filterParameters)));

    provider->locationUpdateSelectiveEventOccured(gpsLocation1);
}

/**
  * Trigger:    An event occurs. The filter chain has a positive result.
  * Expected:   A broadcast publication is triggered
  */
TEST_F(BroadcastPublicationTest, sendPublication_FilterChainSuccess) {

    ON_CALL(*filter1, filter(Eq(gpsLocation1), Eq(filterParameters))).WillByDefault(Return(true));
    ON_CALL(*filter2, filter(Eq(gpsLocation1), Eq(filterParameters))).WillByDefault(Return(true));

    EXPECT_CALL(*publicationSender, sendSubscriptionPublication(
                    Eq(providerParticipantId),
                    Eq(proxyParticipantId),
                    _,
                    AllOf(
                        A<SubscriptionPublication>(),
                        Property(&SubscriptionPublication::getSubscriptionId, Eq(subscriptionId)))
                    ));

    provider->locationUpdateSelectiveEventOccured(gpsLocation1);
}

/**
  * Trigger:    An event occurs. The filter chain has a negative result.
  * Expected:   A broadcast publication is triggered
  */
TEST_F(BroadcastPublicationTest, sendPublication_FilterChainFail) {

    ON_CALL(*filter1, filter(Eq(gpsLocation1), Eq(filterParameters))).WillByDefault(Return(true));
    ON_CALL(*filter2, filter(Eq(gpsLocation1), Eq(filterParameters))).WillByDefault(Return(false));

    EXPECT_CALL(*publicationSender, sendSubscriptionPublication(
                    Eq(providerParticipantId),
                    Eq(proxyParticipantId),
                    _,
                    AllOf(
                        A<SubscriptionPublication>(),
                        Property(&SubscriptionPublication::getSubscriptionId, Eq(subscriptionId)))
                    ))
            .Times(Exactly(0));

    provider->locationUpdateSelectiveEventOccured(gpsLocation1);
}

<|endoftext|>


<commit_before>/*
 * #%L
 * %%
 * Copyright (C) 2011 - 2013 BMW Car IT GmbH
 * %%
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 * #L%
 */
#include "joynr/PrivateCopyAssign.h"
#include <gtest/gtest.h>
#include <gmock/gmock.h>
#include "tests/utils/MockObjects.h"
#include <QString>
#include "joynr/LibjoynrSettings.h"
#include "joynr/OnChangeWithKeepAliveSubscriptionQos.h"
#include "joynr/tests/TestLocationUpdateSelectiveBroadcastFilterParameters.h"

#include "joynr/types/GpsLocation.h"
#include "libjoynr/subscription/SubscriptionBroadcastListener.h"

using namespace ::testing;
using ::testing::InSequence;

using namespace joynr;
using namespace joynr::tests;

ACTION_P(ReleaseSemaphore,semaphore)
{
    semaphore->release(1);
    return true;
}

/**
  * Is an integration test. Tests from Provider -> PublicationManager
  */
class BroadcastPublicationTest : public ::testing::Test {
public:
    BroadcastPublicationTest() :
        gpsLocation1(1.1, 2.2, 3.3, types::GpsFixEnum::MODE2D, 0.0, 0.0, 0.0, 0.0, 444, 444, 444),
        speed1(100),
        providerParticipantId("providerParticipantId"),
        proxyParticipantId("proxyParticipantId"),
        subscriptionId("subscriptionId"),
        publicationManager(NULL),
        publicationSender(NULL),
        request(NULL),
        provider(new MockTestProvider),
        requestCaller(new testRequestCaller(provider)),
        filter1(new MockLocationUpdatedSelectiveFilter),
        filter2(new MockLocationUpdatedSelectiveFilter)
    {
    }

    void SetUp(){
        //remove stored subscriptions
        QFile::remove(LibjoynrSettings::DEFAULT_BROADCASTSUBSCRIPTIONREQUEST_STORAGE_FILENAME());
        publicationManager = new PublicationManager();
        subscriptionBroadcastListener =
                new SubscriptionBroadcastListener(subscriptionId, *publicationManager);
        publicationSender = new MockPublicationSender();
        request = new BroadcastSubscriptionRequest();

        request->setSubscribeToName("locationUpdateSelective");
        request->setSubscriptionId(subscriptionId);

        auto subscriptionQos =
                QSharedPointer<OnChangeSubscriptionQos>(new OnChangeWithKeepAliveSubscriptionQos(
                    80, // validity_ms
                    100, // minInterval_ms
                    200, // maxInterval_ms
                    80 // alertInterval_ms
        ));
        request->setQos(subscriptionQos);
        request->setFilterParameters(filterParameters);

        requestCaller->registerBroadcastListener(
                    "locationUpdateSelective",
                    subscriptionBroadcastListener);

        publicationManager->add(
                    proxyParticipantId,
                    providerParticipantId,
                    requestCaller,
                    request,
                    publicationSender);

        publicationManager->addBroadcastFilter(filter1);
        publicationManager->addBroadcastFilter(filter2);
    }

    void TearDown(){
    }

protected:
    types::GpsLocation gpsLocation1;
    double speed1;

    QString providerParticipantId;
    QString proxyParticipantId;
    QString subscriptionId;
    PublicationManager* publicationManager;
    MockPublicationSender* publicationSender;
    BroadcastSubscriptionRequest* request;
    SubscriptionBroadcastListener* subscriptionBroadcastListener;

    QSharedPointer<MockTestProvider> provider;
    QSharedPointer<RequestCaller> requestCaller;
    TestLocationUpdateSelectiveBroadcastFilterParameters filterParameters;
    QSharedPointer<MockLocationUpdatedSelectiveFilter> filter1;
    QSharedPointer<MockLocationUpdatedSelectiveFilter> filter2;

private:
    DISALLOW_COPY_AND_ASSIGN(BroadcastPublicationTest);
};

/**
  * Trigger:    An event occurs.
  * Expected:   The registered filter objects are called correctly.
  */
TEST_F(BroadcastPublicationTest, call_BroadcastFilterOnEventTriggered) {

    // Use a semaphore to count and wait on calls to the filters
    QSemaphore semaphore(0);

    // Check also the order of filter calls
    {
        InSequence dummy;

        EXPECT_CALL(*filter1, filter(Eq(gpsLocation1), Eq(filterParameters)))
                .WillRepeatedly(ReleaseSemaphore(&semaphore));
        EXPECT_CALL(*filter2, filter(Eq(gpsLocation1), Eq(filterParameters)))
                .WillRepeatedly(ReleaseSemaphore(&semaphore));
    }

    provider->locationUpdateSelectiveEventOccured(gpsLocation1);

    ASSERT_TRUE(semaphore.tryAcquire(2, 4000));

    // The filter objects' destructors aren't executed at the end of the test, because gmock seems
    // to still hold a reference internally. This leads to gmock reporting an error about leaked
    // mock objects when leaving the scope of the test.
    // --> Delete the pointers manually.

    delete filter1.data();
    filter1.clear();

    delete filter2.data();
    filter2.clear();
}
<commit_msg>[cpp] Integration test: Don't check execution with semaphore<commit_after>/*
 * #%L
 * %%
 * Copyright (C) 2011 - 2013 BMW Car IT GmbH
 * %%
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 * #L%
 */
#include "joynr/PrivateCopyAssign.h"
#include <gtest/gtest.h>
#include <gmock/gmock.h>
#include "tests/utils/MockObjects.h"
#include <QString>
#include "joynr/LibjoynrSettings.h"
#include "joynr/OnChangeWithKeepAliveSubscriptionQos.h"
#include "joynr/tests/TestLocationUpdateSelectiveBroadcastFilterParameters.h"

#include "joynr/types/GpsLocation.h"
#include "libjoynr/subscription/SubscriptionBroadcastListener.h"

using namespace ::testing;
using ::testing::InSequence;

using namespace joynr;
using namespace joynr::tests;

/**
  * Is an integration test. Tests from Provider -> PublicationManager
  */
class BroadcastPublicationTest : public ::testing::Test {
public:
    BroadcastPublicationTest() :
        gpsLocation1(1.1, 2.2, 3.3, types::GpsFixEnum::MODE2D, 0.0, 0.0, 0.0, 0.0, 444, 444, 444),
        speed1(100),
        providerParticipantId("providerParticipantId"),
        proxyParticipantId("proxyParticipantId"),
        subscriptionId("subscriptionId"),
        publicationManager(NULL),
        publicationSender(NULL),
        request(NULL),
        provider(new MockTestProvider),
        requestCaller(new testRequestCaller(provider)),
        filter1(new MockLocationUpdatedSelectiveFilter),
        filter2(new MockLocationUpdatedSelectiveFilter)
    {
    }

    void SetUp(){
        //remove stored subscriptions
        QFile::remove(LibjoynrSettings::DEFAULT_BROADCASTSUBSCRIPTIONREQUEST_STORAGE_FILENAME());
        publicationManager = new PublicationManager();
        subscriptionBroadcastListener =
                new SubscriptionBroadcastListener(subscriptionId, *publicationManager);
        publicationSender = new MockPublicationSender();
        request = new BroadcastSubscriptionRequest();

        request->setSubscribeToName("locationUpdateSelective");
        request->setSubscriptionId(subscriptionId);

        auto subscriptionQos =
                QSharedPointer<OnChangeSubscriptionQos>(new OnChangeWithKeepAliveSubscriptionQos(
                    80, // validity_ms
                    100, // minInterval_ms
                    200, // maxInterval_ms
                    80 // alertInterval_ms
        ));
        request->setQos(subscriptionQos);
        request->setFilterParameters(filterParameters);

        requestCaller->registerBroadcastListener(
                    "locationUpdateSelective",
                    subscriptionBroadcastListener);

        publicationManager->add(
                    proxyParticipantId,
                    providerParticipantId,
                    requestCaller,
                    request,
                    publicationSender);

        publicationManager->addBroadcastFilter(filter1);
        publicationManager->addBroadcastFilter(filter2);
    }

    void TearDown(){
        delete publicationSender;

        // The filter objects' destructors aren't executed at the end of the test, because gmock seems
        // to still hold a reference internally. This leads to gmock reporting an error about leaked
        // mock objects when leaving the scope of the test.
        // --> Delete the pointers manually.

        delete filter1.data();
        filter1.clear();

        delete filter2.data();
        filter2.clear();
    }

protected:
    types::GpsLocation gpsLocation1;
    double speed1;

    QString providerParticipantId;
    QString proxyParticipantId;
    QString subscriptionId;
    PublicationManager* publicationManager;
    MockPublicationSender* publicationSender;
    BroadcastSubscriptionRequest* request;
    SubscriptionBroadcastListener* subscriptionBroadcastListener;

    QSharedPointer<MockTestProvider> provider;
    QSharedPointer<RequestCaller> requestCaller;
    TestLocationUpdateSelectiveBroadcastFilterParameters filterParameters;
    QSharedPointer<MockLocationUpdatedSelectiveFilter> filter1;
    QSharedPointer<MockLocationUpdatedSelectiveFilter> filter2;

private:
    DISALLOW_COPY_AND_ASSIGN(BroadcastPublicationTest);
};

/**
  * Trigger:    An event occurs.
  * Expected:   The registered filter objects are called correctly.
  */
TEST_F(BroadcastPublicationTest, call_BroadcastFilterOnEventTriggered) {

    // It's only guaranteed that all filters are executed when they return true
    // (When not returning true, filter chain execution is interrupted)
    ON_CALL(*filter1, filter(Eq(gpsLocation1), Eq(filterParameters))).WillByDefault(Return(true));
    ON_CALL(*filter2, filter(Eq(gpsLocation1), Eq(filterParameters))).WillByDefault(Return(true));

    EXPECT_CALL(*filter1, filter(Eq(gpsLocation1), Eq(filterParameters)));
    EXPECT_CALL(*filter2, filter(Eq(gpsLocation1), Eq(filterParameters)));

    provider->locationUpdateSelectiveEventOccured(gpsLocation1);
}
<|endoftext|>


<commit_before>/*
 * #%L
 * %%
 * Copyright (C) 2011 - 2016 BMW Car IT GmbH
 * %%
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 * #L%
 */
#include <gtest/gtest.h>
#include <gmock/gmock.h>

#include "runtimes/cluster-controller-runtime/JoynrClusterControllerRuntime.h"
#include "joynr/tests/testProxy.h"
#include "joynr/tests/DefaulttestProvider.h"
#include "joynr/types/ProviderQos.h"
#include "joynr/MessagingSettings.h"
#include "joynr/Settings.h"

using namespace ::testing;
using namespace joynr;

namespace joynr {

class LocalDiscoveryTest : public ::testing::Test
{
public:

    LocalDiscoveryTest() :
        runtime1(nullptr),
        runtime2(nullptr),
        testDomain("testDomain")
    {
        auto settings1 = std::make_unique<Settings>("test-resources/MqttWithHttpBackendSystemIntegrationTest1.settings");
        auto settings2 = std::make_unique<Settings>("test-resources/MqttWithHttpBackendSystemIntegrationTest2.settings");

        MessagingSettings messagingSettings1(*settings1);
        MessagingSettings messagingSettings2(*settings2);

        messagingSettings1.setMessagingPropertiesPersistenceFilename(
                    "End2EndBroadcastTest-runtime1-joynr.settings");
        messagingSettings2.setMessagingPropertiesPersistenceFilename(
                    "End2EndBroadcastTest-runtime2-joynr.settings");

        Settings integration1Settings{"test-resources/libjoynrSystemIntegration1.settings"};
        Settings::merge(integration1Settings, *settings1, false);

        runtime1 = std::make_unique<JoynrClusterControllerRuntime>(std::move(settings1));

        Settings integration2Settings{"test-resources/libjoynrSystemIntegration2.settings"};
        Settings::merge(integration2Settings, *settings2, false);

        runtime2 = std::make_unique<JoynrClusterControllerRuntime>(std::move(settings2));

        runtime1->start();
        runtime2->start();

        discoveryQos.setArbitrationStrategy(DiscoveryQos::ArbitrationStrategy::LAST_SEEN);
        discoveryQos.setDiscoveryTimeoutMs(3000);
        discoveryQos.setRetryIntervalMs(250);

        messagingQos.setTtl(500);
    }

    ~LocalDiscoveryTest()
    {
        const bool deleteChannel = true;
        runtime1->stop(deleteChannel);
        runtime2->stop(deleteChannel);

        // Delete persisted files
        std::remove(LibjoynrSettings::DEFAULT_LOCAL_CAPABILITIES_DIRECTORY_PERSISTENCE_FILENAME().c_str());
        std::remove(LibjoynrSettings::DEFAULT_MESSAGE_ROUTER_PERSISTENCE_FILENAME().c_str());
        std::remove(LibjoynrSettings::DEFAULT_SUBSCRIPTIONREQUEST_PERSISTENCE_FILENAME().c_str());
        std::remove(LibjoynrSettings::DEFAULT_PARTICIPANT_IDS_PERSISTENCE_FILENAME().c_str());
    }

protected:

    void registerProvider(JoynrClusterControllerRuntime& runtime)
    {
        auto testProvider = std::make_shared<tests::DefaulttestProvider>();
        joynr::types::ProviderQos providerQos;
        runtime.registerProvider<tests::testProvider>(testDomain, testProvider, providerQos);
    }

    std::unique_ptr<JoynrClusterControllerRuntime> runtime1;
    std::unique_ptr<JoynrClusterControllerRuntime> runtime2;
    const std::string testDomain;
    DiscoveryQos discoveryQos;
    MessagingQos messagingQos;

private:
    DISALLOW_COPY_AND_ASSIGN(LocalDiscoveryTest);
};

} // namespace joynr

class LocalDiscoveryTestTestProxy : public tests::testProxy
{
public:

    LocalDiscoveryTestTestProxy(
        std::shared_ptr<const joynr::system::RoutingTypes::Address> messagingAddress,
        joynr::ConnectorFactory* connectorFactory,
        const std::string& domain,
        const joynr::MessagingQos& qosSettings) :
            joynr::ProxyBase(connectorFactory, domain, qosSettings),
            testProxyBase(messagingAddress, connectorFactory, domain, qosSettings),
            testFireAndForgetProxy(messagingAddress, connectorFactory, domain, qosSettings),
            testSyncProxy(messagingAddress, connectorFactory, domain, qosSettings),
            testAsyncProxy(messagingAddress, connectorFactory, domain, qosSettings),
            testProxy(messagingAddress, connectorFactory, domain, qosSettings)
    {

    }

    using tests::testProxy::providerDiscoveryEntry;
};

TEST_F(LocalDiscoveryTest, testLocalLookup) {
    registerProvider(*runtime1);

    std::unique_ptr<ProxyBuilder<LocalDiscoveryTestTestProxy>> testProxyBuilder(
        runtime1->createProxyBuilder<LocalDiscoveryTestTestProxy>(testDomain)
    );

    std::unique_ptr<LocalDiscoveryTestTestProxy> testProxy(testProxyBuilder
       ->setMessagingQos(messagingQos)
       ->setDiscoveryQos(discoveryQos)
       ->build());

    EXPECT_TRUE(testProxy->providerDiscoveryEntry.getIsLocal());
}

TEST_F(LocalDiscoveryTest, testGloballLookup) {
    registerProvider(*runtime1);

    std::unique_ptr<ProxyBuilder<LocalDiscoveryTestTestProxy>> testProxyBuilder(
        runtime2->createProxyBuilder<LocalDiscoveryTestTestProxy>(testDomain)
    );

    std::unique_ptr<LocalDiscoveryTestTestProxy> testProxy(testProxyBuilder
       ->setMessagingQos(messagingQos)
       ->setDiscoveryQos(discoveryQos)
       ->build());

    EXPECT_FALSE(testProxy->providerDiscoveryEntry.getIsLocal());
}
<commit_msg>[C++] added E2E test for async provider registration<commit_after>/*
 * #%L
 * %%
 * Copyright (C) 2011 - 2017 BMW Car IT GmbH
 * %%
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 * #L%
 */
#include <gtest/gtest.h>
#include <gmock/gmock.h>

#include "joynr/MessagingSettings.h"
#include "joynr/Settings.h"
#include "joynr/tests/DefaulttestProvider.h"
#include "joynr/tests/testProxy.h"
#include "joynr/types/ProviderQos.h"

#include "runtimes/cluster-controller-runtime/JoynrClusterControllerRuntime.h"

using namespace ::testing;
using namespace joynr;

namespace joynr {

class LocalDiscoveryTest : public ::testing::Test
{
public:

    LocalDiscoveryTest() :
        runtime1(nullptr),
        runtime2(nullptr),
        testDomain("testDomain")
    {
        auto settings1 = std::make_unique<Settings>("test-resources/MqttWithHttpBackendSystemIntegrationTest1.settings");
        auto settings2 = std::make_unique<Settings>("test-resources/MqttWithHttpBackendSystemIntegrationTest2.settings");

        MessagingSettings messagingSettings1(*settings1);
        MessagingSettings messagingSettings2(*settings2);

        messagingSettings1.setMessagingPropertiesPersistenceFilename(
                    "End2EndBroadcastTest-runtime1-joynr.settings");
        messagingSettings2.setMessagingPropertiesPersistenceFilename(
                    "End2EndBroadcastTest-runtime2-joynr.settings");

        Settings integration1Settings{"test-resources/libjoynrSystemIntegration1.settings"};
        Settings::merge(integration1Settings, *settings1, false);

        runtime1 = std::make_unique<JoynrClusterControllerRuntime>(std::move(settings1));

        Settings integration2Settings{"test-resources/libjoynrSystemIntegration2.settings"};
        Settings::merge(integration2Settings, *settings2, false);

        runtime2 = std::make_unique<JoynrClusterControllerRuntime>(std::move(settings2));

        runtime1->start();
        runtime2->start();

        discoveryQos.setArbitrationStrategy(DiscoveryQos::ArbitrationStrategy::LAST_SEEN);
        discoveryQos.setDiscoveryTimeoutMs(3000);
        discoveryQos.setRetryIntervalMs(250);

        messagingQos.setTtl(500);
    }

    ~LocalDiscoveryTest()
    {
        const bool deleteChannel = true;
        runtime1->stop(deleteChannel);
        runtime2->stop(deleteChannel);

        // Delete persisted files
        std::remove(LibjoynrSettings::DEFAULT_LOCAL_CAPABILITIES_DIRECTORY_PERSISTENCE_FILENAME().c_str());
        std::remove(LibjoynrSettings::DEFAULT_MESSAGE_ROUTER_PERSISTENCE_FILENAME().c_str());
        std::remove(LibjoynrSettings::DEFAULT_SUBSCRIPTIONREQUEST_PERSISTENCE_FILENAME().c_str());
        std::remove(LibjoynrSettings::DEFAULT_PARTICIPANT_IDS_PERSISTENCE_FILENAME().c_str());
    }

protected:

    void registerProvider(JoynrClusterControllerRuntime& runtime)
    {
        auto testProvider = std::make_shared<tests::DefaulttestProvider>();
        joynr::types::ProviderQos providerQos;
        runtime.registerProvider<tests::testProvider>(testDomain, testProvider, providerQos);
    }

    std::unique_ptr<JoynrClusterControllerRuntime> runtime1;
    std::unique_ptr<JoynrClusterControllerRuntime> runtime2;
    const std::string testDomain;
    DiscoveryQos discoveryQos;
    MessagingQos messagingQos;

private:
    DISALLOW_COPY_AND_ASSIGN(LocalDiscoveryTest);
};

} // namespace joynr

class LocalDiscoveryTestTestProxy : public tests::testProxy
{
public:

    LocalDiscoveryTestTestProxy(
        std::shared_ptr<const joynr::system::RoutingTypes::Address> messagingAddress,
        joynr::ConnectorFactory* connectorFactory,
        const std::string& domain,
        const joynr::MessagingQos& qosSettings) :
            joynr::ProxyBase(connectorFactory, domain, qosSettings),
            testProxyBase(messagingAddress, connectorFactory, domain, qosSettings),
            testFireAndForgetProxy(messagingAddress, connectorFactory, domain, qosSettings),
            testSyncProxy(messagingAddress, connectorFactory, domain, qosSettings),
            testAsyncProxy(messagingAddress, connectorFactory, domain, qosSettings),
            testProxy(messagingAddress, connectorFactory, domain, qosSettings)
    {

    }

    using tests::testProxy::providerDiscoveryEntry;
};

TEST_F(LocalDiscoveryTest, testLocalLookup) {
    registerProvider(*runtime1);

    std::unique_ptr<ProxyBuilder<LocalDiscoveryTestTestProxy>> testProxyBuilder(
        runtime1->createProxyBuilder<LocalDiscoveryTestTestProxy>(testDomain)
    );

    std::unique_ptr<LocalDiscoveryTestTestProxy> testProxy(testProxyBuilder
       ->setMessagingQos(messagingQos)
       ->setDiscoveryQos(discoveryQos)
       ->build());

    EXPECT_TRUE(testProxy->providerDiscoveryEntry.getIsLocal());
}

TEST_F(LocalDiscoveryTest, testGloballLookup) {
    registerProvider(*runtime1);

    std::unique_ptr<ProxyBuilder<LocalDiscoveryTestTestProxy>> testProxyBuilder(
        runtime2->createProxyBuilder<LocalDiscoveryTestTestProxy>(testDomain)
    );

    std::unique_ptr<LocalDiscoveryTestTestProxy> testProxy(testProxyBuilder
       ->setMessagingQos(messagingQos)
       ->setDiscoveryQos(discoveryQos)
       ->build());

    EXPECT_FALSE(testProxy->providerDiscoveryEntry.getIsLocal());
}

TEST_F(LocalDiscoveryTest, testAsyncRegistration)
{
    auto testProvider = std::make_shared<tests::DefaulttestProvider>();
    joynr::types::ProviderQos providerQos;
    auto onSuccess = []() {};
    auto onError = [](const exceptions::JoynrRuntimeException&){
        FAIL();
    };

    runtime1->registerProviderAsync<tests::testProvider>(testDomain, testProvider, providerQos, onSuccess, onError);

    std::unique_ptr<ProxyBuilder<LocalDiscoveryTestTestProxy>> testProxyBuilder(
        runtime2->createProxyBuilder<LocalDiscoveryTestTestProxy>(testDomain)
    );

    std::unique_ptr<LocalDiscoveryTestTestProxy> testProxy(testProxyBuilder
       ->setMessagingQos(messagingQos)
       ->setDiscoveryQos(discoveryQos)
       ->build());
}
<|endoftext|>


<commit_before>/*************************************************************************
 *
 *  $RCSfile: transparencygroupaction.cxx,v $
 *
 *  $Revision: 1.2 $
 *
 *  last change: $Author: rt $ $Date: 2004-11-26 20:57:31 $
 *
 *  The Contents of this file are made available subject to the terms of
 *  either of the following licenses
 *
 *         - GNU Lesser General Public License Version 2.1
 *         - Sun Industry Standards Source License Version 1.1
 *
 *  Sun Microsystems Inc., October, 2000
 *
 *  GNU Lesser General Public License Version 2.1
 *  =============================================
 *  Copyright 2000 by Sun Microsystems, Inc.
 *  901 San Antonio Road, Palo Alto, CA 94303, USA
 *
 *  This library is free software; you can redistribute it and/or
 *  modify it under the terms of the GNU Lesser General Public
 *  License version 2.1, as published by the Free Software Foundation.
 *
 *  This library is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 *  Lesser General Public License for more details.
 *
 *  You should have received a copy of the GNU Lesser General Public
 *  License along with this library; if not, write to the Free Software
 *  Foundation, Inc., 59 Temple Place, Suite 330, Boston,
 *  MA  02111-1307  USA
 *
 *
 *  Sun Industry Standards Source License Version 1.1
 *  =================================================
 *  The contents of this file are subject to the Sun Industry Standards
 *  Source License Version 1.1 (the "License"); You may not use this file
 *  except in compliance with the License. You may obtain a copy of the
 *  License at http://www.openoffice.org/license.html.
 *
 *  Software provided under this License is provided on an "AS IS" basis,
 *  WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
 *  WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
 *  MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
 *  See the License for the specific provisions governing your rights and
 *  obligations concerning the Software.
 *
 *  The Initial Developer of the Original Code is: Sun Microsystems, Inc.
 *
 *  Copyright: 2000 by Sun Microsystems, Inc.
 *
 *  All Rights Reserved.
 *
 *  Contributor(s): _______________________________________
 *
 *
 ************************************************************************/

#ifndef _SV_GEN_HXX
#include <tools/gen.hxx>
#endif

#include <canvas/debug.hxx>
#include <canvas/verbosetrace.hxx>
#include <transparencygroupaction.hxx>
#include <outdevstate.hxx>

#ifndef _RTL_LOGFILE_HXX_
#include <rtl/logfile.hxx>
#endif

#ifndef _DRAFTS_COM_SUN_STAR_RENDERING_XBITMAP_HPP__
#include <drafts/com/sun/star/rendering/XBitmap.hpp>
#endif

#ifndef INCLUDED_RTL_MATH_HXX
#include <rtl/math.hxx>
#endif

#ifndef _SV_BITMAPEX_HXX
#include <vcl/bitmapex.hxx>
#endif
#ifndef _VCL_CANVASTOOLS_HXX
#include <vcl/canvastools.hxx>
#endif
#ifndef _SV_SVAPP_HXX
#include <vcl/svapp.hxx>
#endif
#ifndef _SV_OUTDEV_HXX
#include <vcl/outdev.hxx>
#endif
#ifndef _SV_VIRDEV_HXX
#include <vcl/virdev.hxx>
#endif
#ifndef _SV_VIRDEV_HXX
#include <vcl/virdev.hxx>
#endif
#ifndef _SV_GDIMTF_HXX
#include <vcl/gdimtf.hxx>
#endif
#ifndef _SV_GRADIENT_HXX
#include <vcl/gradient.hxx>
#endif

#ifndef _CANVAS_CANVASTOOLS_HXX
#include <canvas/canvastools.hxx>
#endif

#ifndef _BGFX_NUMERIC_FTOOLS_HXX
#include <basegfx/numeric/ftools.hxx>
#endif
#ifndef _BGFX_MATRIX_B2DHOMMATRIX_HXX
#include <basegfx/matrix/b2dhommatrix.hxx>
#endif
#ifndef _BGFX_TUPLE_B2DTUPLE_HXX
#include <basegfx/tuple/b2dtuple.hxx>
#endif
#ifndef _BGFX_TOOLS_CANVASTOOLS_HXX
#include <basegfx/tools/canvastools.hxx>
#endif

#include <mtftools.hxx>
#include <cppcanvas/vclfactory.hxx>

using namespace ::com::sun::star;
using namespace ::drafts::com::sun::star;

namespace cppcanvas
{
    namespace internal
    {
        // free support functions
        // ======================
        namespace
        {
            /** Setup transformation such that the next render call is
                moved rPoint away, and scaled according to the ratio
                given by src and dst size.
            */
            void implSetupTransform( rendering::RenderState&    rRenderState,
                                     const Point&               rDstPoint   )
            {
                ::basegfx::B2DHomMatrix aLocalTransformation;

                aLocalTransformation.translate( rDstPoint.X(),
                                                rDstPoint.Y() );
                ::canvas::tools::appendToRenderState( rRenderState,
                                                      aLocalTransformation );
            }
        }

        TransparencyGroupAction::TransparencyGroupAction( MtfAutoPtr&                   rGroupMtf,
                                                          const Renderer::Parameters&   rParms,
                                                          const ::Point&                rDstPoint,
                                                          const ::Size&                 rDstSize,
                                                          double                        nAlpha,
                                                          const CanvasSharedPtr&        rCanvas,
                                                          const OutDevState&            rState ) :
            mpGroupMtf( rGroupMtf ),
            mpAlphaGradient(),
            maParms( rParms ),
            maDstSize( rDstSize ),
            mxBufferBitmap(),
            maLastTransformation(),
            mpCanvas( rCanvas ),
            maState(),
            mnAlpha( nAlpha )
        {
            tools::initRenderState(maState,rState);
            implSetupTransform( maState, rDstPoint );
        }

        TransparencyGroupAction::TransparencyGroupAction( MtfAutoPtr&                   rGroupMtf,
                                                          GradientAutoPtr&              rAlphaGradient,
                                                          const Renderer::Parameters&   rParms,
                                                          const ::Point&                rDstPoint,
                                                          const ::Size&                 rDstSize,
                                                          const CanvasSharedPtr&        rCanvas,
                                                          const OutDevState&            rState ) :
            mpGroupMtf( rGroupMtf ),
            mpAlphaGradient( rAlphaGradient ),
            maParms( rParms ),
            maDstSize( rDstSize ),
            mxBufferBitmap(),
            maLastTransformation(),
            mpCanvas( rCanvas ),
            maState(),
            mnAlpha( 1.0 )
        {
            tools::initRenderState(maState,rState);
            implSetupTransform( maState, rDstPoint );
        }

        TransparencyGroupAction::~TransparencyGroupAction()
        {
            // outline, because of incomplete types in header
        }

        // TODO(P3): The whole float transparency handling is a mess,
        // this should be refactored. What's more, the old idea of
        // having only internal 'metaactions', and not the original
        // GDIMetaFile now looks a lot less attractive. Try to move
        // into the direction of having a direct GDIMetaFile2XCanvas
        // renderer, and maybe a separate metafile XCanvas
        // implementation.
        bool TransparencyGroupAction::render( const ::basegfx::B2DHomMatrix& rTransformation ) const
        {
            RTL_LOGFILE_CONTEXT( aLog, "::cppcanvas::internal::TransparencyGroupAction::render()" );
            RTL_LOGFILE_CONTEXT_TRACE1( aLog, "::cppcanvas::internal::TransparencyGroupAction: 0x%X", this );

            // determine overall transformation matrix (render, view,
            // and passed transformation)
            ::basegfx::B2DHomMatrix aTransform;
            ::canvas::tools::getRenderStateTransform( aTransform, maState );
            aTransform = rTransformation * aTransform;

            ::basegfx::B2DHomMatrix aTotalTransform;
            ::canvas::tools::getViewStateTransform( aTotalTransform, mpCanvas->getViewState() );
            aTotalTransform = aTotalTransform * aTransform;

            // since pure translational changes to the transformation
            // does not matter, remove them before comparing
            aTotalTransform.set( 0, 2, 0.0 );
            aTotalTransform.set( 1, 2, 0.0 );

            // as soon as the total transformation changes, we've got
            // to re-render the bitmap
            if( aTotalTransform != maLastTransformation)
            {
                DBG_TESTSOLARMUTEX();

                // determine total scaling factor of the
                // transformation matrix - need to make the bitmap
                // large enough
                ::basegfx::B2DTuple aScale;
                ::basegfx::B2DTuple aTranslate;
                double              nRotate;
                double              nShearX;
                if( !aTotalTransform.decompose( aScale,
                                                aTranslate,
                                                nRotate,
                                                nShearX ) )
                {
                    OSL_ENSURE( false,
                                "TransparencyGroupAction::render(): non-decomposable transformation" );
                    return false;
                }

                ::Size aSize( ::basegfx::fround( aScale.getX() * maDstSize.Width() ),
                              ::basegfx::fround( aScale.getY() * maDstSize.Height() ) );

                // render our content into an appropriately sized
                // VirtualDevice with alpha channel
                VirtualDevice aVDev(
                    *::Application::GetDefaultDevice(), 0, 0 );
                aVDev.SetOutputSizePixel( aSize );
                aVDev.SetMapMode();

                ::Point aEmptyPoint;
                aVDev.DrawTransparent( *mpGroupMtf,
                                       aEmptyPoint,
                                       aSize,
                                       *mpAlphaGradient );

                // update buffered bitmap and transformation
                BitmapSharedPtr aBmp( VCLFactory::getInstance().createBitmap(
                                          mpCanvas,
                                          aVDev.GetBitmapEx(
                                              aEmptyPoint,
                                              aSize ) ) );
                mxBufferBitmap = aBmp->getUNOBitmap();
                maLastTransformation = aTotalTransform;
            }

            // determine target transformation (we can't simply pass
            // aTotalTransform as assembled above, since we must take
            // the canvas' view state as is, it might contain clipping
            // (which, in turn, is relative to the view
            // transformation))

            // given that aTotalTransform is the identity
            // transformation, we could simply render our bitmap
            // as-is. Now, since the mxBufferBitmap content already
            // accounts for scale changes in the overall
            // transformation, we must factor this out
            // before. Generally, the transformation matrix should be
            // structured like this:
            // Translation*Rotation*Shear*Scale. Thus, to neutralize
            // the contained scaling, we've got to right-multiply with
            // the inverse.
            ::basegfx::B2ISize aBmpSize(
                ::basegfx::unotools::b2ISizeFromIntegerSize2D( mxBufferBitmap->getSize() ) );

            ::basegfx::B2DHomMatrix aScaleCorrection;
            aScaleCorrection.scale( (double)maDstSize.Width() / aBmpSize.getX(),
                                    (double)maDstSize.Height() / aBmpSize.getY() );
            aTransform = aTransform * aScaleCorrection;

            rendering::RenderState aLocalState( maState );
            ::canvas::tools::setRenderStateTransform(aLocalState, aTransform);

            if( ::rtl::math::approxEqual(mnAlpha, 1.0) )
            {
                // no further alpha changes necessary -> draw directly
                mpCanvas->getUNOCanvas()->drawBitmap( mxBufferBitmap,
                                                      mpCanvas->getViewState(),
                                                      aLocalState );
            }
            else
            {
                // add alpha modulation value to DeviceColor
                aLocalState.DeviceColor.realloc(4);
                aLocalState.DeviceColor[0] = 1.0;
                aLocalState.DeviceColor[1] = 1.0;
                aLocalState.DeviceColor[2] = 1.0;
                aLocalState.DeviceColor[3] = mnAlpha;
                mpCanvas->getUNOCanvas()->drawBitmapModulated( mxBufferBitmap,
                                                               mpCanvas->getViewState(),
                                                               aLocalState );
            }

            return true;
        }

    }
}
<commit_msg>INTEGRATION: CWS presfixes01 (1.2.6); FILE MERGED 2005/02/16 11:14:31 fs 1.2.6.1: #i42558# drafts.com.sun.star.drawing/rendering/geometry moved to com.sun.star.*<commit_after>/*************************************************************************
 *
 *  $RCSfile: transparencygroupaction.cxx,v $
 *
 *  $Revision: 1.3 $
 *
 *  last change: $Author: vg $ $Date: 2005-03-10 13:27:00 $
 *
 *  The Contents of this file are made available subject to the terms of
 *  either of the following licenses
 *
 *         - GNU Lesser General Public License Version 2.1
 *         - Sun Industry Standards Source License Version 1.1
 *
 *  Sun Microsystems Inc., October, 2000
 *
 *  GNU Lesser General Public License Version 2.1
 *  =============================================
 *  Copyright 2000 by Sun Microsystems, Inc.
 *  901 San Antonio Road, Palo Alto, CA 94303, USA
 *
 *  This library is free software; you can redistribute it and/or
 *  modify it under the terms of the GNU Lesser General Public
 *  License version 2.1, as published by the Free Software Foundation.
 *
 *  This library is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 *  Lesser General Public License for more details.
 *
 *  You should have received a copy of the GNU Lesser General Public
 *  License along with this library; if not, write to the Free Software
 *  Foundation, Inc., 59 Temple Place, Suite 330, Boston,
 *  MA  02111-1307  USA
 *
 *
 *  Sun Industry Standards Source License Version 1.1
 *  =================================================
 *  The contents of this file are subject to the Sun Industry Standards
 *  Source License Version 1.1 (the "License"); You may not use this file
 *  except in compliance with the License. You may obtain a copy of the
 *  License at http://www.openoffice.org/license.html.
 *
 *  Software provided under this License is provided on an "AS IS" basis,
 *  WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
 *  WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
 *  MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
 *  See the License for the specific provisions governing your rights and
 *  obligations concerning the Software.
 *
 *  The Initial Developer of the Original Code is: Sun Microsystems, Inc.
 *
 *  Copyright: 2000 by Sun Microsystems, Inc.
 *
 *  All Rights Reserved.
 *
 *  Contributor(s): _______________________________________
 *
 *
 ************************************************************************/

#ifndef _SV_GEN_HXX
#include <tools/gen.hxx>
#endif

#include <canvas/debug.hxx>
#include <canvas/verbosetrace.hxx>
#include <transparencygroupaction.hxx>
#include <outdevstate.hxx>

#ifndef _RTL_LOGFILE_HXX_
#include <rtl/logfile.hxx>
#endif

#ifndef _COM_SUN_STAR_RENDERING_XBITMAP_HPP__
#include <com/sun/star/rendering/XBitmap.hpp>
#endif

#ifndef INCLUDED_RTL_MATH_HXX
#include <rtl/math.hxx>
#endif

#ifndef _SV_BITMAPEX_HXX
#include <vcl/bitmapex.hxx>
#endif
#ifndef _VCL_CANVASTOOLS_HXX
#include <vcl/canvastools.hxx>
#endif
#ifndef _SV_SVAPP_HXX
#include <vcl/svapp.hxx>
#endif
#ifndef _SV_OUTDEV_HXX
#include <vcl/outdev.hxx>
#endif
#ifndef _SV_VIRDEV_HXX
#include <vcl/virdev.hxx>
#endif
#ifndef _SV_VIRDEV_HXX
#include <vcl/virdev.hxx>
#endif
#ifndef _SV_GDIMTF_HXX
#include <vcl/gdimtf.hxx>
#endif
#ifndef _SV_GRADIENT_HXX
#include <vcl/gradient.hxx>
#endif

#ifndef _CANVAS_CANVASTOOLS_HXX
#include <canvas/canvastools.hxx>
#endif

#ifndef _BGFX_NUMERIC_FTOOLS_HXX
#include <basegfx/numeric/ftools.hxx>
#endif
#ifndef _BGFX_MATRIX_B2DHOMMATRIX_HXX
#include <basegfx/matrix/b2dhommatrix.hxx>
#endif
#ifndef _BGFX_TUPLE_B2DTUPLE_HXX
#include <basegfx/tuple/b2dtuple.hxx>
#endif
#ifndef _BGFX_TOOLS_CANVASTOOLS_HXX
#include <basegfx/tools/canvastools.hxx>
#endif

#include <mtftools.hxx>
#include <cppcanvas/vclfactory.hxx>

using namespace ::com::sun::star;

namespace cppcanvas
{
    namespace internal
    {
        // free support functions
        // ======================
        namespace
        {
            /** Setup transformation such that the next render call is
                moved rPoint away, and scaled according to the ratio
                given by src and dst size.
            */
            void implSetupTransform( rendering::RenderState&    rRenderState,
                                     const Point&               rDstPoint   )
            {
                ::basegfx::B2DHomMatrix aLocalTransformation;

                aLocalTransformation.translate( rDstPoint.X(),
                                                rDstPoint.Y() );
                ::canvas::tools::appendToRenderState( rRenderState,
                                                      aLocalTransformation );
            }
        }

        TransparencyGroupAction::TransparencyGroupAction( MtfAutoPtr&                   rGroupMtf,
                                                          const Renderer::Parameters&   rParms,
                                                          const ::Point&                rDstPoint,
                                                          const ::Size&                 rDstSize,
                                                          double                        nAlpha,
                                                          const CanvasSharedPtr&        rCanvas,
                                                          const OutDevState&            rState ) :
            mpGroupMtf( rGroupMtf ),
            mpAlphaGradient(),
            maParms( rParms ),
            maDstSize( rDstSize ),
            mxBufferBitmap(),
            maLastTransformation(),
            mpCanvas( rCanvas ),
            maState(),
            mnAlpha( nAlpha )
        {
            tools::initRenderState(maState,rState);
            implSetupTransform( maState, rDstPoint );
        }

        TransparencyGroupAction::TransparencyGroupAction( MtfAutoPtr&                   rGroupMtf,
                                                          GradientAutoPtr&              rAlphaGradient,
                                                          const Renderer::Parameters&   rParms,
                                                          const ::Point&                rDstPoint,
                                                          const ::Size&                 rDstSize,
                                                          const CanvasSharedPtr&        rCanvas,
                                                          const OutDevState&            rState ) :
            mpGroupMtf( rGroupMtf ),
            mpAlphaGradient( rAlphaGradient ),
            maParms( rParms ),
            maDstSize( rDstSize ),
            mxBufferBitmap(),
            maLastTransformation(),
            mpCanvas( rCanvas ),
            maState(),
            mnAlpha( 1.0 )
        {
            tools::initRenderState(maState,rState);
            implSetupTransform( maState, rDstPoint );
        }

        TransparencyGroupAction::~TransparencyGroupAction()
        {
            // outline, because of incomplete types in header
        }

        // TODO(P3): The whole float transparency handling is a mess,
        // this should be refactored. What's more, the old idea of
        // having only internal 'metaactions', and not the original
        // GDIMetaFile now looks a lot less attractive. Try to move
        // into the direction of having a direct GDIMetaFile2XCanvas
        // renderer, and maybe a separate metafile XCanvas
        // implementation.
        bool TransparencyGroupAction::render( const ::basegfx::B2DHomMatrix& rTransformation ) const
        {
            RTL_LOGFILE_CONTEXT( aLog, "::cppcanvas::internal::TransparencyGroupAction::render()" );
            RTL_LOGFILE_CONTEXT_TRACE1( aLog, "::cppcanvas::internal::TransparencyGroupAction: 0x%X", this );

            // determine overall transformation matrix (render, view,
            // and passed transformation)
            ::basegfx::B2DHomMatrix aTransform;
            ::canvas::tools::getRenderStateTransform( aTransform, maState );
            aTransform = rTransformation * aTransform;

            ::basegfx::B2DHomMatrix aTotalTransform;
            ::canvas::tools::getViewStateTransform( aTotalTransform, mpCanvas->getViewState() );
            aTotalTransform = aTotalTransform * aTransform;

            // since pure translational changes to the transformation
            // does not matter, remove them before comparing
            aTotalTransform.set( 0, 2, 0.0 );
            aTotalTransform.set( 1, 2, 0.0 );

            // as soon as the total transformation changes, we've got
            // to re-render the bitmap
            if( aTotalTransform != maLastTransformation)
            {
                DBG_TESTSOLARMUTEX();

                // determine total scaling factor of the
                // transformation matrix - need to make the bitmap
                // large enough
                ::basegfx::B2DTuple aScale;
                ::basegfx::B2DTuple aTranslate;
                double              nRotate;
                double              nShearX;
                if( !aTotalTransform.decompose( aScale,
                                                aTranslate,
                                                nRotate,
                                                nShearX ) )
                {
                    OSL_ENSURE( false,
                                "TransparencyGroupAction::render(): non-decomposable transformation" );
                    return false;
                }

                ::Size aSize( ::basegfx::fround( aScale.getX() * maDstSize.Width() ),
                              ::basegfx::fround( aScale.getY() * maDstSize.Height() ) );

                // render our content into an appropriately sized
                // VirtualDevice with alpha channel
                VirtualDevice aVDev(
                    *::Application::GetDefaultDevice(), 0, 0 );
                aVDev.SetOutputSizePixel( aSize );
                aVDev.SetMapMode();

                ::Point aEmptyPoint;
                aVDev.DrawTransparent( *mpGroupMtf,
                                       aEmptyPoint,
                                       aSize,
                                       *mpAlphaGradient );

                // update buffered bitmap and transformation
                BitmapSharedPtr aBmp( VCLFactory::getInstance().createBitmap(
                                          mpCanvas,
                                          aVDev.GetBitmapEx(
                                              aEmptyPoint,
                                              aSize ) ) );
                mxBufferBitmap = aBmp->getUNOBitmap();
                maLastTransformation = aTotalTransform;
            }

            // determine target transformation (we can't simply pass
            // aTotalTransform as assembled above, since we must take
            // the canvas' view state as is, it might contain clipping
            // (which, in turn, is relative to the view
            // transformation))

            // given that aTotalTransform is the identity
            // transformation, we could simply render our bitmap
            // as-is. Now, since the mxBufferBitmap content already
            // accounts for scale changes in the overall
            // transformation, we must factor this out
            // before. Generally, the transformation matrix should be
            // structured like this:
            // Translation*Rotation*Shear*Scale. Thus, to neutralize
            // the contained scaling, we've got to right-multiply with
            // the inverse.
            ::basegfx::B2ISize aBmpSize(
                ::basegfx::unotools::b2ISizeFromIntegerSize2D( mxBufferBitmap->getSize() ) );

            ::basegfx::B2DHomMatrix aScaleCorrection;
            aScaleCorrection.scale( (double)maDstSize.Width() / aBmpSize.getX(),
                                    (double)maDstSize.Height() / aBmpSize.getY() );
            aTransform = aTransform * aScaleCorrection;

            rendering::RenderState aLocalState( maState );
            ::canvas::tools::setRenderStateTransform(aLocalState, aTransform);

            if( ::rtl::math::approxEqual(mnAlpha, 1.0) )
            {
                // no further alpha changes necessary -> draw directly
                mpCanvas->getUNOCanvas()->drawBitmap( mxBufferBitmap,
                                                      mpCanvas->getViewState(),
                                                      aLocalState );
            }
            else
            {
                // add alpha modulation value to DeviceColor
                aLocalState.DeviceColor.realloc(4);
                aLocalState.DeviceColor[0] = 1.0;
                aLocalState.DeviceColor[1] = 1.0;
                aLocalState.DeviceColor[2] = 1.0;
                aLocalState.DeviceColor[3] = mnAlpha;
                mpCanvas->getUNOCanvas()->drawBitmapModulated( mxBufferBitmap,
                                                               mpCanvas->getViewState(),
                                                               aLocalState );
            }

            return true;
        }

    }
}
<|endoftext|>


<commit_before>/*************************************************************************
 *
 *  $RCSfile: transparencygroupaction.hxx,v $
 *
 *  $Revision: 1.4 $
 *
 *  last change: $Author: rt $ $Date: 2005-03-30 08:32:39 $
 *
 *  The Contents of this file are made available subject to the terms of
 *  either of the following licenses
 *
 *         - GNU Lesser General Public License Version 2.1
 *         - Sun Industry Standards Source License Version 1.1
 *
 *  Sun Microsystems Inc., October, 2000
 *
 *  GNU Lesser General Public License Version 2.1
 *  =============================================
 *  Copyright 2000 by Sun Microsystems, Inc.
 *  901 San Antonio Road, Palo Alto, CA 94303, USA
 *
 *  This library is free software; you can redistribute it and/or
 *  modify it under the terms of the GNU Lesser General Public
 *  License version 2.1, as published by the Free Software Foundation.
 *
 *  This library is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 *  Lesser General Public License for more details.
 *
 *  You should have received a copy of the GNU Lesser General Public
 *  License along with this library; if not, write to the Free Software
 *  Foundation, Inc., 59 Temple Place, Suite 330, Boston,
 *  MA  02111-1307  USA
 *
 *
 *  Sun Industry Standards Source License Version 1.1
 *  =================================================
 *  The contents of this file are subject to the Sun Industry Standards
 *  Source License Version 1.1 (the "License"); You may not use this file
 *  except in compliance with the License. You may obtain a copy of the
 *  License at http://www.openoffice.org/license.html.
 *
 *  Software provided under this License is provided on an "AS IS" basis,
 *  WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
 *  WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
 *  MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
 *  See the License for the specific provisions governing your rights and
 *  obligations concerning the Software.
 *
 *  The Initial Developer of the Original Code is: Sun Microsystems, Inc.
 *
 *  Copyright: 2000 by Sun Microsystems, Inc.
 *
 *  All Rights Reserved.
 *
 *  Contributor(s): _______________________________________
 *
 *
 ************************************************************************/

#ifndef _CPPCANVAS_TRANSPARENCYGROUPACTION_HXX
#define _CPPCANVAS_TRANSPARENCYGROUPACTION_HXX

#include <cppcanvas/canvas.hxx>
#include <cppcanvas/renderer.hxx>
#include <action.hxx>

#include <memory> // auto_ptr

class Point;
class Size;
class GDIMetaFile;
class Gradient;

/* Definition of internal::TransparencyGroupActionFactory class */

namespace cppcanvas
{
    namespace internal
    {
        struct OutDevState;

        typedef ::std::auto_ptr< GDIMetaFile >  MtfAutoPtr;
        typedef ::std::auto_ptr< Gradient >     GradientAutoPtr;

        /** Transparency group action.

            This action groups a bunch of other actions, to be
            rendered with the given transparency setting against the
            background.

            Creates encapsulated converters between GDIMetaFile and
            XCanvas. The Canvas argument is deliberately placed at the
            constructor, to force reconstruction of this object for a
            new canvas. This considerably eases internal state
            handling, since a lot of the internal state (e.g. fonts,
            text layout) is Canvas-dependent.
         */
        class TransparencyGroupActionFactory
        {
        public:
            /** Create new transparency group action.

                @param rGroupMtf
                Metafile that groups all actions to be rendered
                transparent

                @param rParms
                Render parameters

                @param rDstPoint
                Left, top edge of destination, in current state
                coordinate system

                @param rDstSize
                Size of the transparency group object, in current
                state coordinate system.

                @param nAlpha
                Alpha value, must be in the range [0,1]
             */
            static ActionSharedPtr createTransparencyGroupAction( MtfAutoPtr&                   rGroupMtf,
                                                                  const Renderer::Parameters&   rParms,
                                                                  const ::Point&                rDstPoint,
                                                                  const ::Size&                 rDstSize,
                                                                  double                        nAlpha,
                                                                  const CanvasSharedPtr&        rCanvas,
                                                                  const OutDevState&            rState );

            /** Create new transparency group action.

                @param rGroupMtf
                Metafile that groups all actions to be rendered
                transparent.

                @param rAlphaGradient
                VCL gradient, to be rendered into the action's alpha
                channel.

                @param rParms
                Render parameters

                @param rDstPoint
                Left, top edge of destination, in current state
                coordinate system

                @param rDstSize
                Size of the transparency group object, in current
                state coordinate system.
             */
            static ActionSharedPtr createTransparencyGroupAction( MtfAutoPtr&                   rGroupMtf,
                                                                  GradientAutoPtr&              rAlphaGradient,
                                                                  const Renderer::Parameters&   rParms,
                                                                  const ::Point&                rDstPoint,
                                                                  const ::Size&                 rDstSize,
                                                                  const CanvasSharedPtr&        rCanvas,
                                                                  const OutDevState&            rState );

        private:
            // static factory, disable big four
            TransparencyGroupActionFactory();
            ~TransparencyGroupActionFactory();
            TransparencyGroupActionFactory(const TransparencyGroupActionFactory&);
            TransparencyGroupActionFactory& operator=( const TransparencyGroupActionFactory& );
        };
    }
}

#endif /*_CPPCANVAS_TRANSPARENCYGROUPACTION_HXX */
<commit_msg>INTEGRATION: CWS ooo19126 (1.4.18); FILE MERGED 2005/09/05 18:41:00 rt 1.4.18.1: #i54170# Change license header: remove SISSL<commit_after>/*************************************************************************
 *
 *  OpenOffice.org - a multi-platform office productivity suite
 *
 *  $RCSfile: transparencygroupaction.hxx,v $
 *
 *  $Revision: 1.5 $
 *
 *  last change: $Author: rt $ $Date: 2005-09-08 08:23:12 $
 *
 *  The Contents of this file are made available subject to
 *  the terms of GNU Lesser General Public License Version 2.1.
 *
 *
 *    GNU Lesser General Public License Version 2.1
 *    =============================================
 *    Copyright 2005 by Sun Microsystems, Inc.
 *    901 San Antonio Road, Palo Alto, CA 94303, USA
 *
 *    This library is free software; you can redistribute it and/or
 *    modify it under the terms of the GNU Lesser General Public
 *    License version 2.1, as published by the Free Software Foundation.
 *
 *    This library is distributed in the hope that it will be useful,
 *    but WITHOUT ANY WARRANTY; without even the implied warranty of
 *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 *    Lesser General Public License for more details.
 *
 *    You should have received a copy of the GNU Lesser General Public
 *    License along with this library; if not, write to the Free Software
 *    Foundation, Inc., 59 Temple Place, Suite 330, Boston,
 *    MA  02111-1307  USA
 *
 ************************************************************************/

#ifndef _CPPCANVAS_TRANSPARENCYGROUPACTION_HXX
#define _CPPCANVAS_TRANSPARENCYGROUPACTION_HXX

#include <cppcanvas/canvas.hxx>
#include <cppcanvas/renderer.hxx>
#include <action.hxx>

#include <memory> // auto_ptr

class Point;
class Size;
class GDIMetaFile;
class Gradient;

/* Definition of internal::TransparencyGroupActionFactory class */

namespace cppcanvas
{
    namespace internal
    {
        struct OutDevState;

        typedef ::std::auto_ptr< GDIMetaFile >  MtfAutoPtr;
        typedef ::std::auto_ptr< Gradient >     GradientAutoPtr;

        /** Transparency group action.

            This action groups a bunch of other actions, to be
            rendered with the given transparency setting against the
            background.

            Creates encapsulated converters between GDIMetaFile and
            XCanvas. The Canvas argument is deliberately placed at the
            constructor, to force reconstruction of this object for a
            new canvas. This considerably eases internal state
            handling, since a lot of the internal state (e.g. fonts,
            text layout) is Canvas-dependent.
         */
        class TransparencyGroupActionFactory
        {
        public:
            /** Create new transparency group action.

                @param rGroupMtf
                Metafile that groups all actions to be rendered
                transparent

                @param rParms
                Render parameters

                @param rDstPoint
                Left, top edge of destination, in current state
                coordinate system

                @param rDstSize
                Size of the transparency group object, in current
                state coordinate system.

                @param nAlpha
                Alpha value, must be in the range [0,1]
             */
            static ActionSharedPtr createTransparencyGroupAction( MtfAutoPtr&                   rGroupMtf,
                                                                  const Renderer::Parameters&   rParms,
                                                                  const ::Point&                rDstPoint,
                                                                  const ::Size&                 rDstSize,
                                                                  double                        nAlpha,
                                                                  const CanvasSharedPtr&        rCanvas,
                                                                  const OutDevState&            rState );

            /** Create new transparency group action.

                @param rGroupMtf
                Metafile that groups all actions to be rendered
                transparent.

                @param rAlphaGradient
                VCL gradient, to be rendered into the action's alpha
                channel.

                @param rParms
                Render parameters

                @param rDstPoint
                Left, top edge of destination, in current state
                coordinate system

                @param rDstSize
                Size of the transparency group object, in current
                state coordinate system.
             */
            static ActionSharedPtr createTransparencyGroupAction( MtfAutoPtr&                   rGroupMtf,
                                                                  GradientAutoPtr&              rAlphaGradient,
                                                                  const Renderer::Parameters&   rParms,
                                                                  const ::Point&                rDstPoint,
                                                                  const ::Size&                 rDstSize,
                                                                  const CanvasSharedPtr&        rCanvas,
                                                                  const OutDevState&            rState );

        private:
            // static factory, disable big four
            TransparencyGroupActionFactory();
            ~TransparencyGroupActionFactory();
            TransparencyGroupActionFactory(const TransparencyGroupActionFactory&);
            TransparencyGroupActionFactory& operator=( const TransparencyGroupActionFactory& );
        };
    }
}

#endif /*_CPPCANVAS_TRANSPARENCYGROUPACTION_HXX */
<|endoftext|>


<commit_before>/**-------------------------------------------------------------------------
@file	mag_bmm150.cpp

@brief	Implementation of BOSCH BMM150 mag sensor

@author	Hoang Nguyen Hoan
@date	Aug. 23, 2019

@license

MIT License

Copyright (c) 2019 I-SYST inc. All rights reserved.

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.

----------------------------------------------------------------------------*/

#include <stdint.h>

#include "idelay.h"
#include "sensors/mag_bmm150.h"

/**
 * @brief	Initialize mag sensor.
 *
 * @param 	Cfg		: Configuration data
 * @param 	pIntrf	: Pointer to communication interface
 * @param 	pTimer	: Pointer to Timer use for time stamp
 *
 * @return	true - Success
 */
bool MagBmm150::Init(const MAGSENSOR_CFG &Cfg, DeviceIntrf * const pIntrf, Timer * const pTimer)
{
	MagSensor::Type(SENSOR_TYPE_MAG);

	//vData.Range = Range(((1<<15) - 1) >> 1);
	//vData.Scale = 2500;

	uint8_t regaddr = BMM150_CTRL1_REG;
	uint8_t d = BMM150_CTRL1_POWER_ON | BMM150_CTRL1_SOFT_RESET | BMM150_CTRL1_SOFT_RESET2;

	// use this way to allow hook up on the secondary interface of a combo device
	MagBmm150::Write(&regaddr, 1, &d, 1);

	msDelay(10);

	regaddr = BMM150_CHIP_ID_REG;
	MagBmm150::Read(&regaddr, 1, &d, 1);

	if (d != BMM150_CHIP_ID)
	{
		return false;
	}

	// There is no setting to change precision
	// fix it to lowest value.
	// X, Y : 13 bits, Z : 15 bits, RHALL : 14 bits
	vPrecision = MAGSENSOR_PRECISION_LOW;
	vSensitivity[0] = BMI150_FLUX_DENSITY_XY / BMI150_ADC_RANGE_XY;
	vSensitivity[1] = vSensitivity[0];
	vSensitivity[2] = BMI150_FLUX_DENSITY_Z / BMI150_ADC_RANGE_Z;

	vRange = BMI150_ADC_RANGE_XY;
	vData.Sensitivity[0] = vSensitivity[0];
	vData.Sensitivity[1] = vSensitivity[1];
	vData.Sensitivity[2] = vSensitivity[2];

	ClearCalibration();

	SamplingFrequency(Cfg.Freq);

	Enable();

	return true;
}

uint32_t MagBmm150::SamplingFrequency(uint32_t Freq)
{
	uint8_t regaddr = BMM150_CTRL2_REG;
	uint8_t d;
	uint32_t f = 0;

	MagBmm150::Read(&regaddr, 1, &d, 1);

	d &= ~BMM150_CTRL2_ODR_MASK;

	if (Freq < 6000)
	{
		f = 2000;
		d |= BMM150_CTRL2_ODR_2HZ;
	}
	else if (Freq < 8000)
	{
		f = 6000;
		d |= BMM150_CTRL2_ODR_6HZ;
	}
	else if (Freq < 10000)
	{
		f = 8000;
		d |= BMM150_CTRL2_ODR_8HZ;
	}
	else if (Freq < 15000)
	{
		f = 10000;
		d |= BMM150_CTRL2_ODR_10HZ;
	}
	else if (Freq < 20000)
	{
		f = 15000;
		d |= BMM150_CTRL2_ODR_15HZ;
	}
	else if (Freq < 25000)
	{
		f = 20000;
		d |= BMM150_CTRL2_ODR_20HZ;
	}
	else if (Freq < 30000)
	{
		f = 25000;
		d |= BMM150_CTRL2_ODR_25HZ;
	}
	else
	{
		f = 30000;
		d |= BMM150_CTRL2_ODR_30HZ;
	}

	MagBmm150::Write(&regaddr, 1, &d, 1);

	return Sensor::SamplingFrequency(f);
}

bool MagBmm150::Enable()
{
	uint8_t regaddr = BMM150_CTRL2_REG;
	uint8_t d;

	MagBmm150::Read(&regaddr, 1, &d, 1);
	d &= ~(BMM150_CTRL2_OPMODE_MASK | BMM150_CTRL2_SELFTEST);
	d |= BMM150_CTRL2_OPMODE_NORMAL;
	MagBmm150::Write(&regaddr, 1, &d, 1);

	msDelay(10);

	regaddr = BMM150_CTRL3_REG;
	MagBmm150::Read(&regaddr, 1, &d, 1);

	d &= ~(BMM150_CTRL3_CHAN_X_DIS | BMM150_CTRL3_CHAN_Y_DIS | BMM150_CTRL3_CHAN_Y_DIS);
	MagBmm150::Write(&regaddr, 1, &d, 1);

	return true;
}

void MagBmm150::Disable()
{
	uint8_t regaddr = BMM150_CTRL3_REG;
	uint8_t d;

	MagBmm150::Read(&regaddr, 1, &d, 1);

	d |= (BMM150_CTRL3_CHAN_X_DIS | BMM150_CTRL3_CHAN_Y_DIS | BMM150_CTRL3_CHAN_Y_DIS);
	MagBmm150::Write(&regaddr, 1, &d, 1);

	MagBmm150::Read(&regaddr, 1, &d, 1);
	d &= ~BMM150_CTRL2_OPMODE_MASK;
	d |= BMM150_CTRL2_OPMODE_SLEEP;
	MagBmm150::Write(&regaddr, 1, &d, 1);
}

void MagBmm150::Reset()
{
	uint8_t regaddr = BMM150_CTRL1_REG;
	uint8_t d;

	MagBmm150::Read(&regaddr, 1, &d, 1);

	d |= BMM150_CTRL1_SOFT_RESET;
	MagBmm150::Write(&regaddr, 1, &d, 1);

	msDelay(1);

	//d |= BMM150_CTRL1_POWER_ON;
	//MagBmm150::Write(&regaddr, 1, &d, 1);
}

bool MagBmm150::UpdateData()
{
	uint8_t regaddr = BMM150_INT_STATUS_REG;
	uint8_t d = 0;
	bool res = false;

	MagBmm150::Read(&regaddr, 1, &d, 1);
	if (d)
	{
		int16_t buff[4];
		regaddr = BMM150_DATA_X_LSB_REG;

		if (vpTimer)
		{
			vData.Timestamp = vpTimer->uSecond();
		}
		MagBmm150::Read(&regaddr, 1, (uint8_t*)buff, 8);

		vData.X = buff[0] >> 3;
		vData.Y = buff[1] >> 3;
		vData.Z = buff[2] >> 1;

		res = true;
	}

	return res;
}
<commit_msg>Missing register address<commit_after>/**-------------------------------------------------------------------------
@file	mag_bmm150.cpp

@brief	Implementation of BOSCH BMM150 mag sensor

@author	Hoang Nguyen Hoan
@date	Aug. 23, 2019

@license

MIT License

Copyright (c) 2019 I-SYST inc. All rights reserved.

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.

----------------------------------------------------------------------------*/

#include <stdint.h>

#include "idelay.h"
#include "sensors/mag_bmm150.h"

/**
 * @brief	Initialize mag sensor.
 *
 * @param 	Cfg		: Configuration data
 * @param 	pIntrf	: Pointer to communication interface
 * @param 	pTimer	: Pointer to Timer use for time stamp
 *
 * @return	true - Success
 */
bool MagBmm150::Init(const MAGSENSOR_CFG &Cfg, DeviceIntrf * const pIntrf, Timer * const pTimer)
{
	MagSensor::Type(SENSOR_TYPE_MAG);

	//vData.Range = Range(((1<<15) - 1) >> 1);
	//vData.Scale = 2500;

	uint8_t regaddr = BMM150_CTRL1_REG;
	uint8_t d = BMM150_CTRL1_POWER_ON | BMM150_CTRL1_SOFT_RESET | BMM150_CTRL1_SOFT_RESET2;

	// use this way to allow hook up on the secondary interface of a combo device
	MagBmm150::Write(&regaddr, 1, &d, 1);

	msDelay(10);

	regaddr = BMM150_CHIP_ID_REG;
	MagBmm150::Read(&regaddr, 1, &d, 1);

	if (d != BMM150_CHIP_ID)
	{
		return false;
	}

	// There is no setting to change precision
	// fix it to lowest value.
	// X, Y : 13 bits, Z : 15 bits, RHALL : 14 bits
	vPrecision = MAGSENSOR_PRECISION_LOW;
	vSensitivity[0] = BMI150_FLUX_DENSITY_XY / BMI150_ADC_RANGE_XY;
	vSensitivity[1] = vSensitivity[0];
	vSensitivity[2] = BMI150_FLUX_DENSITY_Z / BMI150_ADC_RANGE_Z;

	vRange = BMI150_ADC_RANGE_XY;
	vData.Sensitivity[0] = vSensitivity[0];
	vData.Sensitivity[1] = vSensitivity[1];
	vData.Sensitivity[2] = vSensitivity[2];

	ClearCalibration();

	SamplingFrequency(Cfg.Freq);

	Enable();

	return true;
}

uint32_t MagBmm150::SamplingFrequency(uint32_t Freq)
{
	uint8_t regaddr = BMM150_CTRL2_REG;
	uint8_t d;
	uint32_t f = 0;

	MagBmm150::Read(&regaddr, 1, &d, 1);

	d &= ~BMM150_CTRL2_ODR_MASK;

	if (Freq < 6000)
	{
		f = 2000;
		d |= BMM150_CTRL2_ODR_2HZ;
	}
	else if (Freq < 8000)
	{
		f = 6000;
		d |= BMM150_CTRL2_ODR_6HZ;
	}
	else if (Freq < 10000)
	{
		f = 8000;
		d |= BMM150_CTRL2_ODR_8HZ;
	}
	else if (Freq < 15000)
	{
		f = 10000;
		d |= BMM150_CTRL2_ODR_10HZ;
	}
	else if (Freq < 20000)
	{
		f = 15000;
		d |= BMM150_CTRL2_ODR_15HZ;
	}
	else if (Freq < 25000)
	{
		f = 20000;
		d |= BMM150_CTRL2_ODR_20HZ;
	}
	else if (Freq < 30000)
	{
		f = 25000;
		d |= BMM150_CTRL2_ODR_25HZ;
	}
	else
	{
		f = 30000;
		d |= BMM150_CTRL2_ODR_30HZ;
	}

	MagBmm150::Write(&regaddr, 1, &d, 1);

	return Sensor::SamplingFrequency(f);
}

bool MagBmm150::Enable()
{
	uint8_t regaddr = BMM150_CTRL2_REG;
	uint8_t d;

	MagBmm150::Read(&regaddr, 1, &d, 1);
	d &= ~(BMM150_CTRL2_OPMODE_MASK | BMM150_CTRL2_SELFTEST);
	d |= BMM150_CTRL2_OPMODE_NORMAL;
	MagBmm150::Write(&regaddr, 1, &d, 1);

	msDelay(10);

	regaddr = BMM150_CTRL3_REG;
	MagBmm150::Read(&regaddr, 1, &d, 1);

	d &= ~(BMM150_CTRL3_CHAN_X_DIS | BMM150_CTRL3_CHAN_Y_DIS | BMM150_CTRL3_CHAN_Y_DIS);
	MagBmm150::Write(&regaddr, 1, &d, 1);

	return true;
}

void MagBmm150::Disable()
{
	uint8_t regaddr = BMM150_CTRL3_REG;
	uint8_t d;

	MagBmm150::Read(&regaddr, 1, &d, 1);

	d |= (BMM150_CTRL3_CHAN_X_DIS | BMM150_CTRL3_CHAN_Y_DIS | BMM150_CTRL3_CHAN_Y_DIS);
	MagBmm150::Write(&regaddr, 1, &d, 1);

	regaddr = BMM150_CTRL2_REG;
	MagBmm150::Read(&regaddr, 1, &d, 1);
	d &= ~BMM150_CTRL2_OPMODE_MASK;
	d |= BMM150_CTRL2_OPMODE_SLEEP;
	MagBmm150::Write(&regaddr, 1, &d, 1);
}

void MagBmm150::Reset()
{
	uint8_t regaddr = BMM150_CTRL1_REG;
	uint8_t d;

	MagBmm150::Read(&regaddr, 1, &d, 1);

	d |= BMM150_CTRL1_SOFT_RESET;
	MagBmm150::Write(&regaddr, 1, &d, 1);

	msDelay(1);

	//d |= BMM150_CTRL1_POWER_ON;
	//MagBmm150::Write(&regaddr, 1, &d, 1);
}

bool MagBmm150::UpdateData()
{
	uint8_t regaddr = BMM150_INT_STATUS_REG;
	uint8_t d = 0;
	bool res = false;

	MagBmm150::Read(&regaddr, 1, &d, 1);
	if (d)
	{
		int16_t buff[4];
		regaddr = BMM150_DATA_X_LSB_REG;

		if (vpTimer)
		{
			vData.Timestamp = vpTimer->uSecond();
		}
		MagBmm150::Read(&regaddr, 1, (uint8_t*)buff, 8);

		vData.X = buff[0] >> 3;
		vData.Y = buff[1] >> 3;
		vData.Z = buff[2] >> 1;

		res = true;
	}

	return res;
}
<|endoftext|>