summaryrefslogtreecommitdiffstats
path: root/src/libirecovery.c
diff options
context:
space:
mode:
authorGravatar Nikias Bassen2013-11-19 20:01:55 +0100
committerGravatar Nikias Bassen2013-11-19 20:01:55 +0100
commit054a79d64e55ce7d9874e65814c5a17caa1ca1f0 (patch)
treec65e45aa558c79533d29eb193362e8263ce8fc41 /src/libirecovery.c
parentf6ee4a8efc3bfad2c2d451e3ad86edaca765ff9f (diff)
downloadlibirecovery-054a79d64e55ce7d9874e65814c5a17caa1ca1f0.tar.gz
libirecovery-054a79d64e55ce7d9874e65814c5a17caa1ca1f0.tar.bz2
remove irecv_get_* functions and provide general irecv_get_device_info()
Diffstat (limited to 'src/libirecovery.c')
-rw-r--r--src/libirecovery.c485
1 files changed, 233 insertions, 252 deletions
diff --git a/src/libirecovery.c b/src/libirecovery.c
index f189838..604a9c4 100644
--- a/src/libirecovery.c
+++ b/src/libirecovery.c
@@ -49,7 +49,7 @@ struct irecv_client_private {
49 int interface; 49 int interface;
50 int alt_interface; 50 int alt_interface;
51 unsigned int mode; 51 unsigned int mode;
52 char serial[256]; 52 struct irecv_device_info device_info;
53#ifndef WIN32 53#ifndef WIN32
54 libusb_device_handle* handle; 54 libusb_device_handle* handle;
55#else 55#else
@@ -191,6 +191,191 @@ static unsigned int dfu_hash_t1[256] = {
191#define dfu_hash_step(a,b) \ 191#define dfu_hash_step(a,b) \
192 a = (dfu_hash_t1[(a & 0xFF) ^ ((unsigned char)b)] ^ (a >> 8)) 192 a = (dfu_hash_t1[(a & 0xFF) ^ ((unsigned char)b)] ^ (a >> 8))
193 193
194static int irecv_get_string_descriptor_ascii(irecv_client_t client, uint8_t desc_index, unsigned char * buffer, int size) {
195#ifndef WIN32
196 return libusb_get_string_descriptor_ascii(client->handle, desc_index, buffer, size);
197#else
198 irecv_error_t ret;
199 unsigned short langid = 0;
200 unsigned char data[255];
201 int di, si;
202 memset(data, 0, sizeof(data));
203 memset(buffer, 0, size);
204
205 ret = irecv_usb_control_transfer(client, 0x80, 0x06, (0x03 << 8) | desc_index, langid, data, sizeof(data), USB_TIMEOUT);
206
207 if (ret < 0) return ret;
208 if (data[1] != 0x03) return IRECV_E_UNKNOWN_ERROR;
209 if (data[0] > ret) return IRECV_E_UNKNOWN_ERROR;
210
211 for (di = 0, si = 2; si < data[0]; si += 2) {
212 if (di >= (size - 1)) break;
213 if (data[si + 1]) {
214 /* high byte */
215 buffer[di++] = '?';
216 } else {
217 buffer[di++] = data[si];
218 }
219 }
220 buffer[di] = 0;
221
222 return di;
223#endif
224}
225
226static void irecv_load_device_info_from_iboot_string(irecv_client_t client, const char* iboot_string)
227{
228 if (!client || !iboot_string) {
229 return;
230 }
231
232 memset(&client->device_info, '\0', sizeof(struct irecv_device_info));
233
234 char* ptr;
235
236 ptr = strstr(iboot_string, "CPID:");
237 if (ptr != NULL) {
238 sscanf(ptr, "CPID:%x", &client->device_info.cpid);
239 }
240
241 ptr = strstr(iboot_string, "CPRV:");
242 if (ptr != NULL) {
243 sscanf(ptr, "CPRV:%x", &client->device_info.cprv);
244 }
245
246 ptr = strstr(iboot_string, "CPFM:");
247 if (ptr != NULL) {
248 sscanf(ptr, "CPFM:%x", &client->device_info.cpfm);
249 }
250
251 ptr = strstr(iboot_string, "SCEP:");
252 if (ptr != NULL) {
253 sscanf(ptr, "SCEP:%x", &client->device_info.scep);
254 }
255
256 ptr = strstr(iboot_string, "BDID:");
257 if (ptr != NULL) {
258 sscanf(ptr, "BDID:%x", &client->device_info.bdid);
259 }
260
261 ptr = strstr(iboot_string, "ECID:");
262 if (ptr != NULL) {
263 sscanf(ptr, "ECID:" _FMT_qX, &client->device_info.ecid);
264 }
265
266 ptr = strstr(iboot_string, "IBFL:");
267 if (ptr != NULL) {
268 sscanf(ptr, "IBFL:%x", &client->device_info.ibfl);
269 }
270
271 char tmp[256];
272 tmp[0] = '\0';
273 ptr = strstr(iboot_string, "SRNM:[");
274 if(ptr != NULL) {
275 sscanf(ptr, "SRNM:[%s]", tmp);
276 ptr = strrchr(tmp, ']');
277 if(ptr != NULL) {
278 *ptr = '\0';
279 }
280 client->device_info.srnm = strdup(tmp);
281 }
282
283 tmp[0] = '\0';
284 ptr = strstr(iboot_string, "IMEI:[");
285 if(ptr != NULL) {
286 sscanf(ptr, "IMEI:[%s]", tmp);
287 ptr = strrchr(tmp, ']');
288 if(ptr != NULL) {
289 *ptr = '\0';
290 }
291 client->device_info.imei = strdup(tmp);
292 }
293}
294
295static void irecv_copy_nonce_with_tag(irecv_client_t client, const char* tag, unsigned char** nonce, unsigned int* nonce_size)
296{
297 if (!client || !tag) {
298 return;
299 }
300
301 char buf[255];
302 int len;
303
304 *nonce = NULL;
305 *nonce_size = 0;
306
307 len = irecv_get_string_descriptor_ascii(client, 1, (unsigned char*) buf, 255);
308 debug("%s: got length: %d\n", __func__, len);
309 if (len < 0) {
310 return;
311 }
312
313 buf[len] = 0;
314 debug("%s: buf='%s' tag='%s'\n", __func__, buf, tag);
315
316 int taglen = strlen(tag);
317 int nlen = 0;
318 char* nonce_string = NULL;
319 char* p = buf;
320 char* colon = NULL;
321 do {
322 colon = strchr(p, ':');
323 if (!colon)
324 break;
325 if (colon-taglen < p) {
326 break;
327 }
328 char *space = strchr(colon, ' ');
329 if (strncmp(colon-taglen, tag, taglen) == 0) {
330 p = colon+1;
331 if (!space) {
332 nlen = strlen(p);
333 } else {
334 nlen = space-p;
335 }
336 nonce_string = p;
337 nlen/=2;
338 break;
339 } else {
340 if (!space) {
341 break;
342 } else {
343 p = space+1;
344 }
345 }
346 } while (colon);
347
348 if (nlen == 0) {
349 debug("%s: ERROR: couldn't find tag %s in string %s\n", __func__, tag, buf);
350 return;
351 }
352
353 unsigned char *nn = malloc(nlen);
354 if (!nn) {
355 return;
356 }
357
358 int i = 0;
359 for (i = 0; i < nlen; i++) {
360 int val = 0;
361 if (sscanf(nonce_string+(i*2), "%02X", &val) == 1) {
362 nn[i] = (unsigned char)val;
363 } else {
364 debug("%s: ERROR: unexpected data in nonce result (%2s)\n", __func__, nonce_string+(i*2));
365 break;
366 }
367 }
368
369 if (i != nlen) {
370 debug("%s: ERROR: unable to parse nonce\n", __func__);
371 free(nn);
372 return;
373 }
374
375 *nonce = nn;
376 *nonce_size = nlen;
377}
378
194#ifdef WIN32 379#ifdef WIN32
195static const GUID GUID_DEVINTERFACE_IBOOT = {0xED82A167L, 0xD61A, 0x4AF6, {0x9A, 0xB6, 0x11, 0xE5, 0x22, 0x36, 0xC5, 0x76}}; 380static const GUID GUID_DEVINTERFACE_IBOOT = {0xED82A167L, 0xD61A, 0x4AF6, {0x9A, 0xB6, 0x11, 0xE5, 0x22, 0x36, 0xC5, 0x76}};
196static const GUID GUID_DEVINTERFACE_DFU = {0xB8085869L, 0xFEB9, 0x404B, {0x8C, 0xB1, 0x1E, 0x5C, 0x14, 0xFA, 0x8C, 0x54}}; 381static const GUID GUID_DEVINTERFACE_DFU = {0xB8085869L, 0xFEB9, 0x404B, {0x8C, 0xB1, 0x1E, 0x5C, 0x14, 0xFA, 0x8C, 0x54}};
@@ -262,37 +447,31 @@ irecv_error_t mobiledevice_connect(irecv_client_t* client, unsigned long long ec
262 continue; 447 continue;
263 } 448 }
264 449
265 _client->serial[0] = '\0'; 450 char* serial_str[256];
266 if ((sscanf(result, "\\\\?\\usb#vid_%*04x&pid_%*04x#%s#", _client->serial) != 1) || (_client->serial[0] == '\0')) { 451 serial_str[0] = '\0';
452 if ((sscanf(result, "\\\\?\\usb#vid_%*04x&pid_%*04x#%s#", serial_str) != 1) || (serial_str[0] == '\0')) {
267 mobiledevice_closepipes(_client); 453 mobiledevice_closepipes(_client);
268 continue; 454 continue;
269 } 455 }
270 456
271 char* p = strchr(_client->serial, '#'); 457 char* p = strchr(serial_str, '#');
272 if (p) { 458 if (p) {
273 *p = '\0'; 459 *p = '\0';
274 } 460 }
275 461
276 int j; 462 int j;
277 for (j = 0; j < strlen(_client->serial); j++) { 463 for (j = 0; j < strlen(serial_str); j++) {
278 if (_client->serial[j] == '_') { 464 if (serial_str[j] == '_') {
279 _client->serial[j] = ' '; 465 serial_str[j] = ' ';
280 } else { 466 } else {
281 _client->serial[j] = toupper(_client->serial[j]); 467 serial_str[j] = toupper(serial_str[j]);
282 } 468 }
283 } 469 }
284 470
285 if (ecid != 0) { 471 irecv_load_device_info_from_iboot_string(_client, serial_str);
286 char* ecid_string = strstr(_client->serial, "ECID:");
287 if (ecid_string == NULL) {
288 debug("%s: could not get ECID for device\n", __func__);
289 mobiledevice_closepipes(_client);
290 continue;
291 }
292 472
293 unsigned long long this_ecid = 0; 473 if (ecid != 0) {
294 sscanf(ecid_string, "ECID:" _FMT_qX, (unsigned long long*)&this_ecid); 474 if (_client->device_info.ecid != ecid) {
295 if (this_ecid != ecid) {
296 mobiledevice_closepipes(_client); 475 mobiledevice_closepipes(_client);
297 continue; 476 continue;
298 } 477 }
@@ -344,37 +523,29 @@ irecv_error_t mobiledevice_connect(irecv_client_t* client, unsigned long long ec
344 continue; 523 continue;
345 } 524 }
346 525
347 _client->serial[0] = '\0'; 526 char serial_str[256];
348 if ((sscanf(result, "\\\\?\\usb#vid_%*04x&pid_%*04x#%s#", _client->serial) != 1) || (_client->serial[0] == '\0')) { 527 serial_str[0] = '\0';
528 if ((sscanf(result, "\\\\?\\usb#vid_%*04x&pid_%*04x#%s#", serial_str) != 1) || (serial_str[0] == '\0')) {
349 mobiledevice_closepipes(_client); 529 mobiledevice_closepipes(_client);
350 continue; 530 continue;
351 } 531 }
352 532
353 char* p = strchr(_client->serial, '#'); 533 char* p = strchr(serial_str, '#');
354 if (p) { 534 if (p) {
355 *p = '\0'; 535 *p = '\0';
356 } 536 }
357 537
358 int j; 538 int j;
359 for (j = 0; j < strlen(_client->serial); j++) { 539 for (j = 0; j < strlen(serial_str); j++) {
360 if (_client->serial[j] == '_') { 540 if (serial_str[j] == '_') {
361 _client->serial[j] = ' '; 541 serial_str[j] = ' ';
362 } else { 542 } else {
363 _client->serial[j] = toupper(_client->serial[j]); 543 serial_str[j] = toupper(serial_str[j]);
364 } 544 }
365 } 545 }
366 546
367 if (ecid != 0) { 547 if (ecid != 0) {
368 char* ecid_string = strstr(_client->serial, "ECID:"); 548 if (_client->device_info.ecid != ecid) {
369 if (ecid_string == NULL) {
370 debug("%s: could not get ECID for device\n", __func__);
371 mobiledevice_closepipes(_client);
372 continue;
373 }
374
375 unsigned long long this_ecid = 0;
376 sscanf(ecid_string, "ECID:" _FMT_qX, (unsigned long long*)&this_ecid);
377 if (this_ecid != ecid) {
378 mobiledevice_closepipes(_client); 549 mobiledevice_closepipes(_client);
379 continue; 550 continue;
380 } 551 }
@@ -538,38 +709,6 @@ int irecv_usb_bulk_transfer(irecv_client_t client,
538 return ret; 709 return ret;
539} 710}
540 711
541static int irecv_get_string_descriptor_ascii(irecv_client_t client, uint8_t desc_index, unsigned char * buffer, int size) {
542#ifndef WIN32
543 return libusb_get_string_descriptor_ascii(client->handle, desc_index, buffer, size);
544#else
545 irecv_error_t ret;
546 unsigned short langid = 0;
547 unsigned char data[255];
548 int di, si;
549 memset(data, 0, sizeof(data));
550 memset(buffer, 0, size);
551
552 ret = irecv_usb_control_transfer(client, 0x80, 0x06, (0x03 << 8) | desc_index, langid, data, sizeof(data), USB_TIMEOUT);
553
554 if (ret < 0) return ret;
555 if (data[1] != 0x03) return IRECV_E_UNKNOWN_ERROR;
556 if (data[0] > ret) return IRECV_E_UNKNOWN_ERROR;
557
558 for (di = 0, si = 2; si < data[0]; si += 2) {
559 if (di >= (size - 1)) break;
560 if (data[si + 1]) {
561 /* high byte */
562 buffer[di++] = '?';
563 } else {
564 buffer[di++] = data[si];
565 }
566 }
567 buffer[di] = 0;
568
569 return di;
570#endif
571}
572
573irecv_error_t irecv_open_with_ecid(irecv_client_t* pclient, unsigned long long ecid) { 712irecv_error_t irecv_open_with_ecid(irecv_client_t* pclient, unsigned long long ecid) {
574 if(libirecovery_debug) { 713 if(libirecovery_debug) {
575 irecv_set_debug_level(libirecovery_debug); 714 irecv_set_debug_level(libirecovery_debug);
@@ -637,11 +776,16 @@ irecv_error_t irecv_open_with_ecid(irecv_client_t* pclient, unsigned long long e
637 client->handle = usb_handle; 776 client->handle = usb_handle;
638 client->mode = usb_descriptor.idProduct; 777 client->mode = usb_descriptor.idProduct;
639 778
640 /* cache usb serial */ 779 char serial_str[256];
641 irecv_get_string_descriptor_ascii(client, usb_descriptor.iSerialNumber, (unsigned char*) client->serial, 255); 780 irecv_get_string_descriptor_ascii(client, usb_descriptor.iSerialNumber, (unsigned char*)serial_str, 255);
781
782 irecv_load_device_info_from_iboot_string(client, serial_str);
783
784 irecv_copy_nonce_with_tag(client, "NONC", &client->device_info.ap_nonce, &client->device_info.ap_nonce_size);
785 irecv_copy_nonce_with_tag(client, "SNON", &client->device_info.sep_nonce, &client->device_info.sep_nonce_size);
642 786
643 if (ecid != 0) { 787 if (ecid != 0) {
644 char* ecid_string = strstr(client->serial, "ECID:"); 788 char* ecid_string = strstr(serial_str, "ECID:");
645 if (ecid_string == NULL) { 789 if (ecid_string == NULL) {
646 debug("%s: could not get ECID for device\n", __func__); 790 debug("%s: could not get ECID for device\n", __func__);
647 irecv_close(client); 791 irecv_close(client);
@@ -870,6 +1014,18 @@ irecv_error_t irecv_close(irecv_client_t client) {
870 } 1014 }
871 mobiledevice_closepipes(client); 1015 mobiledevice_closepipes(client);
872#endif 1016#endif
1017 if (client->device_info.srnm) {
1018 free(client->device_info.srnm);
1019 }
1020 if (client->device_info.imei) {
1021 free(client->device_info.imei);
1022 }
1023 if (client->device_info.ap_nonce) {
1024 free(client->device_info.ap_nonce);
1025 }
1026 if (client->device_info.sep_nonce) {
1027 free(client->device_info.sep_nonce);
1028 }
873 free(client); 1029 free(client);
874 client = NULL; 1030 client = NULL;
875 } 1031 }
@@ -1216,186 +1372,12 @@ irecv_error_t irecv_get_mode(irecv_client_t client, int* mode) {
1216 return IRECV_E_SUCCESS; 1372 return IRECV_E_SUCCESS;
1217} 1373}
1218 1374
1219irecv_error_t irecv_get_cpid(irecv_client_t client, unsigned int* cpid) { 1375const struct irecv_device_info* irecv_get_device_info(irecv_client_t client)
1376{
1220 if (check_context(client) != IRECV_E_SUCCESS) 1377 if (check_context(client) != IRECV_E_SUCCESS)
1221 return IRECV_E_NO_DEVICE; 1378 return NULL;
1222
1223 if (client->mode == IRECV_K_WTF_MODE) {
1224 char s_cpid[8] = {0,};
1225 strncpy(s_cpid, client->serial, 4);
1226 if (sscanf(s_cpid, "%x", cpid) != 1) {
1227 *cpid = 0;
1228 return IRECV_E_UNKNOWN_ERROR;
1229 }
1230
1231 return IRECV_E_SUCCESS;
1232 }
1233
1234 char* cpid_string = strstr(client->serial, "CPID:");
1235 if (cpid_string == NULL) {
1236 *cpid = 0;
1237 return IRECV_E_UNKNOWN_ERROR;
1238 }
1239 sscanf(cpid_string, "CPID:%x", cpid);
1240
1241 return IRECV_E_SUCCESS;
1242}
1243
1244irecv_error_t irecv_get_bdid(irecv_client_t client, unsigned int* bdid) {
1245 if (check_context(client) != IRECV_E_SUCCESS)
1246 return IRECV_E_NO_DEVICE;
1247
1248 char* bdid_string = strstr(client->serial, "BDID:");
1249 if (bdid_string == NULL) {
1250 *bdid = 0;
1251 return IRECV_E_UNKNOWN_ERROR;
1252 }
1253 sscanf(bdid_string, "BDID:%x", bdid);
1254
1255 return IRECV_E_SUCCESS;
1256}
1257
1258irecv_error_t irecv_get_ecid(irecv_client_t client, unsigned long long* ecid) {
1259 if (check_context(client) != IRECV_E_SUCCESS)
1260 return IRECV_E_NO_DEVICE;
1261
1262 char* ecid_string = strstr(client->serial, "ECID:");
1263 if (ecid_string == NULL) {
1264 *ecid = 0;
1265 return IRECV_E_UNKNOWN_ERROR;
1266 }
1267 sscanf(ecid_string, "ECID:" _FMT_qX, ecid);
1268
1269 return IRECV_E_SUCCESS;
1270}
1271
1272irecv_error_t irecv_get_srnm(irecv_client_t client, char* srnm) {
1273 if (check_context(client) != IRECV_E_SUCCESS)
1274 return IRECV_E_NO_DEVICE;
1275
1276 char* srnmp;
1277 char* srnm_string = strstr(client->serial, "SRNM:[");
1278 if(srnm_string == NULL) {
1279 *srnm = 0;
1280 return IRECV_E_UNKNOWN_ERROR;
1281 }
1282
1283 sscanf(srnm_string, "SRNM:[%s]", srnm);
1284 srnmp = strrchr(srnm, ']');
1285 if(srnmp != NULL) {
1286 *srnmp = '\0';
1287 }
1288
1289 return IRECV_E_SUCCESS;
1290}
1291
1292irecv_error_t irecv_get_imei(irecv_client_t client, char* imei) {
1293 if (check_context(client) != IRECV_E_SUCCESS)
1294 return IRECV_E_NO_DEVICE;
1295
1296 char* imeip;
1297 char* imei_string = strstr(client->serial, "IMEI:[");
1298 if (imei_string == NULL) {
1299 *imei = 0;
1300 return IRECV_E_UNKNOWN_ERROR;
1301 }
1302
1303
1304 sscanf(imei_string, "IMEI:[%s]", imei);
1305 imeip = strrchr(imei, ']');
1306 if(imeip != NULL) {
1307 *imeip = '\0';
1308 }
1309
1310 return IRECV_E_SUCCESS;
1311}
1312
1313irecv_error_t irecv_get_nonce_with_tag(irecv_client_t client, const char* tag, unsigned char** nonce, int* nonce_size) {
1314 if (check_context(client) != IRECV_E_SUCCESS)
1315 return IRECV_E_NO_DEVICE;
1316
1317 if (tag == NULL) {
1318 return IRECV_E_INVALID_INPUT;
1319 }
1320
1321 char buf[255];
1322 int len;
1323
1324 *nonce = NULL;
1325 *nonce_size = 0;
1326
1327 len = irecv_get_string_descriptor_ascii(client, 1, (unsigned char*) buf, 255);
1328 debug("%s: got length: %d\n", __func__, len);
1329 if (len < 0) {
1330 return len;
1331 }
1332
1333 buf[len] = 0;
1334 debug("%s: buf='%s' tag='%s'\n", __func__, buf, tag);
1335
1336 int taglen = strlen(tag);
1337 int nlen = 0;
1338 char* nonce_string = NULL;
1339 char* p = buf;
1340 char* colon = NULL;
1341 do {
1342 colon = strchr(p, ':');
1343 if (!colon)
1344 break;
1345 if (colon-taglen < p) {
1346 break;
1347 }
1348 char *space = strchr(colon, ' ');
1349 if (strncmp(colon-taglen, tag, taglen) == 0) {
1350 p = colon+1;
1351 if (!space) {
1352 nlen = strlen(p);
1353 } else {
1354 nlen = space-p;
1355 }
1356 nonce_string = p;
1357 nlen/=2;
1358 break;
1359 } else {
1360 if (!space) {
1361 break;
1362 } else {
1363 p = space+1;
1364 }
1365 }
1366 } while (colon);
1367
1368 if (nlen == 0) {
1369 debug("%s: ERROR: couldn't find tag %s in string %s\n", __func__, tag, buf);
1370 return IRECV_E_UNKNOWN_ERROR;
1371 }
1372
1373 unsigned char *nn = malloc(nlen);
1374 if (!nn) {
1375 return IRECV_E_OUT_OF_MEMORY;
1376 }
1377
1378 int i = 0;
1379 for (i = 0; i < nlen; i++) {
1380 int val = 0;
1381 if (sscanf(nonce_string+(i*2), "%02X", &val) == 1) {
1382 nn[i] = (unsigned char)val;
1383 } else {
1384 debug("%s: ERROR: unexpected data in nonce result (%2s)\n", __func__, nonce_string+(i*2));
1385 break;
1386 }
1387 }
1388
1389 if (i != nlen) {
1390 debug("%s: ERROR: unable to parse nonce\n", __func__);
1391 free(nn);
1392 return IRECV_E_UNKNOWN_ERROR;
1393 }
1394
1395 *nonce = nn;
1396 *nonce_size = nlen;
1397 1379
1398 return IRECV_E_SUCCESS; 1380 return &client->device_info;
1399} 1381}
1400 1382
1401irecv_error_t irecv_trigger_limera1n_exploit(irecv_client_t client) { 1383irecv_error_t irecv_trigger_limera1n_exploit(irecv_client_t client) {
@@ -1601,11 +1583,11 @@ irecv_error_t irecv_devices_get_device_by_client(irecv_client_t client, irecv_de
1601 1583
1602 *device = NULL; 1584 *device = NULL;
1603 1585
1604 if (irecv_get_cpid(client, &cpid) < 0) { 1586 if (client->device_info.cpid == 0) {
1605 return IRECV_E_UNKNOWN_ERROR; 1587 return IRECV_E_UNKNOWN_ERROR;
1606 } 1588 }
1607 1589
1608 if (irecv_get_bdid(client, &bdid) < 0) { 1590 if (client->device_info.bdid == 0) {
1609 return IRECV_E_UNKNOWN_ERROR; 1591 return IRECV_E_UNKNOWN_ERROR;
1610 } 1592 }
1611 1593
@@ -1660,8 +1642,7 @@ irecv_client_t irecv_reconnect(irecv_client_t client, int initial_pause) {
1660 irecv_client_t new_client = NULL; 1642 irecv_client_t new_client = NULL;
1661 irecv_event_cb_t progress_callback = client->progress_callback; 1643 irecv_event_cb_t progress_callback = client->progress_callback;
1662 1644
1663 unsigned long long ecid = 0; 1645 unsigned long long ecid = client->device_info.ecid;
1664 irecv_get_ecid(client, &ecid);
1665 1646
1666 if (check_context(client) == IRECV_E_SUCCESS) { 1647 if (check_context(client) == IRECV_E_SUCCESS) {
1667 irecv_close(client); 1648 irecv_close(client);