Sha256: e1352388a1c19b3bdcd04bd7f2fcf72cf2c895b7906c6d0e02696ec2fb495f58

Contents?: true

Size: 1.43 KB

Versions: 1

Compression:

Stored size: 1.43 KB

Contents

# frozen_string_literal: true

require "logger"
require "socket"

module Milight
  module V6
    # Send and receive UDP packets.
    class Socket
      READ_TIMEOUT = 5

      attr_reader :host, :port

      def initialize(host, port)
        @host = host
        @port = port
      end

      def send_bytes(bytes)
        logger.debug("Sending: #{format_bytes_as_hex(bytes)}")

        socket.send(bytes.pack('C*'), 0, @host, @port)
      end

      def receive_bytes
        response, address = socket.recvfrom_nonblock(128)
        bytes = response.unpack('C*')

        logger.debug("Received: #{format_bytes_as_hex(bytes)}")

        [bytes, address.last]
      rescue IO::WaitReadable
        ready = IO.select([socket], nil, nil, READ_TIMEOUT)
        retry if ready

        return nil
      end

      def close
        socket.close
      end

      private

      def socket
        @socket ||= begin
          socket = UDPSocket.new

          if @host == "<broadcast>" || @host == "255.255.255.255"
            socket.setsockopt(::Socket::SOL_SOCKET, ::Socket::SO_BROADCAST, true)
          end

          socket
        end
      end

      def logger
        @logger ||= begin
          logger = Logger.new(STDOUT)
          logger.level = Logger::INFO if ENV["MILIGHT_DEBUG"] != "1"
          logger
        end
      end

      def format_bytes_as_hex(bytes)
        bytes.map { |s| format("0x%02X", s) }.join(", ")
      end
    end
  end
end

Version data entries

1 entries across 1 versions & 1 rubygems

Version Path
milight-v6-0.2.0 lib/milight/v6/socket.rb