idevice 1.1.5.0

Sign up to get free protection for your applications and to get access to all the features.
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