def __init__(self, connection, args):
        self._dest = args.dest
        self._guid = args.guid
        self._response = args.response

        self._incoming = Queue()
        self._dispatcher = MessageDispatcher(args.address, args.group)
        self._dispatcher.register_receiver(AMID_GUIDDISCOVERY, self._incoming)

        assert isinstance(connection, Connection)
        self._connection = connection
        self._connection.register_dispatcher(self._dispatcher)
class GUIDDisco(object):

    def __init__(self, connection, args):
        self._dest = args.dest
        self._guid = args.guid
        self._response = args.response

        self._incoming = Queue()
        self._dispatcher = MessageDispatcher(args.address, args.group)
        self._dispatcher.register_receiver(AMID_GUIDDISCOVERY, self._incoming)

        assert isinstance(connection, Connection)
        self._connection = connection
        self._connection.register_dispatcher(self._dispatcher)

    def run(self):
        while not self._incoming.empty():
            self.receive(self._incoming.get())
        self._send()

    @staticmethod
    def _ts_now():
        now = datetime.datetime.utcnow()
        s = now.strftime("%Y-%m-%d %H:%M:%S")
        return s + ".%03uZ" % (now.microsecond / 1000)

    def _send(self):
        self._start = time.time()

        p = DiscoPacket(DiscoPacket.GUIDDISCOVERY_REQUEST, self._guid)

        if self._response:
            p.header = DiscoPacket.GUIDDISCOVERY_RESPONSE

        packet = Message()
        packet.destination = self._dest
        packet.source = self._dispatcher.address
        packet.type = AMID_GUIDDISCOVERY
        packet.payload = p.serialize()

        print("{} disco {:04X}->{:04X} {:s}".format(self._ts_now(), self._dispatcher.address, self._dest, p))

        self._connection.send(packet)

    def receive(self, packet):
        try:
            p = DiscoPacket()
            p.deserialize(packet.payload)

            printgreen("{} reply {:04X}->{:04X} {:s}".format(self._ts_now(), packet.source, packet.destination, p))

        except ValueError as e:
            printred("{} error {:04X}->{:04X} {}".format(self._ts_now(), packet.source, packet.destination, e.message))
Exemple #3
0
    def __init__(self, connection, args):
        super(PingSender, self).__init__()

        self._address = args.address
        self._destination = args.destination
        self._count = args.count
        self._interval = args.interval
        self._pongs = args.pongs
        self._delay = args.delay

        self._ping_size = args.ping_size
        min_size = len(PingPacket().serialize())  # TODO change once serdepa supports size as a class method
        if self._ping_size < min_size:
            self._ping_size = min_size

        self._pong_size = args.pong_size
        min_size = len(PongPacket().serialize())   # TODO change once serdepa supports size as a class method
        if self._pong_size < min_size:
            self._pong_size = min_size

        self._pingnum = 0

        self._ping_start = 0
        self._last_pongs = {}

        self._incoming = Queue.Queue()
        self._dispatcher = MessageDispatcher(args.address, args.group)
        self._dispatcher.register_receiver(AMID_TOSPINGPONG_PONG, self._incoming)

        assert isinstance(connection, Connection)
        self._connection = connection
        self._connection.register_dispatcher(self._dispatcher)

        self._alive = threading.Event()
        self._alive.set()
Exemple #4
0
def construct_connection(connection_string):
    """
    Constructs the connection object and returns it.

    The connection string takes the form of protocol@location:port_or_baud
    Examples: sf@localhost:9002
              serial@/dev/ttyUSB0

    :param str connection string: A string in the form of protocol@location:port_or_baud
    :rtype: moteconnection.connection.Connection
    """
    connection = Connection()
    connection.connect(
        connection_string,
        reconnect=10,
        connected=partial(print, "Connected to {}".format(connection_string)),
        disconnected=partial(print, "Disconnected from {}".format(connection_string))
    )

    dispatcher = MessageDispatcher()
    # This example uses a callback function (print in this case). The callback function
    # _must_ take exactly 1 positional argument. That argument will be an instance of
    # `moteconnection.message.Message`.
    # The alternatice method to using a callback function is to pass an instance of
    # `queue.Queue` (python3) or `Queue.Queue` (python2) to these methoods.
    dispatcher.register_default_snooper(print)
    dispatcher.register_default_receiver(print)
    connection.register_dispatcher(dispatcher)
    return connection
Exemple #5
0
def construct_connection(connection_string, src, group):
    """
    Constructs the connection object and returns it.

    The connection string takes the form of protocol@location:port_or_baud
    Examples: sf@localhost:9002
              serial@/dev/ttyUSB0

    :param str connection string: A string in the form of protocol@location:port_or_baud
    :rtype: moteconnection.connection.Connection
    """
    connection = Connection()
    connection.connect(
        connection_string,
        reconnect=10,
        connected=partial(print, "Connected to {}".format(connection_string)),
        disconnected=partial(print,
                             "Disconnected from {}".format(connection_string)))

    dispatcher = MessageDispatcher(src, group)
    connection.register_dispatcher(dispatcher)
    return connection
Exemple #6
0
class PingSender(threading.Thread):

    def __init__(self, connection, args):
        super(PingSender, self).__init__()

        self._address = args.address
        self._destination = args.destination
        self._count = args.count
        self._interval = args.interval
        self._pongs = args.pongs
        self._delay = args.delay

        self._ping_size = args.ping_size
        min_size = len(PingPacket().serialize())  # TODO change once serdepa supports size as a class method
        if self._ping_size < min_size:
            self._ping_size = min_size

        self._pong_size = args.pong_size
        min_size = len(PongPacket().serialize())   # TODO change once serdepa supports size as a class method
        if self._pong_size < min_size:
            self._pong_size = min_size

        self._pingnum = 0

        self._ping_start = 0
        self._last_pongs = {}

        self._incoming = Queue.Queue()
        self._dispatcher = MessageDispatcher(args.address, args.group)
        self._dispatcher.register_receiver(AMID_TOSPINGPONG_PONG, self._incoming)

        assert isinstance(connection, Connection)
        self._connection = connection
        self._connection.register_dispatcher(self._dispatcher)

        self._alive = threading.Event()
        self._alive.set()

    def _ts_now(self):
        now = datetime.datetime.utcnow()
        s = now.strftime("%Y-%m-%d %H:%M:%S")
        return s + ".%03uZ" % (now.microsecond / 1000)

    def run(self):
        while self._alive.is_set():
            passed = time.time() - self._ping_start
            if passed >= self._interval:
                if self._count == 0 or self._pingnum < self._count:
                    self._pingnum += 1
                    self._ping_start = time.time()
                    self._last_pongs = {}

                    p = PingPacket()
                    p.pingnum = self._pingnum
                    p.pongs = self._pongs
                    p.delay_ms = self._delay
                    p.ping_size = self._ping_size
                    p.pong_size = self._pong_size

                    out = "{} ping {:>2} 0/{} {:04X}->{:04X}[{:02X}] ({:>3}/{:>3}/???)".format(
                        self._ts_now(), self._pingnum, self._pongs,
                        self._address, self._destination, AMID_TOSPINGPONG_PING,
                        self._ping_size, self._pong_size)
                        # TODO pong_size_max should be read from connection

                    print_green(out)

                    try:
                        self._connection.send(Message(AMID_TOSPINGPONG_PING, destination=self._destination,
                                                      payload=p.serialize()))
                    except IOError:
                        print("{} send failed".format(self._ts_now()))

                else:
                    print("{} all pings sent".format(self._ts_now()))
            else:
                try:
                    p = self._incoming.get(timeout=0.1)
                    self.receive(p)
                except Queue.Empty:
                    pass

    def join(self, timeout=None):
        self._alive.clear()
        super(PingSender, self).join(timeout)

    def receive(self, packet):
        log.debug("RCV: {}".format(packet))
        try:
            p = PongPacket()
            p.deserialize(packet.payload)

            pformat = "{} pong {:>2} {}/{} {:04X}->{:04X}[{:02X}]"

            if p.pingnum == self._pingnum:
                if packet.source not in self._last_pongs:
                    self._last_pongs[packet.source] = 0

                if p.pong > self._last_pongs[packet.source] + 1:
                    for i in xrange(self._last_pongs[packet.source] + 1, p.pong):
                        pout = pformat.format(self._ts_now(), p.pingnum, i, p.pongs, packet.source, packet.destination, packet.type)
                        out = "{} LOST".format(pout)
                        print_red(out)

                self._last_pongs[packet.source] = p.pong
                delay = p.tx_time_ms - p.rx_time_ms
                rtt = (time.time() - self._ping_start) * 1000 - delay
            else:
                delay = 0
                rtt = 0

            pout = pformat.format(self._ts_now(), p.pingnum, p.pong, p.pongs, packet.source, packet.destination, packet.type)
            out = "{} ({:>3}/{:>3}/{:>3}) time={:>4.0f}ms delay={:>4.0f}ms uptime={:d}s {:s}".format(
                pout,
                p.ping_size, p.pong_size, p.pong_size_max,
                rtt, delay, p.uptime_s, str(p.padding.serialize()).encode("hex").upper())

            if packet.source != self._destination and self._destination != AM_BROADCAST_ADDR:
                log.debug(out)
            else:
                print(out)

        except ValueError as e:
            print_red("{} pong {}".format(self._ts_now(), e.message))