class ATEM::Network

Public Class Methods

new(ip, port, uid = 0x1337) click to toggle source
# File lib/atem/network.rb, line 32
def initialize ip, port, uid = 0x1337

        @socket = UDPSocket.new
        @socket.bind "0.0.0.0", 9100

        @ip = ip
        @port = port
        @uid = uid
        @package_id = 0

end

Public Instance Methods

<<(data) click to toggle source
# File lib/atem/network.rb, line 48
def << data

        bitmask, ack_id, payload = data

        bitmask = bitmask << 11
        bitmask |= (payload.length + @@SIZE_OF_HEADER)
        
        package_id = 0
        if (bitmask & (Packet::HELLO | Packet::ACK)) != 0 and @ready and payload.length != 0
                # p "SENDING PACKAGE"
                @package_id += 1 
                package_id = @package_id
        end

        packet = [bitmask, @uid, ack_id, 0, package_id].pack("S>S>S>L>S>")
        packet += payload

        # print "TX(#{packet.length}, #{@package_id}, #{ack_id})"; p packet.to_hex
        @socket.send packet, 0, @ip, @port

end
disconnect() click to toggle source
# File lib/atem/network.rb, line 44
def disconnect
        @socket.close
end
hello() click to toggle source
# File lib/atem/network.rb, line 82
def hello

        self << [0x02, 0x0, [0x01000000, 0x00].pack("L>L>")]
        self.receive_until_ready

end
receive() click to toggle source
# File lib/atem/network.rb, line 89
                def receive

                        packets = []
                        next_packet = nil

                        begin

                                begin
                                        data, _ = @socket.recvfrom(2048)
                                rescue
                                        p "ERR"
                                        return []
                                end

                                # print "RX(#{data.length}) "; p data.to_hex

                                bitmask, size, uid, ack_id, _, package_id = data.unpack("CXS>S>S>LS>")
                                @uid = uid

                                bitmask = bitmask >> 3
                                size &= 0x07FF

                                # print "RX HEADER: "
                                # p [bitmask, size, uid, ack_id, package_id]

                                @ack_id = package_id

                                packet = [ack_id, bitmask, package_id, data[ @@SIZE_OF_HEADER .. -1 ]]

                                packets += handle(packet)

#                               raise Retry

#                       rescue Retry
#                               retry if next_packet and next_packet.length >= @@SIZE_OF_HEADER
                        end

                        packets

                end
receive_until_ready() click to toggle source
# File lib/atem/network.rb, line 130
def receive_until_ready 

        packets = []
        while !@ready
                packets += receive
        end
        packets

end
send!(cmd, payload) click to toggle source
# File lib/atem/network.rb, line 70
def send! cmd, payload

        raise "Invalid command" if cmd.bytes.length != 4

        size = cmd.length + payload.length + 4
        datagram = [size, 0, 0].pack("S>CC") + cmd + payload

        self << [Packet::ACK_REQ, @ack_id, datagram]
        self.receive 

end

Private Instance Methods

handle(packet) click to toggle source
# File lib/atem/network.rb, line 142
def handle packet

        bitmask = packet[1]

        if (bitmask & Packet::HELLO) == Packet::HELLO

                @ready = false
                self << [Packet::ACK, 0x0, '']

        elsif ((bitmask & Packet::ACK_REQ) == Packet::ACK_REQ) and (@ready or (!@ready and packet[3].length == 0))

                self << [Packet::ACK, packet[2], '']
                @ready = true

        end

        data = packet[3]
        packets = []
        
        while data != nil and data.length > 0

                packet, data = payload(data)
                packets << packet
                
        end

        packets

end
payload(packet) click to toggle source
# File lib/atem/network.rb, line 172
def payload packet

        size = packet.unpack("S>")[0]
        pack = packet[4..size-1]
        packet = packet[size..-1]

        command = pack.slice!(0, 4)

        [[command, pack], packet]

end