summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Makefile2
-rw-r--r--include/libirecovery.h7
-rw-r--r--src/irecovery.c15
-rw-r--r--src/libirecovery.c150
4 files changed, 166 insertions, 8 deletions
diff --git a/Makefile b/Makefile
index c7322f1..228b9c3 100644
--- a/Makefile
+++ b/Makefile
@@ -1,4 +1,4 @@
1all: 1all: static
2 @echo "Please choose either macosx, linux, or windows" 2 @echo "Please choose either macosx, linux, or windows"
3 3
4static: 4static:
diff --git a/include/libirecovery.h b/include/libirecovery.h
index b489011..801ad88 100644
--- a/include/libirecovery.h
+++ b/include/libirecovery.h
@@ -24,6 +24,9 @@
24#define IRECV_ERROR_UNABLE_TO_CONNECT -3 24#define IRECV_ERROR_UNABLE_TO_CONNECT -3
25#define IRECV_ERROR_INVALID_INPUT -4 25#define IRECV_ERROR_INVALID_INPUT -4
26#define IRECV_ERROR_UNKNOWN -5 26#define IRECV_ERROR_UNKNOWN -5
27#define IRECV_ERROR_FILE_NOT_FOUND -6
28#define IRECV_ERROR_USB_UPLOAD -7
29#define IRECV_ERROR_USB_STATUS -8
27 30
28enum { 31enum {
29 kAppleId = 0x05AC, 32 kAppleId = 0x05AC,
@@ -44,5 +47,5 @@ int irecv_exit(irecv_device* device);
44int irecv_init(irecv_device** device); 47int irecv_init(irecv_device** device);
45int irecv_reset(irecv_device* device); 48int irecv_reset(irecv_device* device);
46int irecv_close(irecv_device* device); 49int irecv_close(irecv_device* device);
47int irecv_command(irecv_device* device, const char* command); 50int irecv_send_file(irecv_device* device, const char* filename);
48 51int irecv_send_command(irecv_device* device, const char* command);
diff --git a/src/irecovery.c b/src/irecovery.c
index 51320a5..3091319 100644
--- a/src/irecovery.c
+++ b/src/irecovery.c
@@ -22,7 +22,7 @@
22#include <libirecovery.h> 22#include <libirecovery.h>
23 23
24enum { 24enum {
25 kResetDevice, kSendCommand 25 kResetDevice, kSendCommand, kSendFile
26}; 26};
27 27
28void print_usage() { 28void print_usage() {
@@ -51,8 +51,13 @@ int main(int argc, char** argv) {
51 break; 51 break;
52 52
53 case 'c': 53 case 'c':
54 argument = optarg;
55 action = kSendCommand; 54 action = kSendCommand;
55 argument = optarg;
56 break;
57
58 case 'f':
59 action = kSendFile;
60 argument = optarg;
56 break; 61 break;
57 62
58 default: 63 default:
@@ -77,8 +82,12 @@ int main(int argc, char** argv) {
77 irecv_reset(device); 82 irecv_reset(device);
78 break; 83 break;
79 84
85 case kSendFile:
86 irecv_send_file(device, argument);
87 break;
88
80 case kSendCommand: 89 case kSendCommand:
81 irecv_command(device, argument); 90 irecv_send_command(device, argument);
82 break; 91 break;
83 92
84 default: 93 default:
diff --git a/src/libirecovery.c b/src/libirecovery.c
index 85967ec..e3d6eb6 100644
--- a/src/libirecovery.c
+++ b/src/libirecovery.c
@@ -120,7 +120,7 @@ void irecv_set_debug(int level) {
120 irecv_debug = level; 120 irecv_debug = level;
121} 121}
122 122
123int irecv_command(irecv_device* device, const char* command) { 123int irecv_send_command(irecv_device* device, const char* command) {
124 if(device == NULL || device->handle == NULL) { 124 if(device == NULL || device->handle == NULL) {
125 return IRECV_ERROR_NO_DEVICE; 125 return IRECV_ERROR_NO_DEVICE;
126 } 126 }
@@ -138,6 +138,152 @@ int irecv_command(irecv_device* device, const char* command) {
138 return IRECV_SUCCESS; 138 return IRECV_SUCCESS;
139} 139}
140 140
141int irecv_upload(irecv_device* device, const char* filename) { 141int irecv_send_file(irecv_device* device, const char* filename) {
142 FILE* file = fopen(filename, "rb");
143 if (file == NULL) {
144 return IRECV_ERROR_FILE_NOT_FOUND;
145 }
146
147 fseek(file, 0, SEEK_END);
148 int length = ftell(file);
149 fseek(file, 0, SEEK_SET);
150
151 unsigned char* buffer = (unsigned char*) malloc(length);
152 if (buffer == NULL) {
153 fclose(file);
154 return IRECV_ERROR_OUT_OF_MEMORY;
155 }
156
157 int bytes = fread(buffer, 1, length, file);
158 fclose(file);
159
160 if(bytes != length) {
161 free(buffer);
162 return IRECV_ERROR_UNKNOWN;
163 }
164
165 return irecv_send_buffer(device, buffer, length);
166}
167
168unsigned int irecv_get_status(irecv_device* device) {
169 unsigned char status[6];
170 memset(status, '\0', 6);
171 if(libusb_control_transfer(device->handle, 0xA1, 3, 0, 0, status, 6, 500) != 6) {
172 return IRECV_ERROR_USB_STATUS;
173 }
174 return (unsigned int) status[4];
175}
176
177int irecv_send_buffer(irecv_device* device, unsigned char* buffer, int length) {
178 int packets = length / 0x800;
179 if (length % 0x800) {
180 packets++;
181 }
182
183 int last = length % 0x800;
184 if (!last) {
185 last = 0x800;
186 }
187
188 int i = 0;
189 char status[6];
190 for (i = 0; i < packets; i++) {
191 int size = i + 1 < packets ? 0x800 : last;
192 int bytes = libusb_control_transfer(device->handle, 0x21, 1, i, 0, &buffer[i * 0x800], size, 500);
193 if (bytes != size) {
194 free(buffer);
195 return IRECV_ERROR_USB_UPLOAD;
196 }
197
198 if (irecv_get_status(device) != 5) {
199 free(buffer);
200 return IRECV_ERROR_USB_STATUS;
201 }
202 }
203
204 libusb_control_transfer(device->handle, 0x21, 1, i, 0, buffer, 0, 1000);
205 for (i = 6; i <= 8; i++) {
206 if (irecv_get_status(device) != i) {
207 free(buffer);
208 return IRECV_ERROR_USB_STATUS;
209 }
210 }
211
212 free(buffer);
142 return IRECV_SUCCESS; 213 return IRECV_SUCCESS;
143} 214}
215
216/*
217int send_file(struct libusb_device_handle *handle, const char* filename, int loadOffset) {
218 FILE* file = fopen(filename, "rb");
219 if (file == NULL) {
220 printf("send_file: File %s not found.\n", filename);
221 return -1;
222 }
223
224 fseek(file, 0, SEEK_END);
225 int len = ftell(file);
226 fseek(file, 0, SEEK_SET);
227
228 char* buffer = malloc(len + loadOffset);
229 if (buffer == NULL) {
230 printf("send_file: Error allocating memory!\n");
231 fclose(file);
232 return -1;
233 }
234
235 fread(&buffer[loadOffset], 1, len, file);
236 fclose(file);
237
238 len += loadOffset;
239
240 int packets = len / 0x800;
241 if (len % 0x800) {
242 packets++;
243 }
244
245 int last = len % 0x800;
246 if (!last) {
247 last = 0x800;
248 }
249
250 int i = 0;
251 char response[6];
252 for (i = 0; i < packets; i++) {
253 int size = i + 1 < packets ? 0x800 : last;
254
255 if (!libusb_control_transfer(handle, 0x21, 1, i, 0, &buffer[i * 0x800], size, 1000)) {
256 printf("send_file: Error sending packet!\n");
257 return -1;
258 }
259
260 if (libusb_control_transfer(handle, 0xA1, 3, 0, 0, response, 6, 1000) != 6) {
261 printf("send_file: Error receiving status!\n");
262 return -1;
263
264 } else {
265 if (response[4] != 5) {
266 printf("send_file: Status error!\n");
267 return -1;
268 }
269 }
270 }
271
272 libusb_control_transfer(handle, 0x21, 1, i, 0, buffer, 0, 1000);
273 for (i = 6; i <= 8; i++) {
274 if (libusb_control_transfer(handle, 0xA1, 3, 0, 0, response, 6, 1000) != 6) {
275 printf("send_file: Error receiving status!\n");
276 return -1;
277
278 } else {
279 if (response[4] != i) {
280 printf("send_file: Status error!\n");
281 return -1;
282 }
283 }
284 }
285
286 free(buffer);
287 return 0;
288}
289*/