Skip to content

Commit

Permalink
Remove active_connection, add IO kill switch
Browse files Browse the repository at this point in the history
IMO is better and easier to use for killing the connection.
  • Loading branch information
petabyt committed Nov 16, 2023
1 parent d45fe13 commit 8a7c0a1
Show file tree
Hide file tree
Showing 12 changed files with 100 additions and 78 deletions.
4 changes: 2 additions & 2 deletions src/bind.c
Original file line number Diff line number Diff line change
Expand Up @@ -107,8 +107,8 @@ int bind_get_storage_info(struct BindReq *bind, struct PtpRuntime *r) {

int bind_get_object_handles(struct BindReq *bind, struct PtpRuntime *r) {
struct UintArray *arr;
#warning "TODO: Fix wrong order of parameters"
int x = ptp_get_object_handles(r, bind->params[0], bind->params[2], bind->params[1], &arr);
// Parameters changed to correct order 14 nov 2023
int x = ptp_get_object_handles(r, bind->params[0], bind->params[1], bind->params[2], &arr);
if (x) return sprintf(bind->buffer, "{\"error\": %d}", x);

int len = sprintf(bind->buffer, "{\"error\": %d, \"resp\": [", x);
Expand Down
10 changes: 7 additions & 3 deletions src/camlib.h
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,8 @@

#include "ptp.h"

#define ptp_get_last_transaction(...) DEPRECATED_USE_ptp_get_last_transaction_id

// Used in dumps, should be set to the git commit hash
#ifndef CAMLIB_VERSION
#ifdef __DATE__
Expand Down Expand Up @@ -101,8 +103,10 @@ enum PtpConnType {
};

struct PtpRuntime {
// Managed by comm backend
uint8_t active_connection;
// Set to 1 to kill all IO operations. By default, this is 1. When a valid connection
// is achieved by libusb, libwpd, and tcp backends, it will be set to 0. On IO error, it
// will be set to 1.
uint8_t io_kill_switch;

// Is set to USB by default
uint8_t connection_type;
Expand Down Expand Up @@ -206,7 +210,7 @@ void ptp_update_transaction(struct PtpRuntime *r, int t);
int ptp_get_return_code(struct PtpRuntime *r);
uint32_t ptp_get_param(struct PtpRuntime *r, int index);
int ptp_get_param_length(struct PtpRuntime *r);
int ptp_get_last_transaction(struct PtpRuntime *r);
int ptp_get_last_transaction_id(struct PtpRuntime *r);

// Get ptr of packet payload, after header (includes parameters)
uint8_t *ptp_get_payload(struct PtpRuntime *r);
Expand Down
4 changes: 2 additions & 2 deletions src/canon.c
Original file line number Diff line number Diff line change
Expand Up @@ -108,14 +108,14 @@ int ptp_eos_set_prop_value(struct PtpRuntime *r, int code, int value) {

int ptp_eos_set_prop_data(struct PtpRuntime *r, int code, void *data, int dlength) {
// Might be unsafe (EOS buffer overflow bricks?)
//exit(1);
return PTP_UNSUPPORTED;
}

int ptp_eos_get_event(struct PtpRuntime *r) {
struct PtpCommand cmd;
cmd.code = PTP_OC_EOS_GetEvent;
cmd.param_length = 0;
return ptp_generic_send(r, &cmd);
return ptp_generic_send(r, &cmd);
}

int ptp_eos_ping(struct PtpRuntime *r) {
Expand Down
8 changes: 8 additions & 0 deletions src/data.c
Original file line number Diff line number Diff line change
Expand Up @@ -383,7 +383,15 @@ int ptp_eos_prop_next(void **d, struct PtpGenericEvent *p) {
return 0;
}

// Stream reader for events
struct PtpEventReader {
int entries;
int index;
void *ptr;
};

// TODO: misnomer: ptp_eos_unpack_events
// TODO: we should have a way to read next entry without allocating/freeing memory
int ptp_eos_events(struct PtpRuntime *r, struct PtpGenericEvent **p) {
uint8_t *dp = ptp_get_payload(r);

Expand Down
38 changes: 38 additions & 0 deletions src/generic.c
Original file line number Diff line number Diff line change
Expand Up @@ -65,3 +65,41 @@ int ptp_take_picture(struct PtpRuntime *r) {

return PTP_UNSUPPORTED;
}

int ptp_events_json(struct PtpRuntime *r, char *buffer, int max) {
return 0;
}

int ptp_get_all_known(struct PtpRuntime *r, struct PtpGenericEvent **s, int *length) {
uint16_t *props = r->di->props_supported;
int plength = r->di->props_supported_length;
(*length) = plength;

(*s) = malloc(sizeof(struct PtpGenericEvent) * plength);

for (int i = 0; i < plength; i++) {
struct PtpGenericEvent *cur = &((*s)[i]);
memset(cur, 0, sizeof(struct PtpGenericEvent));

cur->code = props[i];

int rc = ptp_get_prop_value(r, props[i]);
if (rc) return rc;

int v = ptp_parse_prop_value(r);
cur->value = v;
if (v == -1) {
continue;
}

// TODO: Get more props
switch (props[i]) {
case PTP_PC_BatteryLevel:
cur->name = "battery";
cur->value = v;
break;
}
}

return 0;
}
8 changes: 4 additions & 4 deletions src/lib.c
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@

// Reset all fields of PtpRuntime - this must be updated when new fields are added
void ptp_generic_reset(struct PtpRuntime *r) {
r->active_connection = 0;
r->io_kill_switch = 1;
r->transaction = 0;
r->session = 0;
r->connection_type = PTP_USB;
Expand Down Expand Up @@ -92,7 +92,7 @@ int ptp_generic_send(struct PtpRuntime *r, struct PtpCommand *cmd) {
return PTP_IO_ERR;
}

if (ptp_get_last_transaction(r) != r->transaction) {
if (ptp_get_last_transaction_id(r) != r->transaction) {
ptp_verbose_log("Mismatch transaction ID\n");
ptp_mutex_unlock(r);
return PTP_IO_ERR;
Expand Down Expand Up @@ -161,9 +161,9 @@ int ptp_generic_send_data(struct PtpRuntime *r, struct PtpCommand *cmd, void *da
return PTP_IO_ERR;
}

if (ptp_get_last_transaction(r) != r->transaction) {
if (ptp_get_last_transaction_id(r) != r->transaction) {
ptp_verbose_log("ptp_generic_send_data: Mismatch transaction ID (%d/%d)\n",
ptp_get_last_transaction(r), r->transaction);
ptp_get_last_transaction_id(r), r->transaction);
ptp_mutex_unlock(r);
return PTP_IO_ERR;
}
Expand Down
13 changes: 6 additions & 7 deletions src/libusb.c
Original file line number Diff line number Diff line change
Expand Up @@ -209,7 +209,7 @@ int ptp_device_open(struct PtpRuntime *r, struct PtpDeviceEntry *entry) {
return PTP_OPEN_FAIL;
}

r->active_connection = 1;
r->io_kill_switch = 0;

return 0;
}
Expand Down Expand Up @@ -245,21 +245,20 @@ int ptp_device_init(struct PtpRuntime *r) {
return PTP_OPEN_FAIL;
}

r->active_connection = 1;
r->io_kill_switch = 0;

return 0;
}

int ptp_device_close(struct PtpRuntime *r) {
r->io_kill_switch = 1;
struct LibUSBBackend *backend = (struct LibUSBBackend *)r->comm_backend;
if (libusb_release_interface(backend->handle, 0)) {
return 1;
}

libusb_close(backend->handle);

r->active_connection = 0;

return 0;
}

Expand All @@ -269,7 +268,7 @@ int ptp_device_reset(struct PtpRuntime *r) {

int ptp_cmd_write(struct PtpRuntime *r, void *to, int length) {
struct LibUSBBackend *backend = (struct LibUSBBackend *)r->comm_backend;
if (backend == NULL) return -1;
if (backend == NULL || r->io_kill_switch) return -1;
int transferred;
int rc = libusb_bulk_transfer(
backend->handle,
Expand All @@ -284,7 +283,7 @@ int ptp_cmd_write(struct PtpRuntime *r, void *to, int length) {

int ptp_cmd_read(struct PtpRuntime *r, void *to, int length) {
struct LibUSBBackend *backend = (struct LibUSBBackend *)r->comm_backend;
if (backend == NULL) return -1;
if (backend == NULL || r->io_kill_switch) return -1;
int transferred = 0;
int rc = libusb_bulk_transfer(
backend->handle,
Expand All @@ -299,7 +298,7 @@ int ptp_cmd_read(struct PtpRuntime *r, void *to, int length) {

int ptp_read_int(struct PtpRuntime *r, void *to, int length) {
struct LibUSBBackend *backend = (struct LibUSBBackend *)r->comm_backend;
if (backend == NULL) return -1;
if (backend == NULL || r->io_kill_switch) return -1;
int transferred = 0;
int rc = libusb_bulk_transfer(
backend->handle,
Expand Down
42 changes: 31 additions & 11 deletions src/libwpd.c
Original file line number Diff line number Diff line change
Expand Up @@ -9,52 +9,65 @@
#include <ptp.h>
#include <libwpd.h>

struct WpdStruct backend_wpd;

int ptp_comm_init(struct PtpRuntime *r) {
ptp_generic_reset(r);
wpd_init(1, L"Camlib WPD");

r->comm_backend = malloc(sizeof(struct WpdStruct));

// We are not using low-level I/O operations, so this is never used
r->r->max_packet_size = 512;

return 0;
}

int ptp_device_init(struct PtpRuntime *r) {
ptp_comm_init(r);

struct WpdStruct *wpd = (struct WpdStruct *)(r->comm_backend);
if (wpd == NULL) return PTP_IO_ERR;

int length = 0;
wchar_t **devices = wpd_get_devices(&backend_wpd, &length);
wchar_t **devices = wpd_get_devices(wpd, &length);

if (length == 0) return PTP_NO_DEVICE;

for (int i = 0; i < length; i++) {
wprintf(L"Trying device: %s\n", devices[i]);

int ret = wpd_open_device(&backend_wpd, devices[i]);
int ret = wpd_open_device(wpd, devices[i]);
if (ret) {
return PTP_OPEN_FAIL;
}

int type = wpd_get_device_type(&backend_wpd);
int type = wpd_get_device_type(wpd);
ptp_verbose_log("Found device of type: %d\n", type);
if (type == WPD_DEVICE_TYPE_CAMERA) {
return 0;
}

wpd_close_device(&backend_wpd);
wpd_close_device(wpd);
}

return PTP_NO_DEVICE;
}

struct PtpDeviceEntry *ptpusb_device_list(struct PtpRuntime *r) {
// Unimplemented
return NULL;
}

int ptp_device_open(struct PtpRuntime *r, struct PtpDeviceEntry *entry) {
// Unimplemented
return PTP_IO_ERR;
}

int ptp_send_bulk_packets(struct PtpRuntime *r, int length) {
if (r->io_kill_switch) return PTP_IO_ERR;

struct WpdStruct *wpd = (struct WpdStruct *)(r->comm_backend);
if (wpd == NULL) return PTP_IO_ERR;

struct LibWPDPtpCommand cmd;
struct PtpBulkContainer *bulk = (struct PtpBulkContainer*)(r->data);

Expand All @@ -67,10 +80,10 @@ int ptp_send_bulk_packets(struct PtpRuntime *r, int length) {

int ret;
if (r->data_phase_length) {
ret = wpd_send_do_command(&backend_wpd, &cmd, r->data_phase_length);
ret = wpd_send_do_command(wpd, &cmd, r->data_phase_length);
r->data_phase_length = 0;
} else {
ret = wpd_receive_do_command(&backend_wpd, &cmd);
ret = wpd_receive_do_command(wpd, &cmd);
}

if (ret) {
Expand All @@ -80,7 +93,7 @@ int ptp_send_bulk_packets(struct PtpRuntime *r, int length) {
}
} else if (bulk->type == PTP_PACKET_TYPE_DATA) {
cmd.param_length = 0;
int ret = wpd_send_do_data(&backend_wpd, &cmd, ptp_get_payload(r), length - 12);
int ret = wpd_send_do_data(wpd, &cmd, ptp_get_payload(r), length - 12);
if (ret < 0) {
return PTP_IO_ERR;
} else {
Expand All @@ -102,16 +115,21 @@ int ptp_send_bulk_packets(struct PtpRuntime *r, int length) {
}

int ptp_receive_bulk_packets(struct PtpRuntime *r) {
if (r->io_kill_switch) return PTP_IO_ERR;

// Don't do anything if the data phase was already sent
if (r->data_phase_length) {
r->data_phase_length = 0;
return 12;
}

struct WpdStruct *wpd = (struct WpdStruct *)(r->comm_backend);
if (wpd == NULL) return PTP_IO_ERR;

struct PtpBulkContainer *bulk = (struct PtpBulkContainer*)(r->data);
if (bulk->type == PTP_PACKET_TYPE_COMMAND) {
struct LibWPDPtpCommand cmd;
int b = wpd_receive_do_data(&backend_wpd, &cmd, (uint8_t *)(r->data + 12), r->data_length - 12);
int b = wpd_receive_do_data(wpd, &cmd, (uint8_t *)(r->data + 12), r->data_length - 12);
if (b < 0) {
return PTP_IO_ERR;
}
Expand Down Expand Up @@ -145,7 +163,9 @@ int ptp_read_int(struct PtpRuntime *r, void *to, int length) {
}

int ptp_device_close(struct PtpRuntime *r) {
wpd_close_device(&backend_wpd);
struct WpdStruct *wpd = (struct WpdStruct *)(r->comm_backend);
if (wpd == NULL) return PTP_IO_ERR;
wpd_close_device(wpd);
return 0;
}

Expand Down
34 changes: 0 additions & 34 deletions src/operations.c
Original file line number Diff line number Diff line change
Expand Up @@ -342,37 +342,3 @@ int ptp_download_file(struct PtpRuntime *r, int handle, char *file) {
}
}
}

int ptp_get_all_known(struct PtpRuntime *r, struct PtpGenericEvent **s, int *length) {
uint16_t *props = r->di->props_supported;
int plength = r->di->props_supported_length;
(*length) = plength;

(*s) = malloc(sizeof(struct PtpGenericEvent) * plength);

for (int i = 0; i < plength; i++) {
struct PtpGenericEvent *cur = &((*s)[i]);
memset(cur, 0, sizeof(struct PtpGenericEvent));

cur->code = props[i];

int rc = ptp_get_prop_value(r, props[i]);
if (rc) return rc;

int v = ptp_parse_prop_value(r);
cur->value = v;
if (v == -1) {
continue;
}

// TODO: Get more props
switch (props[i]) {
case PTP_PC_BatteryLevel:
cur->name = "battery";
cur->value = v;
break;
}
}

return 0;
}
2 changes: 1 addition & 1 deletion src/packet.c
Original file line number Diff line number Diff line change
Expand Up @@ -360,7 +360,7 @@ uint32_t ptp_get_param(struct PtpRuntime *r, int index) {
}
}

int ptp_get_last_transaction(struct PtpRuntime *r) {
int ptp_get_last_transaction_id(struct PtpRuntime *r) {
if (r->connection_type == PTP_IP) {
struct PtpIpResponseContainer *resp = ptpip_get_response_packet(r);
return resp->transaction;
Expand Down
Loading

0 comments on commit 8a7c0a1

Please sign in to comment.