Class: Idevice::IdeviceConnection

Inherits:
C::ManagedOpaquePointer show all
Defined in:
lib/idevice/idevice.rb

Constant Summary collapse

DEFAULT_RECV_TIMEOUT =
0
DEFAULT_RECV_CHUNKSZ =
8192

Class Method Summary collapse

Instance Method Summary collapse

Methods inherited from C::ManagedOpaquePointer

#initialize

Constructor Details

This class inherits a constructor from Idevice::C::ManagedOpaquePointer

Class Method Details

.connect(idevice, port) ⇒ Object



90
91
92
93
94
95
96
97
98
99
100
101
# File 'lib/idevice/idevice.rb', line 90

def self.connect(idevice, port)
  FFI::MemoryPointer.new(:pointer) do |tmpptr|
    err = C.idevice_connect(idevice, port, tmpptr)
    raise IdeviceLibError, "Idevice error: #{err}" if err != :SUCCESS
    idev_connection = tmpptr.read_pointer
    if idev_connection.null?
      raise IdeviceLibError, "idevice_connect returned a null idevice_connection_t"
    else
      return new(idev_connection)
    end
  end
end

.release(ptr) ⇒ Object



86
87
88
# File 'lib/idevice/idevice.rb', line 86

def self.release(ptr)
  C.idevice_disconnect(ptr) unless ptr.null? or ptr.disconnected?
end

Instance Method Details

#connected?Boolean

Returns:

  • (Boolean)


110
111
112
# File 'lib/idevice/idevice.rb', line 110

def connected?
  not disconnected?
end

#disconnectObject

Raises:



103
104
105
106
107
108
# File 'lib/idevice/idevice.rb', line 103

def disconnect
  err = C.idevice_disconnect(self)
  raise IdeviceLibError, "Idevice error: #{err}" if err != :SUCCESS
  @_disconnected = true
  nil
end

#disconnected?Boolean

Returns:

  • (Boolean)


114
115
116
# File 'lib/idevice/idevice.rb', line 114

def disconnected?
  @_disconnected == true
end

#receive_all(timeout = nil, chunksz = nil) ⇒ Object

blocking read - optionally yields to a block with each chunk read



137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
# File 'lib/idevice/idevice.rb', line 137

def receive_all(timeout=nil, chunksz=nil)
  timeout ||= DEFAULT_RECV_TIMEOUT
  chunksz ||= DEFAULT_RECV_CHUNKSZ
  recvdata = StringIO.new unless block_given?

  FFI::MemoryPointer.new(chunksz) do |data_ptr|
    FFI::MemoryPointer.new(:uint32) do |recv_bytes|
      while (ierr=C.idevice_connection_receive_timeout(self, data_ptr, data_ptr.size, recv_bytes, timeout)) == :SUCCESS
        chunk = data_ptr.read_bytes(recv_bytes.read_uint32) 
        if block_given?
          yield chunk
        else
          recvdata << chunk
        end
      end

      # UNKNOWN_ERROR seems to indicate end of data/connection
      raise IdeviceLibError, "Idevice error: #{ierr}" if ierr != :UNKNOWN_ERROR
    end
  end

  return recvdata.string unless block_given?
end

#receive_data(maxlen, timeout = nil) ⇒ Object

read up to maxlen bytes



162
163
164
165
166
167
168
169
170
171
172
173
174
175
# File 'lib/idevice/idevice.rb', line 162

def receive_data(maxlen, timeout=nil)
  timeout ||= DEFAULT_RECV_TIMEOUT
  recvdata = StringIO.new

  FFI::MemoryPointer.new(maxlen) do |data_ptr|
    FFI::MemoryPointer.new(:uint32) do |recv_bytes|
      # one-shot, read up to max-len and we're done
      err = C.idevice_connection_receive_timeout(self, data_ptr, data_ptr.size, recv_bytes, timeout)
      raise IdeviceLibError, "Idevice error: #{err}" if err != :SUCCESS
      recvdata << data_ptr.read_bytes(recv_bytes.read_uint32)
    end
  end
  return recvdata.string
end

#receive_lockdown_messageObject



182
183
184
185
186
187
188
189
190
191
192
193
194
# File 'lib/idevice/idevice.rb', line 182

def receive_lockdown_message
    len = receive_data(4).unpack("N").first
    dat = receive_data(len)
    case dat[0,6]
    when "<?xml "
        return Plist.parse_xml(dat)
    when "bplist"
        return Plist.parse_binary(dat)
    else
        # just return raw data if this appears as something else
        return dat
    end
end

#send_data(data) ⇒ Object



118
119
120
121
122
123
124
125
126
127
128
129
130
131
# File 'lib/idevice/idevice.rb', line 118

def send_data(data)
  FFI::MemoryPointer.from_bytes(data) do |data_ptr|
    FFI::MemoryPointer.new(:uint32) do |sent_bytes|
      begin
        err = C.idevice_connection_send(self, data_ptr, data_ptr.size, sent_bytes)
        raise IdeviceLibError, "Idevice error: #{err}" if err != :SUCCESS
        sent = sent_bytes.read_uint32
        break if sent == 0
        data_ptr += sent
      end while data_ptr.size > 0
    end
  end
  return
end

#send_lockdown_message(msg) ⇒ Object



177
178
179
180
# File 'lib/idevice/idevice.rb', line 177

def send_lockdown_message(msg)
    dat = msg.to_plist
    send_data([dat.bytesize].pack("N") << dat)
end