def start(self):
        self._harness = self._newHarness()
        self._harness.start()
        self._harness.up()

        self._sendSock = socket.socket(self.addr.af, socket.SOCK_DGRAM)
        self._recvSock = socket.socket(self.addr.af, socket.SOCK_DGRAM)
        self._recvSock.bind((self._listenAddress or self.addr.local, 0))

        self._reader = PacketReader(source = self._newPacketSource(self._harness.char_dev.fileno()),
                                    skip = True,
                                    decode = lambda packet : self._decodePacket(packet))
        self._sockReader = PacketReader(source = SelectPacketSource(self._recvSock.fileno()))

        self._reader.start()
        self._sockReader.start()
class PacketCodec(object):
    """
    Helper for tests that wish to send and receive packets. This provides the interface to send and
    receive packets at the IP/IPv6 level on both the network interface and char dev sides.
    """

    def __init__(self, af, listenAddress, newHarness, newPacketSource):
        self._af = af
        self._listenAddress = listenAddress
        self._newHarness = newHarness
        self._newPacketSource = newPacketSource

    def __str__(self):
        af_map = { socket.AF_INET: 'IN', socket.AF_INET6: 'IN6' }
        return '<%s<%s, %s>>' % (self.__class__.__name__,
                                 af_map[self._af],
                                 self._newPacketSource.__name__)

    def _decodePacket(self, packet):
        return packet

    def _framePacket(self, payload):
        return payload

    def _frameExpectation(self, expectation):
        return expectation

    @property
    def af(self):
        return self._af

    @property
    def addr(self):
        if self._af == socket.AF_INET:
            return self._harness.addr
        elif self._af == socket.AF_INET6:
            return self._harness.addr6
        assert False

    @property
    def UDPPort(self):
        return self._recvSock.getsockname()[1]

    def start(self):
        self._harness = self._newHarness()
        self._harness.start()
        self._harness.up()

        self._sendSock = socket.socket(self.addr.af, socket.SOCK_DGRAM)
        self._recvSock = socket.socket(self.addr.af, socket.SOCK_DGRAM)
        self._recvSock.bind((self._listenAddress or self.addr.local, 0))

        self._reader = PacketReader(source = self._newPacketSource(self._harness.char_dev.fileno()),
                                    skip = True,
                                    decode = lambda packet : self._decodePacket(packet))
        self._sockReader = PacketReader(source = SelectPacketSource(self._recvSock.fileno()))

        self._reader.start()
        self._sockReader.start()

    def stop(self):
        self._sockReader.stop()
        self._reader.stop()
        self._harness.stop()
        self._sendSock.close()
        self._recvSock.close()

    def sendUDP(self, payload, addr):
        self._sendSock.sendto(payload, addr)

    def expectUDP(self, expectation):
        self._sockReader.expect(expectation)

    def runUDP(self):
        return self._sockReader.run()

    def sendPacket(self, payload):
        self._harness.char_dev.send(self._framePacket(payload))

    def expectPacket(self, expectation):
        self._reader.expect(self._frameExpectation(expectation))

    def runPacket(self):
        return self._reader.run()