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
@@ -0,0 +1,306 @@
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
+ require 'time'
26
+
27
+ module Idevice
28
+ class MobileSyncError < IdeviceLibError
29
+ end
30
+
31
+ # Used to synchronize data classes with a device and computer.
32
+ class MobileSyncClient < C::ManagedOpaquePointer
33
+ include LibHelpers
34
+
35
+ def self.release(ptr)
36
+ C.mobilesync_client_free(ptr) unless ptr.null?
37
+ end
38
+
39
+ def self.attach(opts={})
40
+ _attach_helper("com.apple.mobilesync", opts) do |idevice, ldsvc, p_ms|
41
+ err = C.mobilesync_client_new(idevice, ldsvc, p_ms)
42
+ raise MobileSyncError, "MobileSync error: #{err}" if err != :SUCCESS
43
+
44
+ ms = p_ms.read_pointer
45
+ raise MobileSyncError, "mobilesync_client_new returned a NULL client" if ms.null?
46
+ return new(ms)
47
+ end
48
+ end
49
+
50
+ def receive_plist
51
+ FFI::MemoryPointer.new(:pointer) do |p_result|
52
+ err = C.mobilesync_receive(self, p_result)
53
+ raise MobileSyncError, "MobileSync error: #{err}" if err != :SUCCESS
54
+ return p_result.read_pointer.read_plist_t
55
+ end
56
+ end
57
+
58
+ def send_plist(request)
59
+ err = C.mobilesync_send(self, Plist_t.from_ruby(request))
60
+ raise MobileSyncError, "MobileSync error: #{err}" if err != :SUCCESS
61
+
62
+ return true
63
+ end
64
+
65
+ SYNC_TYPES = [
66
+ :FAST, # Fast-sync requires that only the changes made since the last synchronization should be reported by the computer.
67
+ :SLOW, # Slow-sync requires that all data from the computer needs to be synchronized/sent.
68
+ :RESET, # Reset-sync signals that the computer should send all data again.
69
+ ]
70
+
71
+ def start(data_class, anchors, data_class_version=106)
72
+ anchors = C.mobilesync_anchors_new(*anchors)
73
+
74
+ FFI::MemoryPointer.new(:int) do |p_sync_type|
75
+ FFI::MemoryPointer.new(:uint64) do |p_dev_data_class_version|
76
+ FFI::MemoryPointer.new(:pointer) do |p_error|
77
+ err = C.mobilesync_send(self, data_class, anchors, data_class_version, p_sync_type, p_dev_data_class_version, p_error)
78
+ errstr = nil
79
+ p_errstr = p_error.read_pointer
80
+ unless p_errstr.null?
81
+ errstr = p_errstr.read_string
82
+ C.free(p_errstr)
83
+ end
84
+
85
+ if err != :SUCCESS
86
+ msg = "MobileSync error: #{err}"
87
+ msg << "(#{errstr})" if errstr
88
+ raise MobileSyncError, msg
89
+ end
90
+
91
+ sync_type = sync_type.read_int
92
+ ddc_ver = p_device_data_class_version.read_uint64
93
+
94
+ return({
95
+ sync_type: (SYNC_TYPES[sync_type] || sync_type),
96
+ device_data_class_version: ddc_ver,
97
+ error: errstr,
98
+ })
99
+ end
100
+ end
101
+ end
102
+ end
103
+
104
+ def cancel(reason)
105
+ err = C.mobilesync_cancel(self, reason)
106
+ raise MobileSyncError, "MobileSync error: #{err}" if err != :SUCCESS
107
+
108
+ return true
109
+ end
110
+
111
+ def finish
112
+ err = C.mobilesync_finish(self)
113
+ raise MobileSyncError, "MobileSync error: #{err}" if err != :SUCCESS
114
+
115
+ return true
116
+ end
117
+
118
+ def request_all_records_from_device
119
+ err = C.mobilesync_get_all_records_from_device(self)
120
+ raise MobileSyncError, "MobileSync error: #{err}" if err != :SUCCESS
121
+
122
+ return true
123
+ end
124
+
125
+ def request_changes_from_device
126
+ err = C.mobilesync_get_changes_from_device(self)
127
+ raise MobileSyncError, "MobileSync error: #{err}" if err != :SUCCESS
128
+
129
+ return true
130
+ end
131
+
132
+ def clear_all_records_on_device
133
+ err = C.mobilesync_clear_all_records_on_device(self)
134
+ raise MobileSyncError, "MobileSync error: #{err}" if err != :SUCCESS
135
+
136
+ return true
137
+ end
138
+
139
+ def receive_changes
140
+ ret = []
141
+
142
+ FFI::MemoryPointer.new(:pointer) do |p_entities|
143
+ FFI::MemoryPointer.new(:uint8) do |p_is_last_record|
144
+ FFI::MemoryPointer.new(:pointer) do |p_actions|
145
+ last_record = false
146
+ until last_record
147
+ err = C.mobilesync_receive_changes(self, p_entities, p_is_last_record, p_actions)
148
+ raise MobileSyncError, "MobileSync error: #{err}" if err != :SUCCESS
149
+
150
+ last_record = (p_is_last_record.read_uint8 != 0)
151
+ ret << {
152
+ entities: p_entities.read_pointer.read_plist_t,
153
+ actions: p_actions.read_pointer.read_plist_t,
154
+ }
155
+ end
156
+ end
157
+ end
158
+ end
159
+
160
+ return ret
161
+ end
162
+
163
+ def acknowledge_changes_from_device
164
+ err = C.mobilesync_acknowledge_changes_from_device(self)
165
+ raise MobileSyncError, "MobileSync error: #{err}" if err != :SUCCESS
166
+
167
+ return true
168
+ end
169
+
170
+ def signal_ready_to_send_changes_from_computer
171
+ err = C.mobilesync_ready_to_send_changes_from_computer(self)
172
+ raise MobileSyncError, "MobileSync error: #{err}" if err != :SUCCESS
173
+
174
+ return true
175
+ end
176
+
177
+ def _send_changes(entities, is_last, actions=nil)
178
+ act = actions ? Plist_t.from_ruby(actions) : nil
179
+ err = C.mobilesync_send_changes(self, Plist_t.from_ruby(entities), is_last, act)
180
+ raise MobileSyncError, "MobileSync error: #{err}" if err != :SUCCESS
181
+ end
182
+
183
+ def send_changes(changes)
184
+ raise TypeError, "changes must be an array" unless changes.is_a? Array
185
+ raise ArgumentError, "changes must not be empty" if changes.empty?
186
+
187
+ lastchange = changes.unshift
188
+ changes.each { |change| _send_changes(change[:entities], 0, change[:actions]) }
189
+ _send_changes(lastchange[:entities], 1, lastchange[:actions])
190
+ return true
191
+ end
192
+
193
+ #mobilesync_error_t mobilesync_remap_identifiers(mobilesync_client_t client, plist_t *mapping);
194
+ def remap_identifiers(mappings)
195
+ raise TypeError, "mappings must be an array" unless changes.is_a? Array
196
+ raise ArgumentError, "mappings must not be empty" if changes.empty?
197
+
198
+ FFI::MemoryPointer.new(FFI::Pointer.size * (mappings.count+1)) do |p_mapping|
199
+ p_mapping.write_array_of_pointer(mappings.map{|m| Plist_t.from_ruby(m)} + nil)
200
+ err = C.mobilesync_remap_identifiers(self, p_mapping)
201
+ raise MobileSyncError, "MobileSync error: #{err}" if err != :SUCCESS
202
+ return true
203
+ end
204
+ end
205
+ end
206
+
207
+ # Mobile Sync anchors used by the device and computer
208
+ class MobileSyncAnchors < FFI::ManagedStruct
209
+ def self.release(ptr)
210
+ C.mobilesync_anchors_free(ptr) unless ptr.null?
211
+ end
212
+
213
+ layout(
214
+ :device_anchor, :string,
215
+ :computer_anchor, :string,
216
+ )
217
+ end
218
+
219
+ module C
220
+ ffi_lib 'imobiledevice'
221
+
222
+ typedef enum(
223
+ :SUCCESS , 0,
224
+ :INVALID_ARG , -1,
225
+ :PLIST_ERROR , -2,
226
+ :MUX_ERROR , -3,
227
+ :BAD_VERSION , -4,
228
+ :SYNC_REFUSED , -5,
229
+ :CANCELLED , -6,
230
+ :WRONG_DIRECTION, -7,
231
+ :NOT_READY , -8,
232
+ :UNKNOWN_ERROR , -256,
233
+ ), :mobilesync_error_t
234
+
235
+ ## The sync type of the current sync session.
236
+ typedef enum(
237
+ :FAST, # Fast-sync requires that only the changes made since the last synchronization should be reported by the computer.
238
+ :SLOW, # Slow-sync requires that all data from the computer needs to be synchronized/sent.
239
+ :RESET, # Reset-sync signals that the computer should send all data again.
240
+ ), :mobilesync_sync_type_t
241
+
242
+ #mobilesync_error_t mobilesync_client_new(idevice_t device, lockdownd_service_descriptor_t service, mobilesync_client_t * client);
243
+ attach_function :mobilesync_client_new, [Idevice, LockdownServiceDescriptor, :pointer], :mobilesync_error_t
244
+
245
+ #mobilesync_error_t mobilesync_client_free(mobilesync_client_t client);
246
+ attach_function :mobilesync_client_free, [MobileSyncClient], :mobilesync_error_t
247
+
248
+ #mobilesync_error_t mobilesync_receive(mobilesync_client_t client, plist_t *plist);
249
+ attach_function :mobilesync_receive, [MobileSyncClient, :pointer], :mobilesync_error_t
250
+
251
+ #mobilesync_error_t mobilesync_send(mobilesync_client_t client, plist_t plist);
252
+ attach_function :mobilesync_send, [MobileSyncClient, Plist_t], :mobilesync_error_t
253
+
254
+ #mobilesync_error_t mobilesync_start(mobilesync_client_t client, const char *data_class, mobilesync_anchors_t anchors, uint64_t computer_data_class_version, mobilesync_sync_type_t *sync_type, uint64_t *device_data_class_version, char** error_description);
255
+ attach_function :mobilesync_start, [MobileSyncClient, :string, MobileSyncAnchors, :uint64, :pointer, :pointer, :pointer], :mobilesync_error_t
256
+
257
+ #mobilesync_error_t mobilesync_cancel(mobilesync_client_t client, const char* reason);
258
+ attach_function :mobilesync_cancel, [MobileSyncClient, :string], :mobilesync_error_t
259
+
260
+ #mobilesync_error_t mobilesync_finish(mobilesync_client_t client);
261
+ attach_function :mobilesync_finish, [MobileSyncClient], :mobilesync_error_t
262
+
263
+ #mobilesync_error_t mobilesync_get_all_records_from_device(mobilesync_client_t client);
264
+ attach_function :mobilesync_get_all_records_from_device, [MobileSyncClient], :mobilesync_error_t
265
+
266
+ #mobilesync_error_t mobilesync_get_changes_from_device(mobilesync_client_t client);
267
+ attach_function :mobilesync_get_changes_from_device, [MobileSyncClient], :mobilesync_error_t
268
+
269
+ #mobilesync_error_t mobilesync_clear_all_records_on_device(mobilesync_client_t client);
270
+ attach_function :mobilesync_clear_all_records_on_device, [MobileSyncClient], :mobilesync_error_t
271
+
272
+ #mobilesync_error_t mobilesync_receive_changes(mobilesync_client_t client, plist_t *entities, uint8_t *is_last_record, plist_t *actions);
273
+ attach_function :mobilesync_receive_changes, [MobileSyncClient, :pointer, :pointer, :pointer], :mobilesync_error_t
274
+
275
+ #mobilesync_error_t mobilesync_acknowledge_changes_from_device(mobilesync_client_t client);
276
+ attach_function :mobilesync_acknowledge_changes_from_device, [MobileSyncClient], :mobilesync_error_t
277
+
278
+ #mobilesync_error_t mobilesync_ready_to_send_changes_from_computer(mobilesync_client_t client);
279
+ attach_function :mobilesync_ready_to_send_changes_from_computer, [MobileSyncClient], :mobilesync_error_t
280
+
281
+ #mobilesync_error_t mobilesync_send_changes(mobilesync_client_t client, plist_t entities, uint8_t is_last_record, plist_t actions);
282
+ attach_function :mobilesync_send_changes, [MobileSyncClient, Plist_t, :uint8, Plist_t], :mobilesync_error_t
283
+
284
+ #mobilesync_error_t mobilesync_remap_identifiers(mobilesync_client_t client, plist_t *mapping);
285
+ attach_function :mobilesync_remap_identifiers, [MobileSyncClient, :pointer], :mobilesync_error_t
286
+
287
+ #mobilesync_anchors_t mobilesync_anchors_new(const char *device_anchor, const char *computer_anchor);
288
+ attach_function :mobilesync_anchors_new, [:string, :string], MobileSyncAnchors
289
+
290
+ #void mobilesync_anchors_free(mobilesync_anchors_t anchors);
291
+ attach_function :mobilesync_anchors_free, [MobileSyncAnchors], :void
292
+
293
+
294
+ ### actions Helpers
295
+
296
+ #plist_t mobilesync_actions_new();
297
+ attach_function :mobilesync_actions_new, [], Plist_t
298
+
299
+ #void mobilesync_actions_add(plist_t actions, ...);
300
+ attach_function :mobilesync_actions_add, [Plist_t, :varargs], Plist_t
301
+
302
+ #void mobilesync_actions_free(plist_t actions);
303
+ attach_function :mobilesync_actions_free, [Plist_t], :void
304
+
305
+ end
306
+ end
@@ -0,0 +1,168 @@
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 NotificationProxyError < IdeviceLibError
27
+ end
28
+
29
+ # Aliased short name for NotificationProxyError
30
+ NPError = NotificationProxyError
31
+
32
+ # Notifications that can be received from the device
33
+ module NPRecvNotifications
34
+ SYNC_CANCEL_REQUEST = "com.apple.itunes-client.syncCancelRequest"
35
+ SYNC_SUSPEND_REQUEST = "com.apple.itunes-client.syncSuspendRequest"
36
+ SYNC_RESUME_REQUEST = "com.apple.itunes-client.syncResumeRequest"
37
+ PHONE_NUMBER_CHANGED = "com.apple.mobile.lockdown.phone_number_changed"
38
+ DEVICE_NAME_CHANGED = "com.apple.mobile.lockdown.device_name_changed"
39
+ TIMEZONE_CHANGED = "com.apple.mobile.lockdown.timezone_changed"
40
+ TRUSTED_HOST_ATTACHED = "com.apple.mobile.lockdown.trusted_host_attached"
41
+ HOST_DETACHED = "com.apple.mobile.lockdown.host_detached"
42
+ HOST_ATTACHED = "com.apple.mobile.lockdown.host_attached"
43
+ REGISTRATION_FAILED = "com.apple.mobile.lockdown.registration_failed"
44
+ ACTIVATION_STATE = "com.apple.mobile.lockdown.activation_state"
45
+ BRICK_STATE = "com.apple.mobile.lockdown.brick_state"
46
+ DISK_USAGE_CHANGED = "com.apple.mobile.lockdown.disk_usage_changed"# /**< iOS 4.0+ */
47
+ DS_DOMAIN_CHANGED = "com.apple.mobile.data_sync.domain_changed"
48
+ BACKUP_DOMAIN_CHANGED = "com.apple.mobile.backup.domain_changed"
49
+ APP_INSTALLED = "com.apple.mobile.application_installed"
50
+ APP_UNINSTALLED = "com.apple.mobile.application_uninstalled"
51
+ DEV_IMAGE_MOUNTED = "com.apple.mobile.developer_image_mounted"
52
+ ATTEMPTACTIVATION = "com.apple.springboard.attemptactivation"
53
+ ITDBPREP_DID_END = "com.apple.itdbprep.notification.didEnd"
54
+ LANGUAGE_CHANGED = "com.apple.language.changed"
55
+ ADDRESS_BOOK_PREF_CHANGED = "com.apple.AddressBook.PreferenceChanged"
56
+ end
57
+
58
+ # Notifications that can be sent to the device
59
+ module NPSendNotifications
60
+ SYNC_WILL_START = "com.apple.itunes-mobdev.syncWillStart"
61
+ SYNC_DID_START = "com.apple.itunes-mobdev.syncDidStart"
62
+ SYNC_DID_FINISH = "com.apple.itunes-mobdev.syncDidFinish"
63
+ SYNC_LOCK_REQUEST = "com.apple.itunes-mobdev.syncLockRequest"
64
+ end
65
+
66
+ # Used to receive and post device notifications
67
+ class NotificationProxyClient < C::ManagedOpaquePointer
68
+ include LibHelpers
69
+
70
+ def self.release(ptr)
71
+ C.np_client_free(ptr) unless ptr.null?
72
+ end
73
+
74
+ def self.attach(opts={})
75
+ _attach_helper("com.apple.mobile.notification_proxy", opts) do |idevice, ldsvc, p_np|
76
+ err = C.np_client_new(idevice, ldsvc, p_np)
77
+ raise NotificationProxyError, "Notification Proxy Error: #{err}" if err != :SUCCESS
78
+
79
+ np = p_np.read_pointer
80
+ raise NPError, "np_client_new returned a NULL client" if np.null?
81
+ return new(np)
82
+ end
83
+ end
84
+
85
+ def post_notification(notification)
86
+ err = C.np_post_notification(self, notification)
87
+ raise NotificationProxyError, "Notification Proxy Error: #{err}" if err != :SUCCESS
88
+
89
+ return true
90
+ end
91
+
92
+ def observe_notification
93
+ FFI::MemoryPointer.new(:pointer) do |p_notification|
94
+ err = C.np_observe_notification(self, p_notification)
95
+ raise NotificationProxyError, "Notification Proxy Error: #{err}" if err != :SUCCESS
96
+
97
+ notification = p_notification.read_pointer
98
+ unless notification.null?
99
+ ret = notification.read_string
100
+ C.free(notification)
101
+ return ret
102
+ end
103
+ end
104
+ end
105
+
106
+ def observe_notifications
107
+ FFI::MemoryPointer.new(:pointer) do |p_notifications|
108
+ err = C.np_observe_notifications(self, p_notifications)
109
+ raise NotificationProxyError, "Notification Proxy Error: #{err}" if err != :SUCCESS
110
+
111
+ return _unbound_list_to_array(p_notifications)
112
+ end
113
+ end
114
+
115
+ def set_notify_callback(&block)
116
+ err = C.np_set_notify_callback(self, _cb(&block), nil)
117
+ raise NotificationProxyError, "Notification Proxy Error: #{err}" if err != :SUCCESS
118
+
119
+ @notify_callback = block
120
+ return true
121
+ end
122
+
123
+ private
124
+ def _cb
125
+ lambda do |notification, junk|
126
+ yield(notification)
127
+ end
128
+ end
129
+ end
130
+
131
+ # Aliased short name for NotificationProxyClient
132
+ NPClient = NotificationProxyClient
133
+
134
+ module C
135
+ ffi_lib 'imobiledevice'
136
+
137
+ typedef enum(
138
+ :SUCCESS , 0,
139
+ :INVALID_ARG , -1,
140
+ :PLIST_ERROR , -2,
141
+ :CONN_FAILED , -3,
142
+ :UNKNOWN_ERROR, -256,
143
+ ), :np_error_t
144
+
145
+ #np_error_t np_client_new(idevice_t device, lockdownd_service_descriptor_t service, np_client_t *client);
146
+ attach_function :np_client_new, [Idevice, LockdownServiceDescriptor, :pointer], :np_error_t
147
+
148
+ #np_error_t np_client_free(np_client_t client);
149
+ attach_function :np_client_free, [NPClient], :np_error_t
150
+
151
+ #np_error_t np_post_notification(np_client_t client, const char *notification);
152
+ attach_function :np_post_notification, [NPClient, :string], :np_error_t
153
+
154
+ #np_error_t np_observe_notification(np_client_t client, const char *notification);
155
+ attach_function :np_observe_notification, [NPClient, :string], :np_error_t
156
+
157
+ #np_error_t np_observe_notifications(np_client_t client, const char **notification_spec);
158
+ attach_function :np_observe_notifications, [NPClient, :pointer], :np_error_t
159
+
160
+ #/** Reports which notification was received. */
161
+ #typedef void (*np_notify_cb_t) (const char *notification, void *user_data);
162
+ callback :np_notify_cb_t, [:string, :pointer], :void
163
+
164
+ #np_error_t np_set_notify_callback(np_client_t client, np_notify_cb_t notify_cb, void *userdata);
165
+ attach_function :np_set_notify_callback, [NPClient, :np_notify_cb_t, :pointer], :np_error_t
166
+
167
+ end
168
+ end