Skip to content

Commit

Permalink
Add r->response_wait_default, improve ptp_download_object
Browse files Browse the repository at this point in the history
  • Loading branch information
petabyt committed Feb 3, 2024
1 parent 7cad9de commit 8cfe9ba
Show file tree
Hide file tree
Showing 6 changed files with 42 additions and 26 deletions.
4 changes: 3 additions & 1 deletion src/bind.c
Original file line number Diff line number Diff line change
Expand Up @@ -502,7 +502,9 @@ int bind_get_partial_object(struct BindReq *bind, struct PtpRuntime *r) {
}

int bind_download_file(struct BindReq *bind, struct PtpRuntime *r) {
int x = ptp_download_file(r, bind->params[0], bind->string);
FILE *f = fopen(bind->string, "wb");
int x = ptp_download_object(r, bind->params[0],f, 0x100000);
fclose(f);
if (x < 0) {
return sprintf(bind->buffer, "{\"error\": %d}", -1);
} else {
Expand Down
7 changes: 7 additions & 0 deletions src/camlib.h
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,9 @@ enum PtpGeneralError {
PTP_CHECK_CODE = -8,
};

/// @brief Evaluates PtpGeneralError into string message
const char *ptp_perror(int rc);

enum PtpLiveViewType {
PTP_LV_NONE = 0,
PTP_LV_EOS = 1,
Expand Down Expand Up @@ -134,8 +137,12 @@ struct PtpRuntime {
pthread_mutex_t *mutex;

/// @brief Optionally wait up to 256 seconds for a response. Some PTP operations require this, such as EOS capture.
/// @note Not thread safe. Will be reset after each operation.
uint8_t wait_for_response;

/// @brief Default value for wait_for_response.
uint8_t response_wait_default;

/// @brief For devices that implement it, this will hold a linked list of properties and an array of their supported values.
/// generic_ functions will reject set property calls if an invalid value is written.
struct PtpPropAvail *avail;
Expand Down
2 changes: 1 addition & 1 deletion src/cl_ops.h
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ int ptp_get_thumbnail(struct PtpRuntime *r, int handle);
/// @note Not thread safe.
int ptp_get_partial_object(struct PtpRuntime *r, uint32_t handle, int offset, int max);
/// @brief Download an object from handle, to a local file (uses GetPartialObject)
int ptp_download_file(struct PtpRuntime *r, int handle, char *file);
int ptp_download_object(struct PtpRuntime *r, int handle, FILE *stream, size_t max);
/// @brief Recieve a generic list of all properties received in DeviceInfo
/// This is similar to getting all events, but for first startup when you know nothing.
/// Some vendors do this, but this gets all the properties manually.
Expand Down
16 changes: 16 additions & 0 deletions src/lib.c
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ void ptp_reset(struct PtpRuntime *r) {
r->transaction = 0;
r->session = 0;
r->connection_type = PTP_USB;
r->response_wait_default = 1;
r->wait_for_response = 1;
}

Expand Down Expand Up @@ -281,6 +282,21 @@ int ptp_check_prop(struct PtpRuntime *r, int code) {
return 0;
}

const char *ptp_perror(int rc) {
switch (rc) {
case PTP_OK: return "OK";
case PTP_NO_DEVICE: return "No device found";
case PTP_NO_PERM: return "Lacking permissions";
case PTP_OPEN_FAIL: return "Failed opening device";
case PTP_OUT_OF_MEM: return "Out of memory";
case PTP_IO_ERR: return "I/O Error";
case PTP_RUNTIME_ERR: return "Runtime error";
case PTP_UNSUPPORTED: return "Unsupported operation";
case PTP_CHECK_CODE: return "Check code";
default: return "?";
}
}

int ptp_dump(struct PtpRuntime *r) {
FILE *f = fopen("DUMP", "w");
fwrite(r->data, r->data_length, 1, f);
Expand Down
33 changes: 12 additions & 21 deletions src/operations.c
Original file line number Diff line number Diff line change
Expand Up @@ -322,40 +322,31 @@ int ptp_get_object(struct PtpRuntime *r, int handle) {
return ptp_send(r, &cmd);
}

int ptp_download_file(struct PtpRuntime *r, int handle, char *file) {
int max = ptp_get_payload_length(r);

struct PtpObjectInfo oi;
if (ptp_get_object_info(r, handle, &oi)) {
return 0;
}

max = oi.compressed_size;

FILE *f = fopen(file, "w");
if (f == NULL) {
return PTP_RUNTIME_ERR;
}

int ptp_download_object(struct PtpRuntime *r, int handle, FILE *f, size_t max) {
int read = 0;
while (1) {
ptp_mutex_keep_locked(r);
int x = ptp_get_partial_object(r, handle, read, max);
if (x) {
fclose(f);
ptp_mutex_unlock(r);
return x;
}

if (ptp_get_payload_length(r) == 0) {
size_t partial_len = ptp_get_payload_length(r);

if (partial_len == 0) {
fclose(f);
ptp_mutex_unlock(r);
return 0;
}

fwrite(ptp_get_payload(r), 1, ptp_get_payload_length(r), f);
fwrite(ptp_get_payload(r), 1, partial_len, f);

read += ptp_get_payload_length(r);
ptp_mutex_unlock(r);

if (read == oi.compressed_size) {
fclose(f);
read += partial_len;

if (partial_len != max) {
return 0;
}
}
Expand Down
6 changes: 3 additions & 3 deletions src/transport.c
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,7 @@ int ptpip_read_packet(struct PtpRuntime *r, int of) {
}
}

r->wait_for_response = 1;
r->wait_for_response = r->response_wait_default;

if (rc < 0) {
ptp_verbose_log("Failed to read packet length: %d\n", rc);
Expand Down Expand Up @@ -171,7 +171,7 @@ int ptpusb_read_all_packets(struct PtpRuntime *r) {
CAMLIB_SLEEP(CAMLIB_WAIT_MS);
}
}
r->wait_for_response = 1;
r->wait_for_response = r->response_wait_default;

if (rc < 0) {
ptp_verbose_log("Failed to read packets: %d\n", rc);
Expand Down Expand Up @@ -222,7 +222,7 @@ int ptpipusb_read_packet(struct PtpRuntime *r, int of) {
}
}

r->wait_for_response = 1;
r->wait_for_response = r->response_wait_default;

if (rc < 0) {
ptp_verbose_log("Failed to read packet length: %d\n", rc);
Expand Down

0 comments on commit 8cfe9ba

Please sign in to comment.