# Source code for obspy.clients.seedlink.client.slstate

    # -*- coding: utf-8 -*-
    """
    Module to manage SeedLinkConnection state.

    Part of Python implementation of libslink of Chad Trabant and
    JSeedLink of Anthony Lomax

    :copyright:
        The ObsPy Development Team (devs@obspy.org) & Anthony Lomax
    :license:
        GNU Lesser General Public License, Version 3
        (https://www.gnu.org/copyleft/lesser.html)
    """
    from __future__ import (absolute_import, division, print_function,
                            unicode_literals)
    from future.builtins import *  # NOQA

    from ..seedlinkexception import SeedLinkException
    from ..slpacket import SLPacket

    class SLState(object):
        """
        Class to manage SeedLinkConnection state.

        :var SL_DOWN: Connection state down.
        :type SL_DOWN: int
        :var SL_UP: Connection state up.
        :type SL_UP: int
        :var SL_DATA: Connection state data.
        :type SL_DATA: int
        :var state: Connection state.
        :type state: int
        :var NO_QUERY: INFO query state NO_QUERY.
        :type NO_QUERY: int
        :var INFO_QUERY: INFO query state INFO_QUERY.
        :type INFO_QUERY: int
        :var KEEP_ALIVE_QUERY: INFO query state KEEP_ALIVE_QUERY.
        :type KEEP_ALIVE_QUERY: int
        :var query_mode: INFO query state.
        :type query_mode: int
        :var BUFSIZE: Size of receiving buffer (default is 8192).
        :type BUFSIZE: int
        :var databuf: Data buffer for received packets.
        :type databuf: bytearray
        :var recptr: Receive pointer for databuf.
        :type recptr: int
        :var sendptr: Send pointer for databuf.
        :type sendptr: int
        :var expect_info: Flag to indicate if an INFO response is expected.
        :type expect_info: bool
        :var netto_trig: Network timeout trigger.netto_trig
        :type netto_trig: int
        :var netdly_trig: Network re-connect delay trigger.
        :type netdly_trig: int
        :var keepalive_trig: Send keepalive trigger.
        :type keepalive_trig: int
        :var previous_time: Time stamp of last state update.
        :type previous_time: float
        :var netto_time: Network timeout time stamp.
        :type netto_time: float
        :var netdly_time: Network re-connect delay time stamp.
        :type netdly_time: float
        :var keepalive_time: Keepalive time stamp.
        :type keepalive_time: float
        """
        SL_DOWN = 0
        SL_UP = 1
        SL_DATA = 2
        NO_QUERY = 0
        INFO_QUERY = 1
        KEEP_ALIVE_QUERY = 2
        BUFSIZE = 8192

        def __init__(self):
            self.state = SLState.SL_DOWN
            self.query_mode = SLState.NO_QUERY
            # AJL self.databuf = [str() for __idx0 in range(BUFSIZE)]
            self.databuf = bytearray(SLState.BUFSIZE)
            # AJL packed_buf = [str() for __idx0 in range(BUFSIZE)]
            self.packed_buf = bytearray(SLState.BUFSIZE)
            self.recptr = 0
            self.sendptr = 0
            self.expect_info = False
            self.netto_trig = -1
            self.netdly_trig = 0
            self.keepalive_trig = -1
            self.previous_time = 0.0
            self.netto_time = 0.0
            self.netdly_time = 0.0
            self.keepalive_time = 0.0

        def get_packet(self):
            """
            Returns last received packet.

            :return: last received packet if data buffer contains a full packet to
                send.
            :raise SeedLinkException: if there is not a packet ready to send.

            See also: :meth:`packet_available`
            """
            if not self.packet_available():
                raise SeedLinkException("SLPacket not available to send")
            return SLPacket(self.databuf, self.sendptr)

        def packet_available(self):
            """
            Check for full packet available to send.

            :return: true if data buffer contains a full packet to send.

            See also: :meth:`get_packet`

            """
            return self.recptr - self.sendptr >= \
                SLPacket.SLHEADSIZE + SLPacket.SLRECSIZE

        def bytes_remaining(self):
            """
            Return number of bytes remaining in receiving buffer.

            :return: number of bytes remaining.

            """
            return self.BUFSIZE - self.recptr

        def is_error(self):
            """
            Check for SeedLink ERROR packet.

            :return: true if next send packet is a SeedLink ERROR packet

            :raise SeedLinkException: if there are not enough bytes to determine

            """
            if self.recptr - self.sendptr < len(SLPacket.ERRORSIGNATURE):
                msg = "not enough bytes to determine packet type"
                raise SeedLinkException(msg)
            return self.databuf[self.sendptr: self.sendptr +
                                len(SLPacket.ERRORSIGNATURE)].lower() == \
                SLPacket.ERRORSIGNATURE.lower()  # @UndefinedVariable

        def is_end(self):
            """
            Check for SeedLink END packet.

            :return: true if next send packet is a SeedLink END packet

            :raise SeedLinkException: if there are not enough bytes to determine
            """
            if self.recptr - self.sendptr < len(SLPacket.ENDSIGNATURE):
                msg = "not enough bytes to determine packet type"
                raise SeedLinkException(msg)
            return self.databuf[self.sendptr: self.sendptr +
                                len(SLPacket.ENDSIGNATURE)].lower() == \
                SLPacket.ENDSIGNATURE.lower()  # @UndefinedVariable

        def packet_is_info(self):
            """
            Check for SeedLink INFO packet.

            :return: true if next send packet is a SeedLink INFO packet

            :raise SeedLinkException: if there are not enough bytes to determine
                packet type
            """
            if self.recptr - self.sendptr < len(SLPacket.INFOSIGNATURE):
                msg = "not enough bytes to determine packet type"
                raise SeedLinkException(msg)
            return self.databuf[self.sendptr: self.sendptr +
                                len(SLPacket.INFOSIGNATURE)].lower() == \
                SLPacket.INFOSIGNATURE.lower()  # @UndefinedVariable

        def increment_send_pointer(self):
            """
            Increments the send pointer by size of one packet.

            """
            self.sendptr += SLPacket.SLHEADSIZE + SLPacket.SLRECSIZE

        def pack_data_buffer(self):
            """
            Packs the buffer by removing all sent packets and shifting remaining
            bytes to beginning of buffer.
            """
            # AJL System.arraycopy(self.databuf, self.sendptr, self.packed_buf, 0,
            #                     self.recptr - self.sendptr)
            self.packed_buf[0:self.recptr - self.sendptr] = \
                self.databuf[self.sendptr: self.recptr]
            temp_buf = self.databuf
            self.databuf = self.packed_buf
            self.packed_buf = temp_buf
            self.recptr -= self.sendptr
            self.sendptr = 0

        def append_bytes(self, bytes_):
            """
            Appends bytes to the receive buffer after the last received data.
            """
            if self.bytes_remaining() < len(bytes_):
                msg = "not enough bytes remaining in buffer to append new bytes"
                raise SeedLinkException(msg)

            self.databuf[self.recptr:self.recptr + len(bytes_)] = bytes_
            self.recptr += len(bytes_)

### Thank you!

We would like to thank our contributors, whose efforts make this software what it is. These people have helped by writing code and documentation, and by testing. They have created and maintained this product, its associated libraries and applications, our build tools and our web sites.

#### Contributors

- Ackerley, Nick
- Allgeyer, Sebastien
- Ammon, Charles J.
- Antunes, Emanuel
- Arnarsson, Ólafur St.
- Bank, Markus
- Barsch, Robert
- Behr, Yannik
- Bernardi, Fabrizio
- Bernauer, Felix
- Bes de Berc, Maxime
- Beyreuther, Moritz
- Boltz, Shawn
- Bonaimé, Sébastien
- Carothers, Lloyd
- Chamberlain, Calum
- Chambers, Derrick
- Chen, Zhao
- Clark, Adam
- Danecek, Peter
- Egdorf, Sven
- Engels, Fabian
- Ermert, Laura
- Eulenfeld, Tom

- Fabbri, Tommaso
- Falco, Nicholas
- Fee, Jeremy
- Grellier, Clément
- Grunberg, Marc
- Hammer, Conny
- Heimann, Sebastian
- Heiniger, Lukas
- Hope, Gaute
- Igel, Heiner
- Inza, Adolfo
- Isken, Marius
- Ketchum, David
- Koymans, Mathijs
- Kremers, Simon
- Kress, Victor
- Krieger, Lars
- Krischer, Lion
- Kula, Damian
- Käufl, Paul
- Köhler, Andreas
- Lecocq, Thomas
- Leeman, John
- Legovini, Paride

- Lesage, Philippe
- Li, Yulin
- Lomax, Anthony
- Lopes, Rui L.
- MacCarthy, Jonathan
- Maggi, Alessia
- Martin, Henri
- Medlin, Andrew
- Megies, Tobias
- Meschede, Matthias
- Michelini, Alberto
- Miller, Nathaniel C.
- Morgenstern, Bernhard
- Nof, Ran Novitsky
- Panning, Mark P.
- Parker, Tom
- Pestourie, Romain
- Rapagnani, Giovanni
- Reyes, Celso
- Ringler, Adam
- Rothenhäusler, Nicolas
- Russo, Emiliano
- Sales de Andrade, Elliott

- Satriano, Claudio
- Saul, Joachim
- Scheingraber, Chris
- Schneider, Simon
- Sippl, Christian
- Snoke, Arthur
- Stange, Stefan
- Stähler, Simon C.
- Sullivan, Benjamin
- Tian, Dongdong
- Trabant, Chad
- Trani, Luca
- Uieda, Leonardo
- Walker, Andrew
- Walther, Marcus
- Wassermann, Joachim
- Williams, Mark C.
- Winkelman, Andrew
- Zaccarelli, Riccardo
- Zad, Seyed Kasra Hosseini
- Zhu, Lijun
- van Driel, Martin
- van Wijk, Kasper

#### Funds

ObsPy was partially funded by the

- German Science Foundation (DFG) via grant DFG IG 16/9-1
- German Ministry for Education and Research (BMBF), GEOTECHNOLOGIEN grant 03G0646H.
- NERA project (Network of European Research Infrastructures for Earthquake Risk Assessment and Mitigation) under the European Community's Seventh Framework Programme (FP7/2007-2013) grant agreement n° 262330
- Leibniz Institute for Applied Geophysics (LIAG)
- VERCE EU-FP7 project (no. 283543)