summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorGravatar Hao Zhou2014-12-09 11:16:40 +0800
committerGravatar Hao Zhou2014-12-09 11:16:40 +0800
commitc86c7b572949af76becd113230bc1784aadb1eb0 (patch)
tree6157dc25a61eccb5e48d1e8a2900362206b20685
parent83c45ae97ffb8db73b92ccbf1e89443fefbcb937 (diff)
downloadlibimobiledevice-c86c7b572949af76becd113230bc1784aadb1eb0.tar.gz
libimobiledevice-c86c7b572949af76becd113230bc1784aadb1eb0.tar.bz2
cython: Add DebugServerClient class to communicate with debugserver
-rw-r--r--cython/Makefile.am3
-rw-r--r--cython/debugserver.pxi247
-rw-r--r--cython/imobiledevice.pyx1
3 files changed, 250 insertions, 1 deletions
diff --git a/cython/Makefile.am b/cython/Makefile.am
index 0261bfa..94ff728 100644
--- a/cython/Makefile.am
+++ b/cython/Makefile.am
@@ -24,7 +24,8 @@ PXIINCLUDES = \
24 misagent.pxi \ 24 misagent.pxi \
25 house_arrest.pxi \ 25 house_arrest.pxi \
26 restore.pxi \ 26 restore.pxi \
27 mobile_image_mounter.pxi 27 mobile_image_mounter.pxi \
28 debugserver.pxi
28 29
29CLEANFILES = \ 30CLEANFILES = \
30 *.pyc \ 31 *.pyc \
diff --git a/cython/debugserver.pxi b/cython/debugserver.pxi
new file mode 100644
index 0000000..ddbe066
--- /dev/null
+++ b/cython/debugserver.pxi
@@ -0,0 +1,247 @@
1cdef extern from "libimobiledevice/debugserver.h":
2 cdef struct debugserver_client_private:
3 pass
4 ctypedef debugserver_client_private *debugserver_client_t
5 cdef struct debugserver_command_private:
6 pass
7 ctypedef debugserver_command_private *debugserver_command_t
8 ctypedef enum debugserver_error_t:
9 DEBUGSERVER_E_SUCCESS = 0
10 DEBUGSERVER_E_INVALID_ARG = -1
11 DEBUGSERVER_E_MUX_ERROR = -2
12 DEBUGSERVER_E_SSL_ERROR = -3
13 DEBUGSERVER_E_RESPONSE_ERROR = -4
14 DEBUGSERVER_E_UNKNOWN_ERROR = -256
15
16 debugserver_error_t debugserver_client_new(idevice_t device, lockdownd_service_descriptor_t service, debugserver_client_t * client)
17 debugserver_error_t debugserver_client_free(debugserver_client_t client)
18
19 debugserver_error_t debugserver_client_send(debugserver_client_t client, const char* data, uint32_t size, uint32_t *sent)
20 debugserver_error_t debugserver_client_send_command(debugserver_client_t client, debugserver_command_t command, char** response)
21 debugserver_error_t debugserver_client_receive(debugserver_client_t client, char *data, uint32_t size, uint32_t *received)
22 debugserver_error_t debugserver_client_receive_with_timeout(debugserver_client_t client, char *data, uint32_t size, uint32_t *received, unsigned int timeout)
23 debugserver_error_t debugserver_client_receive_response(debugserver_client_t client, char** response)
24 debugserver_error_t debugserver_client_set_argv(debugserver_client_t client, int argc, char* argv[], char** response)
25 debugserver_error_t debugserver_client_set_environment_hex_encoded(debugserver_client_t client, const char* env, char** response)
26
27 debugserver_error_t debugserver_command_new(const char* name, int argc, const char* argv[], debugserver_command_t* command)
28 debugserver_error_t debugserver_command_free(debugserver_command_t command)
29 void debugserver_encode_string(const char* buffer, char** encoded_buffer, uint32_t* encoded_length)
30 void debugserver_decode_string(const char *encoded_buffer, size_t encoded_length, char** buffer)
31
32
33cdef class DebugServerError(BaseError):
34 def __init__(self, *args, **kwargs):
35 self._lookup_table = {
36 DEBUGSERVER_E_SUCCESS: "Success",
37 DEBUGSERVER_E_INVALID_ARG: "Invalid argument",
38 DEBUGSERVER_E_MUX_ERROR: "MUX error",
39 DEBUGSERVER_E_SSL_ERROR: "SSL error",
40 DEBUGSERVER_E_RESPONSE_ERROR: "Response error",
41 DEBUGSERVER_E_UNKNOWN_ERROR: "Unknown error",
42 }
43 BaseError.__init__(self, *args, **kwargs)
44
45
46# from http://stackoverflow.com/a/17511714
47from cpython.string cimport PyString_AsString
48cdef char ** to_cstring_array(list_str):
49 if not list_str:
50 return NULL
51 cdef char **ret = <char **>malloc(len(list_str) * sizeof(char *))
52 for i in xrange(len(list_str)):
53 ret[i] = PyString_AsString(list_str[i])
54 return ret
55
56
57cdef class DebugServerCommand(Base):
58 cdef debugserver_command_t _c_command
59
60 def __init__(self, bytes name, int argc = 0, argv = None, *args, **kwargs):
61 cdef:
62 char* c_name = name
63 char** c_argv = to_cstring_array(argv)
64
65 try:
66 self.handle_error(debugserver_command_new(c_name, argc, c_argv, &self._c_command))
67 except BaseError, e:
68 raise
69 finally:
70 free(c_argv)
71
72 def __enter__(self):
73 return self
74
75 def __exit__(self, type, value, traceback):
76 self.free()
77
78 cdef free(self):
79 cdef debugserver_error_t err
80 if self._c_command is not NULL:
81 err = debugserver_command_free(self._c_command)
82 self.handle_error(err)
83
84 cdef inline BaseError _error(self, int16_t ret):
85 return DebugServerError(ret)
86
87
88cdef class DebugServerClient(BaseService):
89 __service_name__ = "com.apple.debugserver"
90 cdef debugserver_client_t _c_client
91
92 def __cinit__(self, iDevice device = None, LockdownServiceDescriptor descriptor = None, *args, **kwargs):
93 if (device is not None and descriptor is not None):
94 self.handle_error(debugserver_client_new(device._c_dev, descriptor._c_service_descriptor, &(self._c_client)))
95
96 def __dealloc__(self):
97 cdef debugserver_error_t err
98 if self._c_client is not NULL:
99 err = debugserver_client_free(self._c_client)
100 self.handle_error(err)
101
102 cdef BaseError _error(self, int16_t ret):
103 return DebugServerError(ret)
104
105 cpdef uint32_t send(self, bytes data):
106 cdef:
107 uint32_t bytes_send
108 char* c_data = data
109 try:
110 self.handle_error(debugserver_client_send(self._c_client, c_data, len(data), &bytes_send))
111 except BaseError, e:
112 raise
113
114 return bytes_send
115
116 cpdef bytes send_command(self, DebugServerCommand command):
117 cdef:
118 char* c_response = NULL
119 bytes result
120
121 try:
122 self.handle_error(debugserver_client_send_command(self._c_client, command._c_command, &c_response))
123 if c_response:
124 result = c_response
125 return result
126 else:
127 return None
128 except BaseError, e:
129 raise
130 finally:
131 free(c_response)
132
133 cpdef bytes receive(self, uint32_t size):
134 cdef:
135 uint32_t bytes_received
136 char* c_data = <char *>malloc(size)
137 bytes result
138
139 try:
140 self.handle_error(debugserver_client_receive(self._c_client, c_data, size, &bytes_received))
141 result = c_data[:bytes_received]
142 return result
143 except BaseError, e:
144 raise
145 finally:
146 free(c_data)
147
148 cpdef bytes receive_with_timeout(self, uint32_t size, unsigned int timeout):
149 cdef:
150 uint32_t bytes_received
151 char* c_data = <char *>malloc(size)
152 bytes result
153
154 try:
155 self.handle_error(debugserver_client_receive_with_timeout(self._c_client, c_data, size, &bytes_received, timeout))
156 result = c_data[:bytes_received]
157 return result
158 except BaseError, e:
159 raise
160 finally:
161 free(c_data)
162
163 cpdef bytes receive_response(self):
164 cdef:
165 char* c_response = NULL
166 bytes result
167
168 try:
169 self.handle_error(debugserver_client_receive_response(self._c_client, &c_response))
170 if c_response:
171 result = c_response
172 return result
173 else:
174 return None
175 except BaseError, e:
176 raise
177 finally:
178 free(c_response)
179
180 cpdef bytes set_argv(self, int argc, argv):
181 cdef:
182 char** c_argv = to_cstring_array(argv)
183 char* c_response = NULL
184 bytes result
185
186 try:
187 self.handle_error(debugserver_client_set_argv(self._c_client, argc, c_argv, &c_response))
188 if c_response:
189 result = c_response
190 return result
191 else:
192 return None
193 except BaseError, e:
194 raise
195 finally:
196 free(c_argv)
197 free(c_response)
198
199 cpdef bytes set_environment_hex_encoded(self, bytes env):
200 cdef:
201 char* c_env = env
202 char* c_response = NULL
203 bytes result
204
205 try:
206 self.handle_error(debugserver_client_set_environment_hex_encoded(self._c_client, c_env, &c_response))
207 if c_response:
208 result = c_response
209 return result
210 else:
211 return None
212 except BaseError, e:
213 raise
214 finally:
215 free(c_response)
216
217 cpdef bytes encode_string(self, bytes buffer):
218 cdef:
219 char *c_buffer = buffer
220 uint32_t encoded_length = len(c_buffer) * 2 + 0x3 + 1
221 char* c_encoded_buffer = <char *>malloc(encoded_length)
222 bytes result
223
224 try:
225 debugserver_encode_string(c_buffer, &c_encoded_buffer, &encoded_length)
226 result = c_encoded_buffer[:encoded_length]
227 return result
228 except BaseError, e:
229 raise
230 finally:
231 free(c_encoded_buffer)
232
233 cpdef bytes decode_string(self, bytes encoded_buffer):
234 cdef:
235 char* c_encoded_buffer = encoded_buffer
236 uint32_t encoded_length = len(c_encoded_buffer)
237 char *c_buffer = <char *>malloc(encoded_length)
238 bytes result
239
240 try:
241 debugserver_decode_string(c_encoded_buffer, encoded_length, &c_buffer)
242 result = c_buffer
243 return result
244 except BaseError, e:
245 raise
246 finally:
247 free(c_buffer)
diff --git a/cython/imobiledevice.pyx b/cython/imobiledevice.pyx
index 607ff2f..e011223 100644
--- a/cython/imobiledevice.pyx
+++ b/cython/imobiledevice.pyx
@@ -256,3 +256,4 @@ include "diagnostics_relay.pxi"
256include "misagent.pxi" 256include "misagent.pxi"
257include "house_arrest.pxi" 257include "house_arrest.pxi"
258include "restore.pxi" 258include "restore.pxi"
259include "debugserver.pxi"