Send a packet

        :param ip: Ip to send to
        :type ip: str
        :param port: Port to send to
        :type port: int
        :param packet: Packet to be transmitted
        :type packet: APPMessage
        :param update_timestamp: Should update timestamp to current
        :type update_timestamp: bool
        :param acknowledge_packet: Should packet get acknowledged
        :type acknowledge_packet: bool
        :rtype: None

def _send_packet(
            self, ip, port, packet,
            update_timestamp=True, acknowledge_packet=True
    ):
        """
        Send a packet

        :param ip: Ip to send to
        :type ip: str
        :param port: Port to send to
        :type port: int
        :param packet: Packet to be transmitted
        :type packet: APPMessage
        :param update_timestamp: Should update timestamp to current
        :type update_timestamp: bool
        :param acknowledge_packet: Should packet get acknowledged
        :type acknowledge_packet: bool
        :rtype: None
        """
        if acknowledge_packet:
            packet.header.sequence_number = self._send_seq_num
            self._send_seq_num += 1
        packet.header.device_id = self._device_id
        try:
            packed = packet.pack(update_timestamp=update_timestamp)
        except ValueError:
            self.exception("Failed to pack packet")
            return
        self._send(ip, port, packed)
        # TODO: add to wait for ack list
        if acknowledge_packet:
            with self._seq_ack_lock:
                self._seq_ack.add(packet.header.sequence_number)
            self._to_ack.put(
                (time.time() + self._retransmit_timeout, 1, (ip, port), packet)
            )
        self.debug(u"Send: {}".format(packet))