[Merge] lp:~mandel/location-service/espoo-provider into lp:location-service
Ricardo Mendoza
ricardo.mendoza at canonical.com
Tue Aug 26 10:15:55 UTC 2014
Typo in method definition
Diff comments:
> === modified file 'data/ubuntu-location-service.conf.in'
> --- data/ubuntu-location-service.conf.in 2013-10-15 16:02:00 +0000
> +++ data/ubuntu-location-service.conf.in 2014-08-26 10:03:22 +0000
> @@ -4,4 +4,4 @@
>
> respawn
>
> -exec /usr/bin/ubuntu-location-serviced --bus system --provider gps::Provider
> +exec /usr/bin/ubuntu-location-serviced --bus system --provider gps::Provider --provider remote::Provider --remote::Provider::name="com.ubuntu.espoo.Service.Provider" --remote::Provider::path="/com/ubuntu/espoo/Service/Provider"
>
> === modified file 'debian/changelog'
> --- debian/changelog 2014-08-18 08:11:55 +0000
> +++ debian/changelog 2014-08-26 10:03:22 +0000
> @@ -1,3 +1,8 @@
> +location-service (2.1) UNRELEASED; urgency=medium
> +
> + * Add a new provider for the remote project.
> +
> + -- Manuel de la Pena <manuel.delapena at canonical.com> Tue, 19 Aug 2014 11:54:49 +0000
> location-service (2.0.1+14.10.20140818-0ubuntu1) utopic; urgency=low
>
> [ thomas-voss ]
>
> === modified file 'src/location_service/com/ubuntu/location/providers/CMakeLists.txt'
> --- src/location_service/com/ubuntu/location/providers/CMakeLists.txt 2014-02-07 17:16:49 +0000
> +++ src/location_service/com/ubuntu/location/providers/CMakeLists.txt 2014-08-26 10:03:22 +0000
> @@ -1,4 +1,5 @@
> add_subdirectory(dummy)
> +add_subdirectory(remote)
> add_subdirectory(geoclue)
> add_subdirectory(gps)
> add_subdirectory(skyhook)
>
> === modified file 'src/location_service/com/ubuntu/location/providers/config.cpp'
> --- src/location_service/com/ubuntu/location/providers/config.cpp 2014-05-19 09:55:25 +0000
> +++ src/location_service/com/ubuntu/location/providers/config.cpp 2014-08-26 10:03:22 +0000
> @@ -68,3 +68,11 @@
> };
> #endif // COM_UBUNTU_LOCATION_SERVICE_PROVIDERS_SKYHOOK
>
> +#if defined(COM_UBUNTU_LOCATION_SERVICE_PROVIDERS_REMOTE)
> +#include <com/ubuntu/location/providers/remote/provider.h>
> +static FactoryInjector remote_injector
> +{
> + "remote::Provider",
> + com::ubuntu::location::providers::remote::Provider::create_instance
> +};
> +#endif // COM_UBUNTU_LOCATION_SERVICE_PROVIDERS_REMOTE
>
> === modified file 'src/location_service/com/ubuntu/location/providers/geoclue/CMakeLists.txt'
> --- src/location_service/com/ubuntu/location/providers/geoclue/CMakeLists.txt 2014-01-20 13:03:19 +0000
> +++ src/location_service/com/ubuntu/location/providers/geoclue/CMakeLists.txt 2014-08-26 10:03:22 +0000
> @@ -9,10 +9,10 @@
> message(STATUS "Enabling support for Geoclue location providers")
>
> add_library(geoclue provider.cpp)
> -
> +
> set(
> ENABLED_PROVIDER_TARGETS
> - ${ENABLED_PROVIDER_TARGETS} geoclue
> + ${ENABLED_PROVIDER_TARGETS} geoclue
> PARENT_SCOPE
> )
>
>
> === added directory 'src/location_service/com/ubuntu/location/providers/remote'
> === added file 'src/location_service/com/ubuntu/location/providers/remote/CMakeLists.txt'
> --- src/location_service/com/ubuntu/location/providers/remote/CMakeLists.txt 1970-01-01 00:00:00 +0000
> +++ src/location_service/com/ubuntu/location/providers/remote/CMakeLists.txt 2014-08-26 10:03:22 +0000
> @@ -0,0 +1,37 @@
> +option(
> + LOCATION_SERVICE_ENABLE_REMOTE_PROVIDER
> + "Enable location provider relying on the remote provider SDK"
> + ON
> +)
> +
> +if (LOCATION_SERVICE_ENABLE_REMOTE_PROVIDER)
> +
> + message(STATUS "Enabling support for the remote location providers")
> +
> + set(REMOTE_SOURCES
> + provider.cpp
> + )
> +
> + set(REMOTE_HEADERS
> + remote_interface.h
> + provider.h
> + )
> +
> + add_library(remote
> + ${REMOTE_HEADERS}
> + ${REMOTE_SOURCES}
> + )
> +
> + set(
> + ENABLED_PROVIDER_TARGETS
> + ${ENABLED_PROVIDER_TARGETS} remote
> + PARENT_SCOPE
> + )
> +
> + set(
> + ENABLED_PROVIDER_TARGETS_DEFINITIONS
> + -DCOM_UBUNTU_LOCATION_SERVICE_PROVIDERS_REMOTE ${ENABLED_PROVIDER_TARGETS_DEFINITIONS}
> + PARENT_SCOPE
> + )
> +
> +endif (LOCATION_SERVICE_ENABLE_REMOTE_PROVIDER)
>
> === added file 'src/location_service/com/ubuntu/location/providers/remote/provider.cpp'
> --- src/location_service/com/ubuntu/location/providers/remote/provider.cpp 1970-01-01 00:00:00 +0000
> +++ src/location_service/com/ubuntu/location/providers/remote/provider.cpp 2014-08-26 10:03:22 +0000
> @@ -0,0 +1,156 @@
> +/*
> + * Copyright © 2012-2013 Canonical Ltd.
> + *
> + * This program is free software: you can redistribute it and/or modify it
> + * under the terms of the GNU Lesser General Public License version 3,
> + * as published by the Free Software Foundation.
> + *
> + * This program 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 program. If not, see <http://www.gnu.org/licenses/>.
> + *
> + * Authored by: Thomas Voß <thomas.voss at canonical.com>
> + */
> +#include <com/ubuntu/location/providers/remote/provider.h>
> +
> +#include <com/ubuntu/location/logging.h>
> +
> +#include <core/dbus/object.h>
> +#include <core/dbus/signal.h>
> +#include <core/dbus/asio/executor.h>
> +
> +#include <thread>
> +
> +namespace cul = com::ubuntu::location;
> +namespace culpr = com::ubuntu::location::providers::remote;
> +
> +namespace dbus = core::dbus;
> +
> +namespace
> +{
> +dbus::Bus::Ptr the_system_bus()
> +{
> + static dbus::Bus::Ptr system_bus = std::make_shared<dbus::Bus>(dbus::WellKnownBus::system);
> + return system_bus;
> +}
> +}
> +
> +struct culpr::Provider::Private
> +{
> + typedef core::dbus::Signal<
> + com::ubuntu::remote::RemoteInterface::Signals::PositionChanged,
> + com::ubuntu::remote::RemoteInterface::Signals::PositionChanged::ArgumentType
> + > PositionChanged;
> +
> + Private(const culpr::Provider::Configuration& config)
> + : bus(the_system_bus()),
> + service(dbus::Service::use_service(bus, config.name)),
> + object(service->object_for_path(config.path)),
> + signal_position_changed(object->get_signal<com::ubuntu::remote::RemoteInterface::Signals::PositionChanged>())
> + {
> + }
> +
> + void start()
> + {
> + VLOG(10) << __PRETTY_FUNCTION__;
> + bus->install_executor(core::dbus::asio::make_executor(bus));
> + if (!worker.joinable())
> + worker = std::move(std::thread{std::bind(&dbus::Bus::run, bus)});
> + }
> +
> + void stop()
> + {
> + VLOG(10) << __PRETTY_FUNCTION__;
> + try
> + {
> + bus->stop();
> + }
> + catch(...)
> + {
> + // can happen if the start method was not called
> + VLOG(10) << "Stopping not started remote provider.";
> + }
> +
> + if (worker.joinable())
> + worker.join();
> + }
> +
> + dbus::Bus::Ptr bus;
> + dbus::Service::Ptr service;
> + dbus::Object::Ptr object;
> + PositionChanged::Ptr signal_position_changed;
> + PositionChanged::SubscriptionToken position_updates_connection;
> +
> + std::thread worker;
> +};
> +
> +std::string culpr::Provider::class_name()
> +{
> + return "remote::Provider";
> +}
> +
> +cul::Provider::Ptr culpr::Provider::create_instance(const cul::ProviderFactory::Configuration& config)
> +{
> + culpr::Provider::Configuration pConfig;
> + pConfig.name = config.count(Configuration::key_name()) > 0 ? config.get<std::string>(Configuration::key_name()) : throw std::runtime_error("Missing bus-name");
> + pConfig.path = config.count(Configuration::key_path()) > 0 ? config.get<std::string>(Configuration::key_path()) : throw std::runtime_error("Missing bus-path");
> + return cul::Provider::Ptr{new culpr::Provider{pConfig}};
> +}
> +
> +culpr::Provider::Provider(const culpr::Provider::Configuration& config)
> + : com::ubuntu::location::Provider(config.features, config.requirements),
> + d(new Private(config))
> +{
> + d->position_updates_connection =
> + d->signal_position_changed->connect(
> + [this](const com::ubuntu::remote::RemoteInterface::Signals::PositionChanged::ArgumentType& arg)
> + {
> + this->on_position_changed(arg);
> + });
> +}
> +
> +culpr::Provider::~Provider() noexcept
> +{
> + d->stop();
> +}
> +
> +void culpr::Provider::on_position_changed(const com::ubuntu::remote::RemoteInterface::Signals::PositionChanged::ArgumentType& arg)
> +{
> + auto longitude = std::get<0>(arg);
> + auto latitude = std::get<1>(arg);
> + auto altitude = std::get<2>(arg);
> + VLOG(10) << "New update received with longitude: " << longitude
> + << "latitude: " << latitude << "altitude: " << altitude;
> +
> + cul::Position pos
> + {
> + cul::wgs84::Latitude{latitude* cul::units::Degrees},
> + cul::wgs84::Longitude{longitude* cul::units::Degrees}
> + };
> +
> + pos.altitude = cul::wgs84::Altitude{altitude* cul::units::Meters};
> + cul::Update<cul::Position> update(pos);
> + VLOG(10) << "Position updated added";
> + mutable_updates().position(update);
> +}
> +
> +bool culpr::Provider::matches_criteria(const cul::Criteria&)
> +{
> + return true;
> +}
> +
> +void culpr::Provider::start_position_updates()
> +{
> + VLOG(10) << "Starting remote provider\n";
> + d->start();
> +}
> +
> +void culpr::Provider::stop_position_updates()
> +{
> + VLOG(10) << "Stopping remote provider\n";
> + d->stop();
> +}
>
> === added file 'src/location_service/com/ubuntu/location/providers/remote/provider.h'
> --- src/location_service/com/ubuntu/location/providers/remote/provider.h 1970-01-01 00:00:00 +0000
> +++ src/location_service/com/ubuntu/location/providers/remote/provider.h 2014-08-26 10:03:22 +0000
> @@ -0,0 +1,80 @@
> +/*
> + * Copyright © 2012-2013 Canonical Ltd.
> + *
> + * This program is free software: you can redistribute it and/or modify it
> + * under the terms of the GNU Lesser General Public License version 3,
> + * as published by the Free Software Foundation.
> + *
> + * This program 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 program. If not, see <http://www.gnu.org/licenses/>.
> + *
> + * Authored by: Thomas Voß <thomas.voss at canonical.com>
> + */
> +#ifndef LOCATION_SERVICE_COM_UBUNTU_LOCATION_PROVIDERS_ESPOO_PROVIDER_H_
> +#define LOCATION_SERVICE_COM_UBUNTU_LOCATION_PROVIDERS_ESPOO_PROVIDER_H_
> +
> +#include <com/ubuntu/location/provider.h>
> +#include <com/ubuntu/location/provider_factory.h>
> +#include <com/ubuntu/location/providers/remote/remote_interface.h>
> +
> +namespace com
> +{
> +namespace ubuntu
> +{
> +namespace location
> +{
> +namespace providers
> +{
> +namespace remote
> +{
> +
> +class Provider : public com::ubuntu::location::Provider
> +{
> + public:
> + // For integration with the Provider factory.
> + static std::string class_name();
> +
> + // Instantiates a new provider instance, populating the configuration object
> + // from the provided property bundle.
> + static Provider::Ptr create_instance(const ProviderFactory::Configuration&);
> +
> + // structure that represents the configuration used in the remote provider
> + struct Configuration
> + {
> + static std::string key_name() { return "name"; }
> + static std::string key_path() { return "path"; }
> + std::string name;
> + std::string path;
> +
> + Provider::Features features = Provider::Features::position;
> + Provider::Requirements requirements = Provider::Requirements::cell_network |
> + Provider::Requirements::data_network | Provider::Requirements::monetary_spending;
> + };
> +
> + Provider(const Configuration& config);
> + ~Provider() noexcept;
> +
> + virtual bool matches_criteria(const Criteria&);
> +
> + virtual void start_position_updates();
> + virtual void stop_position_updates();
> +
> + protected:
> + void on_position_changed(const com::ubuntu::remote::RemoteInterface::Signals::PositionChanged::ArgumentType& arg);
> +
> + private:
> + struct Private;
> + std::unique_ptr<Private> d;
> +};
> +
> +} // remote
> +} // providers
> +} // location
> +} // ubuntu
> +} // com
> +#endif // LOCATION_SERVICE_COM_UBUNTU_LOCATION_PROVIDERS_GEOCLUE_PROVIDER_H_
>
> === added file 'src/location_service/com/ubuntu/location/providers/remote/remote_interface.h'
> --- src/location_service/com/ubuntu/location/providers/remote/remote_interface.h 1970-01-01 00:00:00 +0000
> +++ src/location_service/com/ubuntu/location/providers/remote/remote_interface.h 2014-08-26 10:03:22 +0000
> @@ -0,0 +1,108 @@
> +/*
> + * Copyright © 2014 Canonical Ltd.
> + *
> + * This program is free software: you can redistribute it and/or modify it
> + * under the terms of the GNU Lesser General Public License version 3,
> + * as published by the Free Software Foundation.
> + *
> + * This program 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 program. If not, see <http://www.gnu.org/licenses/>.
> + *
> + * Authored by: Manuel de la Pena <manuel.delapena at canonical.com>
> + */
> +
> +#ifndef CORE_UBUNTU_ESPOO_PROVIDER_P_H_
> +#define CORE_UBUNTU_ESPOO_PROVIDER_P_H_
> +
> +#include <core/dbus/macros.h>
> +#include <core/dbus/traits/service.h>
> +
> +namespace com
> +{
> +namespace ubuntu
> +{
> +namespace remote
> +{
> +struct RemoteInterface
> +{
> +
> + static const std::string& name()
> + {
> + static const std::string s{"com.ubuntu.remote.Service.Provider"};
> + return s;
> + }
> +
> + DBUS_CPP_METHOD_DEF(StartPositionUpdates, RemoteInterface)
> + DBUS_CPP_METHOD_DEF(StopPositionUpdates, RemoteInterface)
> + DBUS_CPP_METHOD_DEF(StartHeadingUpdates, RemoteInterface)
> + DBUS_CPP_METHOD_DEF(StopHeadingUpdates, RemoteInterface)
> + DBUS_CPP_METHOD_DEF(StartVelocityUpdates, RemoteInterface)
> + DBUS_CPP_METHOD_DEF(StopvVelocityUpdates, RemoteInterface)
Typo
> +
> + struct Signals
> + {
> + struct PositionChanged
> + {
> + inline static std::string name()
> + {
> + return "PositionChanged";
> + };
> + typedef RemoteInterface Interface;
> + typedef std::tuple<double, double, double, double, uint32_t> ArgumentType;
> + };
> +
> + DBUS_CPP_SIGNAL_DEF(HeadingChanged, RemoteInterface, double)
> + DBUS_CPP_SIGNAL_DEF(VelocityChanged, RemoteInterface, double)
> + };
> +
> + struct Properties
> + {
> + DBUS_CPP_READABLE_PROPERTY_DEF(HasPosition, RemoteInterface, bool)
> + DBUS_CPP_READABLE_PROPERTY_DEF(HasVelocity, RemoteInterface, bool)
> + DBUS_CPP_READABLE_PROPERTY_DEF(HasHeading, RemoteInterface, bool)
> + DBUS_CPP_READABLE_PROPERTY_DEF(RequiresSatellites, RemoteInterface, bool)
> + DBUS_CPP_READABLE_PROPERTY_DEF(RequiresCellNetwork, RemoteInterface, bool)
> + DBUS_CPP_READABLE_PROPERTY_DEF(RequiresDataNetwork, RemoteInterface, bool)
> + DBUS_CPP_READABLE_PROPERTY_DEF(RequiresMonetarySpending, RemoteInterface, bool)
> + DBUS_CPP_READABLE_PROPERTY_DEF(ArePositionUpdatesRunning, RemoteInterface, bool)
> + DBUS_CPP_READABLE_PROPERTY_DEF(AreHeadingUpdatesRunning, RemoteInterface, bool)
> + DBUS_CPP_READABLE_PROPERTY_DEF(AreVelocityUpdatesRunning, RemoteInterface, bool)
> + };
> +
> +};
> +} // remote
> +} // ubuntu
> +} // core
> +
> +namespace core
> +{
> +namespace dbus
> +{
> +namespace traits
> +{
> +template<>
> +struct Service<com::ubuntu::remote::RemoteInterface>
> +{
> + static const std::string& interface_name()
> + {
> + static const std::string s{"com.ubuntu.espoo.Service.Provider"};
> + return s;
> + }
> +
> + inline static const std::string& object_path()
> + {
> + static const std::string s{"/com/ubuntu/espoo/Service/Provider"};
> + return s;
> + }
> +
> +};
> +}
> +}
> +}
> +
> +#endif
>
> === modified file 'tests/CMakeLists.txt'
> --- tests/CMakeLists.txt 2014-08-13 13:08:22 +0000
> +++ tests/CMakeLists.txt 2014-08-26 10:03:22 +0000
> @@ -116,3 +116,24 @@
> add_test(geoclue_provider_test ${CMAKE_CURRENT_BINARY_DIR}/geoclue_provider_test)
> endif (LOCATION_SERVICE_ENABLE_DBUS_TEST_RUNNER)
> endif (LOCATION_SERVICE_ENABLE_GEOCLUE_PROVIDERS)
> +
> +if (LOCATION_SERVICE_ENABLE_REMOTE_PROVIDER)
> + add_executable(remote_provider_test remote_provider_test.cpp)
> + target_link_libraries(
> + remote_provider_test
> +
> + ubuntu-location-service
> +
> + ${CMAKE_THREAD_LIBS_INIT}
> + ${Boost_LIBRARIES}
> + ${PROCESS_CPP_LIBRARIES}
> + ${ARGN}
> +
> + gmock
> +
> + gtest
> + gtest_main
> + )
> +
> + add_test(remote_provider_test ${CMAKE_CURRENT_BINARY_DIR}/remote_provider_test)
> +endif (LOCATION_SERVICE_ENABLE_REMOTE_PROVIDER)
>
> === added file 'tests/remote_provider_test.cpp'
> --- tests/remote_provider_test.cpp 1970-01-01 00:00:00 +0000
> +++ tests/remote_provider_test.cpp 2014-08-26 10:03:22 +0000
> @@ -0,0 +1,100 @@
> +/*
> + * Copyright © 2012-2013 Canonical Ltd.
> + *
> + * This program is free software: you can redistribute it and/or modify it
> + * under the terms of the GNU Lesser General Public License version 3,
> + * as published by the Free Software Foundation.
> + *
> + * This program 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 program. If not, see <http://www.gnu.org/licenses/>.
> + *
> + * Authored by: Manuel de la Peña <manuel.delapena at canonical.com>
> + */
> +
> +#include <com/ubuntu/location/provider.h>
> +#include <com/ubuntu/location/proxy_provider.h>
> +#include <com/ubuntu/location/providers/remote/provider.h>
> +
> +#include <gmock/gmock.h>
> +#include <gtest/gtest.h>
> +
> +namespace cul = com::ubuntu::location;
> +namespace remote = com::ubuntu::location::providers::remote;
> +
> +using namespace ::testing;
> +
> +
> +MATCHER_P(postion_equals_tuple, value, "Returns if the string maps are equal.") {
> + auto tuple = static_cast<std::tuple<double, double, double, double, uint32_t> >(value);
> + auto pos = static_cast<cul::Update<cul::Position> >(arg).value;
> +
> + // convert the tuple to the correct units
> + cul::wgs84::Longitude longitude {std::get<0>(tuple)* cul::units::Degrees};
> + cul::wgs84::Latitude latitude {std::get<1>(tuple)* cul::units::Degrees};
> + cul::wgs84::Altitude altitude {std::get<2>(tuple)* cul::units::Meters};
> +
> + return longitude == pos.longitude && latitude == pos.latitude && altitude == pos.altitude;
> +}
> +
> +class DummyProvider : public remote::Provider
> +{
> + public:
> + DummyProvider(const Configuration& config) : remote::Provider(config)
> + {
> + }
> +
> + using remote::Provider::on_position_changed;
> +};
> +
> +class MockEventConsumer
> +{
> + public:
> + MockEventConsumer() {}
> +
> + MOCK_METHOD1(on_new_position, void(const cul::Update<cul::Position>&));
> +};
> +
> +TEST(RemoteProvider, matches_criteria)
> +{
> + auto conf = remote::Provider::Configuration{};
> + conf.name = "com.ubuntu.espoo.Service.Provider";
> + conf.path = "/com/ubuntu/espoo/Service/Provider";
> +
> + DummyProvider provider(conf);
> +
> + EXPECT_FALSE(provider.requires(com::ubuntu::location::Provider::Requirements::satellites));
> + EXPECT_TRUE(provider.requires(com::ubuntu::location::Provider::Requirements::cell_network));
> + EXPECT_TRUE(provider.requires(com::ubuntu::location::Provider::Requirements::data_network));
> + EXPECT_TRUE(provider.requires(com::ubuntu::location::Provider::Requirements::monetary_spending));
> +}
> +
> +TEST(RemoteProvider, updates_are_fwd)
> +{
> + // update received from the remote provider in a tuple
> + std::tuple<double, double, double, double, uint32_t> update{3, 4, 4, 4, 0};
> +
> + auto conf = remote::Provider::Configuration{};
> + conf.name = "com.ubuntu.espoo.Service.Provider";
> + conf.path = "/com/ubuntu/espoo/Service/Provider";
> +
> + DummyProvider provider{conf};
> +
> + cul::Provider::Ptr p1{std::addressof(provider), [](cul::Provider*){}};
> +
> + cul::ProviderSelection selection{p1, p1, p1};
> +
> + cul::ProxyProvider pp{selection};
> +
> + MockEventConsumer mec;
> + EXPECT_CALL(mec, on_new_position(postion_equals_tuple(update))).Times(1);
> +
> + pp.updates().position.connect([&mec](const cul::Update<cul::Position>& p){mec.on_new_position(p);});
> +
> + // create an update to be processed
> + provider.on_position_changed(update);
> +}
>
--
https://code.launchpad.net/~mandel/location-service/espoo-provider/+merge/231523
Your team Ubuntu Phablet Team is subscribed to branch lp:location-service.
More information about the Ubuntu-reviews
mailing list