# Source code for aioxmpp.ping.service

    ########################################################################
    # File name: service.py
    # This file is part of: aioxmpp
    #
    # LICENSE
    #
    # This program is free software: you can redistribute it and/or modify
    # it under the terms of the GNU Lesser General Public License as
    # published by the Free Software Foundation, either version 3 of the
    # License, or (at your option) any later version.
    #
    # 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/>.
    #
    ########################################################################
    import asyncio

    import aioxmpp.disco
    import aioxmpp.service
    import aioxmpp.structs

    from aioxmpp.utils import namespaces

    from . import xso as ping_xso

    class PingService(aioxmpp.service.Service):
        """
        Service implementing XMPP Ping (:xep:`199`).

        This service implements the response to XMPP Pings and provides a method
        to send pings.

        .. automethod:: ping
        """

        ORDER_AFTER = [
            aioxmpp.disco.DiscoServer,
        ]

        _ping_feature = aioxmpp.disco.register_feature(
            namespaces.xep0199_ping
        )

        @aioxmpp.service.iq_handler(aioxmpp.structs.IQType.GET, ping_xso.Ping)
        @asyncio.coroutine
        def handle_ping(self, request):
            return ping_xso.Ping()

        @asyncio.coroutine
        def ping(self, peer):
            """
            Ping a peer.

            :param peer: The peer to ping.
            :type peer: :class:`aioxmpp.JID`
            :raises aioxmpp.errors.XMPPError: as received

            Send a :xep:`199` ping IQ to `peer` and wait for the reply.

            .. note::

                If the peer does not support :xep:`199`, they will respond with
                a ``cancel`` ``service-unavailable`` error. However, some
                implementations return a ``cancel`` ``feature-not-implemented``
                error instead. Callers should be prepared for the
                :class:`aioxmpp.XMPPCancelError` exceptions in those cases.
            """

            iq = aioxmpp.IQ(
                to=peer,
                type_=aioxmpp.IQType.GET,
                payload=ping_xso.Ping()
            )

            yield from self.client.send(iq)