summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/debugserver.c177
1 files changed, 85 insertions, 92 deletions
diff --git a/src/debugserver.c b/src/debugserver.c
index 1c20c25..233af4c 100644
--- a/src/debugserver.c
+++ b/src/debugserver.c
@@ -375,130 +375,126 @@ LIBIMOBILEDEVICE_API debugserver_error_t debugserver_client_set_receive_params(d
375 return DEBUGSERVER_E_SUCCESS; 375 return DEBUGSERVER_E_SUCCESS;
376} 376}
377 377
378static int debugserver_client_receive_internal_check(debugserver_client_t client, char* received_char) 378static debugserver_error_t debugserver_client_receive_internal_char(debugserver_client_t client, char* received_char)
379{ 379{
380 debugserver_error_t res = DEBUGSERVER_E_SUCCESS; 380 debugserver_error_t res = DEBUGSERVER_E_SUCCESS;
381 int did_receive_char = 0;
382 char buffer = 0;
383 uint32_t bytes = 0; 381 uint32_t bytes = 0;
384 382
385 /* we loop here as we expect an answer */ 383 /* we loop here as we expect an answer */
386 res = debugserver_client_receive(client, &buffer, sizeof(char), &bytes); 384 res = debugserver_client_receive(client, received_char, sizeof(char), &bytes);
387 if (res == DEBUGSERVER_E_SUCCESS && received_char[0] != 0) { 385 if (res != DEBUGSERVER_E_SUCCESS) {
388 if (memcmp(&buffer, received_char, sizeof(char)) == 0) { 386 return res;
389 did_receive_char = 1;
390 }
391 } else {
392 did_receive_char = 0;
393 } 387 }
394 388 if (bytes != 1) {
395 if (!did_receive_char) { 389 debug_info("received %d bytes when asking for %d!", bytes, sizeof(char));
396 memcpy(received_char, &buffer, sizeof(char)); 390 return DEBUGSERVER_E_UNKNOWN_ERROR;
397 } 391 }
398 392 return res;
399 return did_receive_char;
400} 393}
401 394
402LIBIMOBILEDEVICE_API debugserver_error_t debugserver_client_receive_response(debugserver_client_t client, char** response, size_t* response_size) 395LIBIMOBILEDEVICE_API debugserver_error_t debugserver_client_receive_response(debugserver_client_t client, char** response, size_t* response_size)
403{ 396{
404 debugserver_error_t res = DEBUGSERVER_E_SUCCESS; 397 debugserver_error_t res = DEBUGSERVER_E_SUCCESS;
405 398
406 int should_receive = 1; 399 char data = '\0';
407 int skip_prefix = 0; 400 int skip_prefix = 0;
408 char* command_prefix = strdup("$");
409 401
410 char* buffer = NULL; 402 char* buffer = malloc(1024);
411 uint32_t buffer_size = 0; 403 uint32_t buffer_size = 0;
412 uint32_t buffer_capacity = 0; 404 uint32_t buffer_capacity = 1024;
413 405
414 if (response) 406 if (response)
415 *response = NULL; 407 *response = NULL;
416 408
417 if (!client->noack_mode) { 409 if (!client->noack_mode) {
418 char ack[2] = {'+', '\0'}; 410 debug_info("attempting to receive ACK (+)");
419 debug_info("attempting to receive ACK %c", *ack); 411 res = debugserver_client_receive_internal_char(client, &data);
420 should_receive = debugserver_client_receive_internal_check(client, ack); 412 if (res != DEBUGSERVER_E_SUCCESS) {
421 debug_info("received char: %c", *ack); 413 goto cleanup;
422 if (strncmp(ack, command_prefix, sizeof(char)) == 0) { 414 }
423 should_receive = 1; 415 if (data == '+') {
416 debug_info("received ACK (+)");
417 } else if (data == '$') {
418 debug_info("received prefix ($)");
419 buffer[0] = '$';
420 buffer_size = 1;
424 skip_prefix = 1; 421 skip_prefix = 1;
425 buffer = malloc(1024); 422 } else {
426 buffer_capacity = 1024; 423 debug_info("unrecognized response when looking for ACK: %c", data);
427 strcpy(buffer, command_prefix); 424 goto cleanup;
428 buffer_size += sizeof(char);
429 debug_info("received ACK");
430 } 425 }
431 } 426 }
432 427
433 debug_info("should_receive: %d, skip_prefix: %d", should_receive, skip_prefix); 428 debug_info("skip_prefix: %d", skip_prefix);
434 429
435 if (should_receive && !skip_prefix) { 430 if (!skip_prefix) {
436 debug_info("attempting to receive prefix"); 431 debug_info("attempting to receive prefix ($)");
437 should_receive = debugserver_client_receive_internal_check(client, command_prefix); 432 res = debugserver_client_receive_internal_char(client, &data);
438 debug_info("received command_prefix: %c", *command_prefix); 433 if (res != DEBUGSERVER_E_SUCCESS) {
439 if (should_receive) { 434 goto cleanup;
440 if (buffer) { 435 }
441 strcpy(buffer, command_prefix); 436 if (data == '$') {
442 } else { 437 debug_info("received prefix ($)");
443 buffer = malloc(1024); 438 buffer[0] = '$';
444 buffer_capacity = 1024; 439 buffer_size = 1;
445 strcpy(buffer, command_prefix); 440 } else {
446 buffer_size += sizeof(char); 441 debug_info("unrecognized response when looking for prefix: %c", data);
447 } 442 goto cleanup;
448 } 443 }
449 } 444 }
450 445
451 debug_info("buffer: %*s, should_receive: %d, skip_prefix: %d", buffer_size, buffer, should_receive, skip_prefix); 446 debug_info("buffer: %*s", buffer_size, buffer);
452 447
453 if (should_receive) { 448 uint32_t checksum_length = DEBUGSERVER_CHECKSUM_HASH_LENGTH;
454 uint32_t checksum_length = DEBUGSERVER_CHECKSUM_HASH_LENGTH; 449 int receiving_checksum_response = 0;
455 int receiving_checksum_response = 0; 450 debug_info("attempting to read up response until checksum");
456 debug_info("attempting to read up response until checksum");
457 451
458 while ((checksum_length > 0)) { 452 while ((checksum_length > 0)) {
459 char data[2] = {'#', '\0'}; 453 res = debugserver_client_receive_internal_char(client, &data);
460 if (debugserver_client_receive_internal_check(client, data)) { 454 if (res != DEBUGSERVER_E_SUCCESS) {
461 receiving_checksum_response = 1; 455 goto cleanup;
462 }
463 if (receiving_checksum_response) {
464 checksum_length--;
465 }
466 if (buffer_size + 1 >= buffer_capacity) {
467 char* newbuffer = realloc(buffer, buffer_capacity+1024);
468 if (!newbuffer) {
469 return DEBUGSERVER_E_UNKNOWN_ERROR;
470 }
471 buffer = newbuffer;
472 buffer[buffer_capacity] = '\0';
473 buffer_capacity += 1024;
474 }
475 strcat(buffer, data);
476 buffer_size += sizeof(char);
477 } 456 }
478 debug_info("validating response checksum..."); 457 if (data == '#') {
479 if (client->noack_mode || debugserver_response_is_checksum_valid(buffer, buffer_size)) { 458 receiving_checksum_response = 1;
480 if (response) { 459 }
481 /* assemble response string */ 460 if (receiving_checksum_response) {
482 uint32_t resp_size = sizeof(char) * (buffer_size - DEBUGSERVER_CHECKSUM_HASH_LENGTH - 1); 461 checksum_length--;
483 *response = (char*)malloc(resp_size + 1); 462 }
484 memcpy(*response, buffer + 1, resp_size); 463 if (buffer_size + 1 >= buffer_capacity) {
485 (*response)[resp_size] = '\0'; 464 char* newbuffer = realloc(buffer, buffer_capacity+1024);
486 if (response_size) *response_size = resp_size; 465 if (!newbuffer) {
487 } 466 return DEBUGSERVER_E_UNKNOWN_ERROR;
488 if (!client->noack_mode) {
489 /* confirm valid command */
490 debugserver_client_send_ack(client);
491 }
492 } else {
493 /* response was invalid */
494 res = DEBUGSERVER_E_RESPONSE_ERROR;
495 if (!client->noack_mode) {
496 /* report invalid command */
497 debugserver_client_send_noack(client);
498 } 467 }
468 buffer = newbuffer;
469 buffer_capacity += 1024;
470 }
471 buffer[buffer_size] = data;
472 buffer_size += sizeof(char);
473 }
474 debug_info("validating response checksum...");
475 if (client->noack_mode || debugserver_response_is_checksum_valid(buffer, buffer_size)) {
476 if (response) {
477 /* assemble response string */
478 uint32_t resp_size = sizeof(char) * (buffer_size - DEBUGSERVER_CHECKSUM_HASH_LENGTH - 1);
479 *response = (char*)malloc(resp_size + 1);
480 memcpy(*response, buffer + 1, resp_size);
481 (*response)[resp_size] = '\0';
482 if (response_size) *response_size = resp_size;
483 }
484 if (!client->noack_mode) {
485 /* confirm valid command */
486 debugserver_client_send_ack(client);
487 }
488 } else {
489 /* response was invalid */
490 res = DEBUGSERVER_E_RESPONSE_ERROR;
491 if (!client->noack_mode) {
492 /* report invalid command */
493 debugserver_client_send_noack(client);
499 } 494 }
500 } 495 }
501 496
497cleanup:
502 if (response) { 498 if (response) {
503 debug_info("response: %s", *response); 499 debug_info("response: %s", *response);
504 } 500 }
@@ -506,9 +502,6 @@ LIBIMOBILEDEVICE_API debugserver_error_t debugserver_client_receive_response(deb
506 if (buffer) 502 if (buffer)
507 free(buffer); 503 free(buffer);
508 504
509 if (command_prefix)
510 free(command_prefix);
511
512 return res; 505 return res;
513} 506}
514 507