Skip to content

Commit

Permalink
More documentation, update to new libwpd backend
Browse files Browse the repository at this point in the history
  • Loading branch information
petabyt committed Sep 14, 2024
1 parent 045546b commit 0212409
Show file tree
Hide file tree
Showing 15 changed files with 213 additions and 195 deletions.
10 changes: 8 additions & 2 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ CFLAGS += -D CAMLIB_NO_COMPAT -D VERBOSE
# - log.c can be replaced with a custom logging mechanism
# - ip.c can be replaced with no_ip.c
# - libwpd.c or libusb.c can be replaced with no_usb.c
# - bind.c and liveview.c can be omitted together
CAMLIB_CORE := operations.o packet.o enums.o data.o enum_dump.o lib.o canon.o liveview.o bind.o ip.o ml.o conv.o generic.o transport.o log.o
CAMLIB_CORE := $(addprefix src/,$(CAMLIB_CORE))

Expand All @@ -17,6 +18,7 @@ EXTRAS := src/canon_adv.o src/object.o
UNIX_CFLAGS = $(shell pkg-config --cflags libusb-1.0)
UNIX_LDFLAGS = $(shell pkg-config --libs libusb-1.0)
UNIX_LIB_FILES := $(CAMLIB_CORE) $(EXTRAS) src/libusb.o
WIN_LIB_FILES := $(CAMLIB_CORE) $(EXTRAS) src/libwpd.o

TARGET ?= l
ifeq ($(TARGET),m)
Expand All @@ -36,6 +38,10 @@ all: libcamlib.dll
MINGW := x86_64-w64-mingw32
CC := $(MINGW)-gcc
CPP := $(MINGW)-c++
MINGW_LIBS := -lwpd -luser32 -lkernel32 -lgdi32 -lcomctl32 -luxtheme -lmsimg32 -lcomdlg32 -ld2d1 -ldwrite -lole32 -loleaut32 -loleacc -lstdc++ -lgcc -lpthread -lssp -lurlmon -luuid -lws2_32
libcamlib.dll: $(WIN_LIB_FILES)
$(CC) -shared $(WIN_LIB_FILES) $(MINGW_LIBS) -o libcamlib.dll
LDFLAGS := $(MINGW_LIBS)
endif

%.o: %.c
Expand All @@ -47,8 +53,8 @@ DEC_FILES := src/dec/main.o src/enums.o src/enum_dump.o src/packet.o src/conv.o
dec: $(DEC_FILES)
$(CC) $(DEC_FILES) $(CFLAGS) -o $@

camlib: src/cli.o $(UNIX_LIB_FILES)
$(CC) src/cli.o $(UNIX_LIB_FILES) $(CFLAGS) $(UNIX_LDFLAGS) -o $@
camlib: src/cli.o $(WIN_LIB_FILES)
$(CC) src/cli.o $(WIN_LIB_FILES) $(CFLAGS) $(LDFLAGS) -o $@

# Run this thing frequently
stringify:
Expand Down
28 changes: 26 additions & 2 deletions src/bind.c
Original file line number Diff line number Diff line change
Expand Up @@ -146,6 +146,15 @@ int bind_get_object_info(struct BindReq *bind, struct PtpRuntime *r) {
return len;
}

int bind_send_object_info(struct BindReq *bind, struct PtpRuntime *r) {
struct PtpObjectInfo oi;
strcpy(oi.filename, "FOO_BAR.JPG");
int x = ptp_send_object_info(r, 0, 0, &oi);
if (x) return bind->out(bind, "{\"error\": %d}", x);
int len = bind->out(bind, "{\"error\": %d}", x);
return len;
}

int bind_custom(struct BindReq *bind, struct PtpRuntime *r) {
struct PtpCommand cmd;
cmd.code = bind->params[0];
Expand Down Expand Up @@ -257,6 +266,15 @@ int bind_set_property(struct BindReq *bind, struct PtpRuntime *r) {
return bind->out(bind, "{\"error\": %d}", x);
}

int bind_get_property(struct BindReq *bind, struct PtpRuntime *r) {
int x = ptp_get_prop_value(r, bind->params[0]);
if (x) {
return bind->out(bind, "{\"error\": %d}", x);
} else {
return bind->out(bind, "{\"error\": %d, \"value\": %u}", x, ptp_parse_prop_value(r));
}
}

int bind_get_events(struct BindReq *bind, struct PtpRuntime *r) {
int dev = ptp_device_type(r);

Expand Down Expand Up @@ -541,9 +559,11 @@ struct RouteMap {
{"ptp_eos_set_event_mode", bind_eos_set_event_mode},

{"ptp_cancel_af", bind_cancel_af},

// Flip DSLR mirror up - or enter liveview
{"ptp_mirror_up", bind_mirror_up},
// Flip mirror down - or disable liveview
{"ptp_mirror_down", bind_mirror_down},
// Focus lens in/out
{"ptp_drive_lens", bind_drive_lens},
{"ptp_get_liveview_frame", bind_get_liveview_frame},
{"ptp_get_liveview_type", bind_get_liveview_type},
Expand All @@ -552,17 +572,21 @@ struct RouteMap {
{"ptp_ml_init_bmp_lv", bind_ml_init_bmp_lv},
{"ptp_init_liveview", bind_liveview_init},
{"ptp_deinit_liveview", bind_liveview_deinit},
// Try and detect manufacturer/type of device connected
{"ptp_get_device_type", bind_get_device_type},
// Get a generic list of events
{"ptp_get_events", bind_get_events},
{"ptp_get_all_props", bind_get_all_props},
{"ptp_set_property", bind_set_property},
{"ptp_get_property", bind_get_property},
{"ptp_get_enums", bind_get_enums},
{"ptp_get_status", bind_get_status},
{"ptp_get_return_code", bind_get_return_code},
{"ptp_get_storage_ids", bind_get_storage_ids},
{"ptp_get_storage_info", bind_get_storage_info},
{"ptp_get_object_handles", bind_get_object_handles},
{"ptp_get_object_info", bind_get_object_info},
{"ptp_send_object_info", bind_send_object_info},
{"ptp_get_thumbnail", bind_get_thumbnail},
{"ptp_get_partial_object", bind_get_partial_object},
{"ptp_download_file", bind_download_file},
Expand All @@ -576,5 +600,5 @@ int bind_run_req(struct PtpRuntime *r, struct BindReq *bind) {
}
}

return -1;
return 1;
}
12 changes: 12 additions & 0 deletions src/camlib.h
Original file line number Diff line number Diff line change
Expand Up @@ -39,15 +39,27 @@ __attribute__ ((noreturn)) void ptp_panic(char *fmt, ...);
/// @brief Camlib library errors, not PTP return codes
enum PtpGeneralError {
PTP_OK = 0,
/// @brief No device found (USB)
PTP_NO_DEVICE = -1,
/// @brief EPERM or other permission denied error
PTP_NO_PERM = -2,
/// @brief Found device, but failed to connect
PTP_OPEN_FAIL = -3,
/// @brief malloc failed
PTP_OUT_OF_MEM = -4,
/// @brief General IO or communication error
PTP_IO_ERR = -5,
/// @brief Unexpected, unhandled, or illegal behavior
PTP_RUNTIME_ERR = -6,
/// @brief Operation or functionality isn't implemented or supported
PTP_UNSUPPORTED = -7,
/// @brief response code is not PTP_RC_OK
PTP_CHECK_CODE = -8,
/// @brief Operation (such as download) was canceled by another thread
PTP_CANCELED = -9,
/// @brief No response
/// @note Used internally only
PTP_COMMAND_IGNORED = -10,
};

/// @brief Evaluates PtpGeneralError into string message
Expand Down
52 changes: 36 additions & 16 deletions src/cl_backend.h
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@

#define PTP_TIMEOUT 1000

// Linked-list entry for a single USB device
/// @brief Linked-list entry for a single USB device
struct PtpDeviceEntry {
struct PtpDeviceEntry *prev;

Expand All @@ -22,46 +22,66 @@ struct PtpDeviceEntry {
struct PtpDeviceEntry *next;
};

/// @brief Initialize communications context for the current thread
int ptp_comm_init(struct PtpRuntime *r);

/// @brief Get a linked list of USB or PTP Devices
/// @memberof PTP/USB
struct PtpDeviceEntry *ptpusb_device_list(struct PtpRuntime *r);
/// @memberof PTP/USB
void ptpusb_free_device_list(struct PtpDeviceEntry *e);
/// @brief Open and connect to a device from the PtpDeviceEntry structure
/// @memberof PTP/USB
int ptp_device_open(struct PtpRuntime *r, struct PtpDeviceEntry *entry);

// Init comm (if not already) and connect to the first device available
/// @brief Runs ptp_comm_init and connect to the first device available
int ptp_device_init(struct PtpRuntime *r);

// Temporary :)
#define ptp_send_bulk_packet DEPRECATED_USE_ptp_cmd_write_INSTEAD
#define ptp_receive_bulk_packet DEPRECATED_USE_ptp_cmd_read_INSTEAD
//#define ptp_send_bulk_packet DEPRECATED_USE_ptp_cmd_write_INSTEAD
//#define ptp_receive_bulk_packet DEPRECATED_USE_ptp_cmd_read_INSTEAD

// Bare IO, send a single 512 byte packet. Return negative or NULL on error.
/// @brief Send data over the raw command endpoint
/// @memberof PTP/USB
int ptp_cmd_write(struct PtpRuntime *r, void *to, int length);
/// @brief Receive raw data over the command endpoint
/// @memberof PTP/USB
int ptp_cmd_read(struct PtpRuntime *r, void *to, int length);

// Reset the pipe, can clear issues
/// @brief Reset the USB device or endpoint if there is communication issues
/// @memberof PTP/USB
int ptp_device_reset(struct PtpRuntime *r);

// Recieve all packets, and whatever else (common logic for all backends)
/// @brief Send packets in r->data
/// @memberof PTP/USB
int ptp_send_bulk_packets(struct PtpRuntime *r, int length);
/// @brief Receive all packets into r->data
/// @memberof PTP/USB
int ptp_receive_bulk_packets(struct PtpRuntime *r);
/// @brief Poll the interrupt endpoint
/// @memberof PTP/USB
int ptp_read_int(struct PtpRuntime *r, void *to, int length);

int ptp_device_close(struct PtpRuntime *r); // TODO: Disconnect, confusing with ptp_close

// Upload file data as packets, but upload r->data till length first
int ptp_fsend_packets(struct PtpRuntime *r, int length, FILE *stream);

// Reads the incoming packet to file, starting after an optional offset
int ptp_freceive_bulk_packets(struct PtpRuntime *r, FILE *stream, int of);
/// @brief Disconnect from the current device
/// @memberof PTP/USB
int ptp_device_close(struct PtpRuntime *r);

int ptpip_connect(struct PtpRuntime *r, const char *addr, int port);
/// @brief Connect to a TCP port on the default network adapter
/// @memberof PTP/IP
int ptpip_connect(struct PtpRuntime *r, const char *addr, int port, int extra_tmout);
/// @memberof PTP/IP
int ptpip_cmd_write(struct PtpRuntime *r, void *data, int size);
/// @memberof PTP/IP
int ptpip_cmd_read(struct PtpRuntime *r, void *data, int size);

/// @memberof PTP/IP
int ptpip_connect_events(struct PtpRuntime *r, const char *addr, int port);
/// @memberof PTP/IP
int ptpip_event_send(struct PtpRuntime *r, void *data, int size);
/// @memberof PTP/IP
int ptpip_event_read(struct PtpRuntime *r, void *data, int size);

int ptpip_close(struct PtpRuntime *r); // TODO: Disconnect, confusing with ptp_close
/// @memberof PTP/IP
int ptpip_close(struct PtpRuntime *r);

#endif
23 changes: 10 additions & 13 deletions src/cl_bind.h
Original file line number Diff line number Diff line change
Expand Up @@ -4,35 +4,32 @@
// Recommended buffer size for bind_run
#define PTP_BIND_DEFAULT_SIZE 5000000

#define BIND_MAX_PARAM 5
#define BIND_MAX_NAME 64
#define BIND_MAX_STRING 128
#define BIND_MAX_BYTES 512

struct BindReq {
// @brief Argument passed to out or out_bytes
void *arg;
// @brief Output JSON data
int (*out)(struct BindReq *bind, char *fmt, ...);
/// @brief Output raw binary data
int (*out_bytes)(struct BindReq *bind, void *bytes, size_t length);

char *buffer;
int max;
/// @brief Name of command to be run
char name[BIND_MAX_NAME];

int params[BIND_MAX_PARAM];
/// @brief Parameters for command
/// @note These are parsed by command handlers in bind.c, not always passed to the PTP operation
int params[5];
int params_length;

/// @brief String argument, NULL for none
char *string;

/// @brief Data argument, NULL for none
uint8_t *bytes;
int bytes_length;
};

// Run a binding - will return JSON
//int bind_run(struct PtpRuntime *r, char *req, char *buffer, int size);

// Run a binding directly from the structure
// @brief Run a binding directly from an instance of struct BindReq
int bind_run_req(struct PtpRuntime *r, struct BindReq *bind);

//void bind_parse(struct BindReq *br, char *req);

#endif
2 changes: 1 addition & 1 deletion src/cl_ops.h
Original file line number Diff line number Diff line change
Expand Up @@ -105,7 +105,7 @@ int ptpip_init_events(struct PtpRuntime *r);

/// @note PTP/IP only
/// @memberof PtpRuntime
int ptpip_init_command_request(struct PtpRuntime *r, char *device_name);
int ptpip_init_command_request(struct PtpRuntime *r, const char *device_name);

// EOS Only functions - not for Canon point and shoot
int ptp_eos_get_viewfinder_data(struct PtpRuntime *r);
Expand Down
11 changes: 8 additions & 3 deletions src/cli.c
Original file line number Diff line number Diff line change
Expand Up @@ -39,8 +39,13 @@ static int run_binding(struct Options *o, struct BindReq *br) {
ptp_open_session(r);

int rc = bind_run_req(r, br);
if (rc > 0) {
printf("Command %s does not exist.\n", br->name);
}
if (rc) return rc;

putchar('\n');

ptp_close_session(r);

ptp_device_close(r);
Expand All @@ -62,12 +67,11 @@ static int parse_run(struct Options *o, int argc, char **argv, int i) {
struct BindReq br;
br.params_length = 0;
br.bytes_length = 0;
br.buffer = malloc(5000);
br.string = NULL;
br.out = out_printf;
br.out_bytes = NULL;

memset(br.params, 0, sizeof(int) * BIND_MAX_PARAM);
memset(br.params, 0, sizeof(br.params));
memset(br.name, 0, BIND_MAX_NAME);

strcpy(br.name, name);
Expand All @@ -80,11 +84,12 @@ static int parse_run(struct Options *o, int argc, char **argv, int i) {
}

int rc = run_binding(o, &br);
puts(br.buffer);
return rc;
}

int main(int argc, char **argv) {
extern int camlib_verbose;
camlib_verbose = 0;
struct Options o;
for (int i = 1; i < argc; i++) {
if (!strcmp(argv[i], "--help")) {
Expand Down
Loading

0 comments on commit 0212409

Please sign in to comment.