idevice 1.1.5.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (62) hide show
  1. data/.gitignore +18 -0
  2. data/.rspec +2 -0
  3. data/Gemfile +4 -0
  4. data/NOTICE +202 -0
  5. data/README.md +74 -0
  6. data/Rakefile +37 -0
  7. data/examples/idevimgmount +58 -0
  8. data/examples/idumplockdownvalues +64 -0
  9. data/examples/ifetchcrashreports +54 -0
  10. data/examples/ilistapps +38 -0
  11. data/examples/ilistudids +26 -0
  12. data/examples/ilog +35 -0
  13. data/examples/installipa +51 -0
  14. data/examples/iremoveapp +42 -0
  15. data/examples/irestart +26 -0
  16. data/examples/iscreenshotr +39 -0
  17. data/idevice.gemspec +33 -0
  18. data/lib/idevice.rb +69 -0
  19. data/lib/idevice/afc.rb +518 -0
  20. data/lib/idevice/c.rb +129 -0
  21. data/lib/idevice/diagnostics_relay.rb +185 -0
  22. data/lib/idevice/file_relay.rb +83 -0
  23. data/lib/idevice/heartbeat.rb +99 -0
  24. data/lib/idevice/house_arrest.rb +138 -0
  25. data/lib/idevice/idevice.rb +208 -0
  26. data/lib/idevice/image_mounter.rb +117 -0
  27. data/lib/idevice/installation_proxy.rb +193 -0
  28. data/lib/idevice/lockdown.rb +350 -0
  29. data/lib/idevice/misagent.rb +112 -0
  30. data/lib/idevice/mobilebackup.rb +183 -0
  31. data/lib/idevice/mobilebackup2.rb +174 -0
  32. data/lib/idevice/mobilesync.rb +306 -0
  33. data/lib/idevice/notification_proxy.rb +168 -0
  34. data/lib/idevice/plist.rb +366 -0
  35. data/lib/idevice/restore.rb +176 -0
  36. data/lib/idevice/sbservices.rb +152 -0
  37. data/lib/idevice/screenshotr.rb +88 -0
  38. data/lib/idevice/version.rb +3 -0
  39. data/lib/idevice/webinspector.rb +96 -0
  40. data/spec/afc_devicespec.rb +409 -0
  41. data/spec/diagnostics_relay_devicespec.rb +125 -0
  42. data/spec/file_relay_devicespec.rb +45 -0
  43. data/spec/heartbeat_devicespec.rb +39 -0
  44. data/spec/idevice_devicespec.rb +93 -0
  45. data/spec/idevice_spec.rb +29 -0
  46. data/spec/image_mounter_devicespec.rb +65 -0
  47. data/spec/installation_proxy_devicespec.rb +54 -0
  48. data/spec/lockdown_devicespec.rb +106 -0
  49. data/spec/misagent_devicespec.rb +43 -0
  50. data/spec/mobilebackup2_devicespec.rb +58 -0
  51. data/spec/mobilebackup_devicespec.rb +41 -0
  52. data/spec/mobilesync_devicespec.rb +62 -0
  53. data/spec/notification_proxy_devicespec.rb +45 -0
  54. data/spec/plist_spec.rb +176 -0
  55. data/spec/restore_devicespec.rb +72 -0
  56. data/spec/samples/plist.bin +0 -0
  57. data/spec/samples/plist.xml +10 -0
  58. data/spec/sbservices_devicespec.rb +64 -0
  59. data/spec/screenshotr_devicespec.rb +39 -0
  60. data/spec/spec_helper.rb +73 -0
  61. data/spec/webinspector_devicespec.rb +36 -0
  62. metadata +233 -0
data/lib/idevice/c.rb ADDED
@@ -0,0 +1,129 @@
1
+ #
2
+ # Copyright (c) 2013 Eric Monti - Bluebox Security
3
+ #
4
+ # Licensed to the Apache Software Foundation (ASF) under one
5
+ # or more contributor license agreements. See the NOTICE file
6
+ # distributed with this work for additional information
7
+ # regarding copyright ownership. The ASF licenses this file
8
+ # to you under the Apache License, Version 2.0 (the
9
+ # "License"); you may not use this file except in compliance
10
+ # with the License. You may obtain a copy of the License at
11
+ #
12
+ # http://www.apache.org/licenses/LICENSE-2.0
13
+ #
14
+ # Unless required by applicable law or agreed to in writing,
15
+ # software distributed under the License is distributed on an
16
+ # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
17
+ # KIND, either express or implied. See the License for the
18
+ # specific language governing permissions and limitations
19
+ # under the License.
20
+
21
+ require "rubygems"
22
+ require 'plist'
23
+ require "ffi"
24
+
25
+ module FFI
26
+ class MemoryPointer < Pointer
27
+ def self.from_bytes(data)
28
+ if block_given?
29
+ new(data.size) do |p|
30
+ p.write_bytes(data)
31
+ yield(p)
32
+ end
33
+ else
34
+ p = new(data.size)
35
+ p.write_bytes(data)
36
+ p
37
+ end
38
+ end
39
+
40
+ def self.null_terminated_array_of_strings(strs)
41
+ psize = FFI::MemoryPointer.size * (strs.count+1)
42
+ pstrs = strs.map{|str| FFI::MemoryPointer.from_string(str) }
43
+ if block_given?
44
+ new(psize) do |aryp|
45
+ aryp.write_array_of_pointer(pstrs)
46
+ yield(aryp)
47
+ end
48
+ else
49
+ aryp.instance_variable_set(:@_string_pointers, pstrs) # retain reference for garbage collection
50
+ aryp.write_array_of_pointer(pstrs)
51
+ return aryp
52
+ end
53
+ end
54
+ end
55
+ end
56
+
57
+ module Idevice
58
+ module LibHelpers
59
+ def self.included(base)
60
+ class << base
61
+ private
62
+ def _attach_helper(svcname, opts={})
63
+ idevice = opts[:idevice] || Idevice.attach(opts)
64
+ ldsvc = opts[:lockdown_service]
65
+ unless ldsvc
66
+ ldclient = opts[:lockdown_client] || LockdownClient.attach(opts.merge(idevice:idevice))
67
+ ldsvc = ldclient.start_service(svcname)
68
+ end
69
+
70
+ FFI::MemoryPointer.new(:pointer) do |p_client|
71
+ yield idevice, ldsvc, p_client
72
+ end
73
+ end
74
+ end
75
+ end
76
+
77
+ private
78
+
79
+ def _unbound_list_to_array(p_unbound_list)
80
+ ret = nil
81
+ base = list = p_unbound_list.read_pointer
82
+ unless list.null?
83
+ ret = []
84
+ until list.read_pointer.null?
85
+ ret << list.read_pointer.read_string
86
+ list += FFI::TypeDefs[:pointer].size
87
+ end
88
+ C.idevice_device_list_free(base)
89
+ end
90
+ return ret
91
+ end
92
+
93
+ def _infolist_to_hash(p_infolist)
94
+ infolist = _unbound_list_to_array(p_infolist)
95
+ if infolist
96
+ return Hash[ infolist.each_slice(2).to_a.map{|k,v| [k.to_sym, v]} ]
97
+ end
98
+ end
99
+
100
+ end
101
+
102
+ module C
103
+ extend FFI::Library
104
+
105
+ class ManagedOpaquePointer < FFI::AutoPointer
106
+ def initialize(pointer)
107
+ raise NoMethodError, "release() not implemented for class #{self}" unless self.class.respond_to? :release
108
+ raise ArgumentError, "Must supply a pointer to memory" unless pointer
109
+ super(pointer, self.class.method(:release))
110
+ end
111
+ end
112
+
113
+ #----------------------------------------------------------------------
114
+ ffi_lib FFI::Library::LIBC
115
+
116
+ # memory allocators
117
+ attach_function :malloc, [:size_t], :pointer
118
+ attach_function :calloc, [:size_t], :pointer
119
+ attach_function :valloc, [:size_t], :pointer
120
+ attach_function :realloc, [:pointer, :size_t], :pointer
121
+ attach_function :free, [:pointer], :void
122
+
123
+ # memory movers
124
+ attach_function :memcpy, [:pointer, :pointer, :size_t], :pointer
125
+ attach_function :bcopy, [:pointer, :pointer, :size_t], :void
126
+
127
+ end
128
+ end
129
+
@@ -0,0 +1,185 @@
1
+ #
2
+ # Copyright (c) 2013 Eric Monti - Bluebox Security
3
+ #
4
+ # Licensed to the Apache Software Foundation (ASF) under one
5
+ # or more contributor license agreements. See the NOTICE file
6
+ # distributed with this work for additional information
7
+ # regarding copyright ownership. The ASF licenses this file
8
+ # to you under the Apache License, Version 2.0 (the
9
+ # "License"); you may not use this file except in compliance
10
+ # with the License. You may obtain a copy of the License at
11
+ #
12
+ # http://www.apache.org/licenses/LICENSE-2.0
13
+ #
14
+ # Unless required by applicable law or agreed to in writing,
15
+ # software distributed under the License is distributed on an
16
+ # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
17
+ # KIND, either express or implied. See the License for the
18
+ # specific language governing permissions and limitations
19
+ # under the License.
20
+
21
+ require 'idevice/c'
22
+ require 'idevice/plist'
23
+ require 'idevice/idevice'
24
+ require 'idevice/lockdown'
25
+
26
+ module Idevice
27
+ class DiagnosticsRelayError < IdeviceLibError
28
+ end
29
+
30
+ class DiagnosticsRelayClient < C::ManagedOpaquePointer
31
+ include LibHelpers
32
+
33
+ FLAG_WAIT_FOR_DISCONNECT = (1 << 1)
34
+ FLAG_DISPLAY_PASS = (1 << 2)
35
+ FLAG_DISPLAY_FAIL = (1 << 3)
36
+
37
+ REQUEST_TYPES = [
38
+ "All",
39
+ "HDMI",
40
+ "WiFi",
41
+ "GasGaugue",
42
+ "NAND",
43
+ ]
44
+
45
+ def self.release(ptr)
46
+ C.diagnostics_relay_client_free(ptr) unless ptr.null?
47
+ end
48
+
49
+
50
+ def self.attach(opts={})
51
+ # Note, we're not using LibHelpers#_attach_helper since we need to do the fallback to
52
+ # the old relay service name below
53
+
54
+ idevice = opts[:idevice] || Idevice.attach(opts)
55
+ ldsvc = opts[:lockdown_service]
56
+ unless ldsvc
57
+ ldclient = opts[:lockdown_client] || LockdownClient.attach(opts.merge(idevice:idevice))
58
+ ldsvc = begin
59
+ ldclient.start_service("com.apple.mobile.diagnostics_relay")
60
+ rescue LockdownError
61
+ # fall-back to old diagnostics relay service name
62
+ ldclient.start_service("com.apple.iosdiagnostics.relay")
63
+ end
64
+ end
65
+
66
+ FFI::MemoryPointer.new(:pointer) do |p_drc|
67
+ err = C.diagnostics_relay_client_new(idevice, ldsvc, p_drc)
68
+ raise DiagnosticsRelayError, "Diagnostics Relay error: #{err}" if err != :SUCCESS
69
+ drc = p_drc.read_pointer
70
+ raise DiagnosticsRelayError, "diagnostics_relay_client_new returned a NULL diagnostics_relay_client_t pointer" if drc.null?
71
+ return new(drc)
72
+ end
73
+ end
74
+
75
+ def diagnostics(type="All")
76
+ FFI::MemoryPointer.new(:pointer) do |p_diags|
77
+ err = C.diagnostics_relay_request_diagnostics(self, type, p_diags)
78
+ raise DiagnosticsRelayError, "Diagnostics Relay error: #{err}" if err != :SUCCESS
79
+
80
+ diags = p_diags.read_pointer.read_plist_t
81
+ raise DiagnosticsRelayError, "diagnostics_relay_request_diagnostics returned null diagnostics" if diags.nil?
82
+ return diags
83
+ end
84
+ end
85
+
86
+ def mobilegestalt(*keys)
87
+ FFI::MemoryPointer.new(:pointer) do |p_result|
88
+ err = C.diagnostics_relay_query_mobilegestalt(self, Plist_t.from_ruby(keys), p_result)
89
+ raise DiagnosticsRelayError, "Diagnostics Relay error: #{err}" if err != :SUCCESS
90
+ result = p_result.read_pointer.read_plist_t
91
+ raise DiagnosticsRelayError, "diagnostics_relay_query_mobilegestalt returned a null result" if result.nil?
92
+ return result
93
+ end
94
+ end
95
+
96
+ def ioregistry_entry(name, klass)
97
+ FFI::MemoryPointer.new(:pointer) do |p_result|
98
+ err = C.diagnostics_relay_query_ioregistry_entry(self, name, klass, p_result)
99
+ raise DiagnosticsRelayError, "Diagnostics Relay error: #{err}" if err != :SUCCESS
100
+ result = p_result.read_pointer.read_plist_t
101
+ raise DiagnosticsRelayError, "diagnostics_relay_query_ioregistry_entry returned a null result" if result.nil?
102
+ return result
103
+ end
104
+ end
105
+
106
+ def ioregistry_plane(plane)
107
+ FFI::MemoryPointer.new(:pointer) do |p_result|
108
+ err = C.diagnostics_relay_query_ioregistry_plane(self, plane, p_result)
109
+ raise DiagnosticsRelayError, "Diagnostics Relay error: #{err}" if err != :SUCCESS
110
+ result = p_result.read_pointer.read_plist_t
111
+ raise DiagnosticsRelayError, "diagnostics_relay_query_ioregistry_plane returned a null result" if result.nil?
112
+ return result
113
+ end
114
+ end
115
+
116
+ def goodbye
117
+ err = C.diagnostics_relay_goodbye(self)
118
+ raise DiagnosticsRelayError, "Diagnostics Relay error: #{err}" if err != :SUCCESS
119
+ return true
120
+ end
121
+
122
+ def sleep
123
+ err = C.diagnostics_relay_sleep(self)
124
+ raise DiagnosticsRelayError, "Diagnostics Relay error: #{err}" if err != :SUCCESS
125
+ return true
126
+ end
127
+
128
+ def restart(flags=0)
129
+ err = C.diagnostics_relay_restart(self, flags)
130
+ raise DiagnosticsRelayError, "Diagnostics Relay error: #{err}" if err != :SUCCESS
131
+ return true
132
+ end
133
+
134
+ def shutdown(flags=0)
135
+ err = C.diagnostics_relay_shutdown(self, flags)
136
+ raise DiagnosticsRelayError, "Diagnostics Relay error: #{err}" if err != :SUCCESS
137
+ return true
138
+ end
139
+ end
140
+
141
+ module C
142
+ ffi_lib 'imobiledevice'
143
+
144
+ typedef enum(
145
+ :SUCCESS , 0,
146
+ :INVALID_ARG , -1,
147
+ :PLIST_ERROR , -2,
148
+ :MUX_ERROR , -3,
149
+ :UNKNOWN_REQUEST , -4,
150
+ :UNKNOWN_ERROR , -256,
151
+ ), :diagnostics_relay_error_t
152
+
153
+ #diagnostics_relay_error_t diagnostics_relay_client_new(idevice_t device, lockdownd_service_descriptor_t service, diagnostics_relay_client_t *client);
154
+ attach_function :diagnostics_relay_client_new, [Idevice, LockdownServiceDescriptor, :pointer], :diagnostics_relay_error_t
155
+
156
+ #diagnostics_relay_error_t diagnostics_relay_client_free(diagnostics_relay_client_t client);
157
+ attach_function :diagnostics_relay_client_free, [DiagnosticsRelayClient], :diagnostics_relay_error_t
158
+
159
+ #diagnostics_relay_error_t diagnostics_relay_goodbye(diagnostics_relay_client_t client);
160
+ attach_function :diagnostics_relay_goodbye, [DiagnosticsRelayClient], :diagnostics_relay_error_t
161
+
162
+ #diagnostics_relay_error_t diagnostics_relay_sleep(diagnostics_relay_client_t client);
163
+ attach_function :diagnostics_relay_sleep, [DiagnosticsRelayClient], :diagnostics_relay_error_t
164
+
165
+ #diagnostics_relay_error_t diagnostics_relay_restart(diagnostics_relay_client_t client, int flags);
166
+ attach_function :diagnostics_relay_restart, [DiagnosticsRelayClient, :int], :diagnostics_relay_error_t
167
+
168
+ #diagnostics_relay_error_t diagnostics_relay_shutdown(diagnostics_relay_client_t client, int flags);
169
+ attach_function :diagnostics_relay_shutdown, [DiagnosticsRelayClient, :int], :diagnostics_relay_error_t
170
+
171
+ #diagnostics_relay_error_t diagnostics_relay_request_diagnostics(diagnostics_relay_client_t client, const char* type, plist_t* diagnostics);
172
+ attach_function :diagnostics_relay_request_diagnostics, [DiagnosticsRelayClient, :string, :pointer], :diagnostics_relay_error_t
173
+
174
+ #diagnostics_relay_error_t diagnostics_relay_query_mobilegestalt(diagnostics_relay_client_t client, plist_t keys, plist_t* result);
175
+ attach_function :diagnostics_relay_query_mobilegestalt, [DiagnosticsRelayClient, Plist_t, :pointer], :diagnostics_relay_error_t
176
+
177
+ #diagnostics_relay_error_t diagnostics_relay_query_ioregistry_entry(diagnostics_relay_client_t client, const char* name, const char* class, plist_t* result);
178
+ attach_function :diagnostics_relay_query_ioregistry_entry, [DiagnosticsRelayClient, :string, :string, :pointer], :diagnostics_relay_error_t
179
+
180
+ #diagnostics_relay_error_t diagnostics_relay_query_ioregistry_plane(diagnostics_relay_client_t client, const char* plane, plist_t* result);
181
+ attach_function :diagnostics_relay_query_ioregistry_plane, [DiagnosticsRelayClient, :string, :pointer], :diagnostics_relay_error_t
182
+
183
+
184
+ end
185
+ end
@@ -0,0 +1,83 @@
1
+ #
2
+ # Copyright (c) 2013 Eric Monti - Bluebox Security
3
+ #
4
+ # Licensed to the Apache Software Foundation (ASF) under one
5
+ # or more contributor license agreements. See the NOTICE file
6
+ # distributed with this work for additional information
7
+ # regarding copyright ownership. The ASF licenses this file
8
+ # to you under the Apache License, Version 2.0 (the
9
+ # "License"); you may not use this file except in compliance
10
+ # with the License. You may obtain a copy of the License at
11
+ #
12
+ # http://www.apache.org/licenses/LICENSE-2.0
13
+ #
14
+ # Unless required by applicable law or agreed to in writing,
15
+ # software distributed under the License is distributed on an
16
+ # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
17
+ # KIND, either express or implied. See the License for the
18
+ # specific language governing permissions and limitations
19
+ # under the License.
20
+
21
+ require 'idevice/c'
22
+ require 'idevice/idevice'
23
+ require 'idevice/lockdown'
24
+
25
+ module Idevice
26
+ class FileRelayError < IdeviceLibError
27
+ end
28
+
29
+ class FileRelayClient < C::ManagedOpaquePointer
30
+ include LibHelpers
31
+ def self.release(ptr)
32
+ C.file_relay_client_free(ptr) unless ptr.null?
33
+ end
34
+
35
+ def self.attach(opts={})
36
+ _attach_helper("com.apple.mobile.file_relay", opts) do |idevice,ldsvc,p_frc|
37
+ err = C.file_relay_client_new(idevice, ldsvc, p_frc)
38
+ raise FileRelayError, "File Relay error: #{err}" if err != :SUCCESS
39
+ frc = p_frc.read_pointer
40
+ raise FileRelayError, "file_relay_client_new returned a NULL client" if frc.null?
41
+ return new(frc)
42
+ end
43
+ end
44
+
45
+ def request_sources(*sources, &block)
46
+ FFI::MemoryPointer.null_terminated_array_of_strings(sources) do |p_sources|
47
+ FFI::MemoryPointer.new(:pointer) do |p_conn|
48
+ err = C.file_relay_request_sources(self, p_sources, p_conn)
49
+ raise FileRelayError, "File Relay error: #{err}" if err != :SUCCESS
50
+ conn = p_conn.read_pointer
51
+ raise FileRelayError, "file_relay_request_sources returned a NULL connection" if conn.null?
52
+ iconn = IdeviceConnection.new(conn)
53
+ ret = iconn.receive_all(nil, &block)
54
+ return ret
55
+ end
56
+ end
57
+ end
58
+ end
59
+
60
+ module C
61
+ ffi_lib 'imobiledevice'
62
+
63
+ typedef enum(
64
+ :SUCCESS , 0,
65
+ :INVALID_ARG , -1,
66
+ :PLIST_ERROR , -2,
67
+ :MUX_ERROR , -3,
68
+ :INVALID_SOURCE , -4,
69
+ :STAGING_EMPTY , -5,
70
+ :UNKNOWN_ERROR , -256,
71
+ ), :file_relay_error_t
72
+
73
+ #file_relay_error_t file_relay_client_new(idevice_t device, lockdownd_service_descriptor_t service, file_relay_client_t *client);
74
+ attach_function :file_relay_client_new, [Idevice, LockdownServiceDescriptor, :pointer], :file_relay_error_t
75
+
76
+ #file_relay_error_t file_relay_client_free(file_relay_client_t client);
77
+ attach_function :file_relay_client_free, [FileRelayClient], :file_relay_error_t
78
+
79
+ #file_relay_error_t file_relay_request_sources(file_relay_client_t client, const char **sources, idevice_connection_t *connection);
80
+ attach_function :file_relay_request_sources, [FileRelayClient, :pointer, :pointer], :file_relay_error_t
81
+
82
+ end
83
+ end
@@ -0,0 +1,99 @@
1
+ #
2
+ # Copyright (c) 2013 Eric Monti - Bluebox Security
3
+ #
4
+ # Licensed to the Apache Software Foundation (ASF) under one
5
+ # or more contributor license agreements. See the NOTICE file
6
+ # distributed with this work for additional information
7
+ # regarding copyright ownership. The ASF licenses this file
8
+ # to you under the Apache License, Version 2.0 (the
9
+ # "License"); you may not use this file except in compliance
10
+ # with the License. You may obtain a copy of the License at
11
+ #
12
+ # http://www.apache.org/licenses/LICENSE-2.0
13
+ #
14
+ # Unless required by applicable law or agreed to in writing,
15
+ # software distributed under the License is distributed on an
16
+ # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
17
+ # KIND, either express or implied. See the License for the
18
+ # specific language governing permissions and limitations
19
+ # under the License.
20
+
21
+ require 'idevice/c'
22
+ require 'idevice/plist'
23
+ require 'idevice/idevice'
24
+ require 'idevice/lockdown'
25
+
26
+ module Idevice
27
+ class HeartbeatError < IdeviceLibError
28
+ end
29
+
30
+ class HeartbeatClient < C::ManagedOpaquePointer
31
+ include LibHelpers
32
+
33
+ def self.release(ptr)
34
+ C.heartbeat_client_free(ptr) unless ptr.null?
35
+ end
36
+
37
+ def self.attach(opts={})
38
+ _attach_helper("com.apple.mobile.heartbeat", opts) do |idevice, ldsvc, p_hb|
39
+ err=C.heartbeat_client_new(idevice, ldsvc, p_hb)
40
+ raise HeartbeatError, "Heartbeat error: #{err}" if err != :SUCCESS
41
+ hb = p_hb.read_pointer
42
+ raise HeartbeatError, "hearbeat_client_new returned a NULL client" if hb.null?
43
+ return new(hb)
44
+ end
45
+ end
46
+
47
+ def send_plist(obj)
48
+ err = C.heartbeat_send(self, obj.to_plist_t)
49
+ raise HeartbeatError, "Heartbeat error: #{err}" if err != :SUCCESS
50
+ return true
51
+ end
52
+
53
+ def receive_plist(timeout=nil)
54
+ timeout ||= 1
55
+
56
+ FFI::MemoryPointer.new(:pointer) do |p_plist|
57
+ err = C.heartbeat_receive_with_timeout(self, p_plist, timeout)
58
+ raise HeartbeatError, "Heartbeat error: #{err}" if err != :SUCCESS
59
+ plist = p_plist.read_pointer
60
+ raise HeartbeatError, "hearbeat_receive returned a NULL plist" if plist.null?
61
+ return Plist.new(plist).to_ruby
62
+ end
63
+ end
64
+
65
+ end
66
+
67
+ module C
68
+ ffi_lib 'imobiledevice'
69
+
70
+ typedef enum(
71
+ :SUCCESS , 0,
72
+ :INVALID_ARG , -1,
73
+ :PLIST_ERROR , -2,
74
+ :MUX_ERROR , -3,
75
+ :SSL_ERROR , -4,
76
+ :UNKNOWN_ERROR, -256,
77
+ ), :heartbeat_error_t
78
+
79
+
80
+ #heartbeat_error_t heartbeat_client_new(idevice_t device, lockdownd_service_descriptor_t service, heartbeat_client_t * client);
81
+ attach_function :heartbeat_client_new, [Idevice, LockdownServiceDescriptor, :pointer], :heartbeat_error_t
82
+
83
+ #heartbeat_error_t heartbeat_client_start_service(idevice_t device, heartbeat_client_t * client, const char* label);
84
+ attach_function :heartbeat_client_start_service, [Idevice, :pointer, :string], :heartbeat_error_t
85
+
86
+ #heartbeat_error_t heartbeat_client_free(heartbeat_client_t client);
87
+ attach_function :heartbeat_client_free, [HeartbeatClient], :heartbeat_error_t
88
+
89
+ #heartbeat_error_t heartbeat_send(heartbeat_client_t client, plist_t plist);
90
+ attach_function :heartbeat_send, [HeartbeatClient, Plist_t], :heartbeat_error_t
91
+
92
+ #heartbeat_error_t heartbeat_receive(heartbeat_client_t client, plist_t * plist);
93
+ attach_function :heartbeat_receive, [HeartbeatClient, :pointer], :heartbeat_error_t
94
+
95
+ #heartbeat_error_t heartbeat_receive_with_timeout(heartbeat_client_t client, plist_t * plist, uint32_t timeout_ms);
96
+ attach_function :heartbeat_receive_with_timeout, [HeartbeatClient, :pointer, :uint32], :heartbeat_error_t
97
+
98
+ end
99
+ end