Skip to content

Commit

Permalink
Bunch of bug fixes and minor tweaks
Browse files Browse the repository at this point in the history
moved buffer resize to lib.c
fixed ptpip_read_packet
added some stuff
  • Loading branch information
petabyt committed Nov 13, 2023
1 parent 541ab7d commit 5a5e935
Show file tree
Hide file tree
Showing 11 changed files with 112 additions and 33 deletions.
46 changes: 35 additions & 11 deletions src/backend.c
Original file line number Diff line number Diff line change
Expand Up @@ -40,30 +40,53 @@ int ptp_send_bulk_packets(struct PtpRuntime *r, int length) {
}

int ptpip_read_packet(struct PtpRuntime *r, int of) {
int rc = 0;
int read = 0;

int rc = 0;
while (rc <= 0 && r->wait_for_response) {
rc = ptp_cmd_read(r, r->data + of + read, r->max_packet_size);
rc = ptpip_cmd_read(r, r->data + of + read, 4);

r->wait_for_response--;

if (rc > 0) break;

if (r->wait_for_response) {
ptp_verbose_log("Trying again...");
CAMLIB_SLEEP(CAMLIB_WAIT_MS);
}
}

r->wait_for_response = 1;

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

if (rc < 4) {
ptp_verbose_log("Failed to read at least packet length: %d\n", rc);
return PTP_IO_ERR;
}

read += rc;

struct PtpIpHeader *h = (struct PtpIpHeader *)(r->data + of);

printf("Got packet of %d bytes, type %X\n", h->length, h->type);
if (h->length - read == 0) {
return read;
}

// Ensure data buffer is large enough for the rest of the packet
if (of + read + h->length >= r->data_length) {
rc = ptp_buffer_resize(r, of + read + h->length);
if (rc) return rc;
}

while (1) {
rc = ptpip_cmd_read(r, r->data + of + read, h->length - read);

if (rc < 0) {
ptp_verbose_log("Read error: %d\n", rc);
return PTP_IO_ERR;
}

Expand Down Expand Up @@ -150,8 +173,14 @@ int ptpusb_read_all_packets(struct PtpRuntime *r) {
}
r->wait_for_response = 1;

if (rc < 0) {
ptp_verbose_log("Failed to read packets: %d\n");
return PTP_IO_ERR;
}

read += rc;

// TODO: unsigned/unsigned compare
if (read >= r->data_length - r->max_packet_size) {
ptp_verbose_log("recieve_bulk_packets: Not enough memory\n");
return PTP_OUT_OF_MEM;
Expand All @@ -175,7 +204,7 @@ int ptpusb_read_all_packets(struct PtpRuntime *r) {
}
}

// For USB packets over IP, we can't do any LibUSB/LibWPD performance tricks.
// For USB packets over IP, we can't do any LibUSB/LibWPD performance tricks. reads will just time out.
int ptpipusb_read_packet(struct PtpRuntime *r, int of) {
int rc = 0;
int read = 0;
Expand Down Expand Up @@ -214,14 +243,9 @@ int ptpipusb_read_packet(struct PtpRuntime *r, int of) {
}

// Ensure data buffer is large enough for the rest of the packet
// TODO: Have this as an external function
if (of + read + h->length >= r->data_length) {
ptp_verbose_log("Extending IO buffer\n");
r->data = realloc(r->data, of + read + h->length + 1000);
r->data_length = of + read + h->length + 1000;
if (r->data == NULL) {
return PTP_OUT_OF_MEM;
}
rc = ptp_buffer_resize(r, of + read + h->length);
if (rc) return rc;
}

while (1) {
Expand Down
7 changes: 4 additions & 3 deletions src/bind.c
Original file line number Diff line number Diff line change
Expand Up @@ -11,9 +11,10 @@

#include <camlib.h>

int bind_connected = 0;
int bind_initialized = 0;
int bind_capture_type = 0;
// TODO: func to access these
static int bind_connected = 0;
static int bind_initialized = 0;
static int bind_capture_type = 0;

int bind_status(struct BindReq *bind, struct PtpRuntime *r) {
return sprintf(bind->buffer, "{\"error\": 0, \"initialized\": %d, \"connected\": %d, "
Expand Down
6 changes: 4 additions & 2 deletions src/camlib.h
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@
// Max timeout for command read/writes
#define PTP_TIMEOUT 1000

// How much x to wait for when wait_for_response is greater than 1
// How much ms to wait for wait_for_response
#define CAMLIB_WAIT_MS 1000

// Conforms to POSIX 2001, some compilers may not have it
Expand Down Expand Up @@ -170,6 +170,8 @@ void ptp_mutex_unlock(struct PtpRuntime *r);
void ptp_mutex_keep_locked(struct PtpRuntime *r);
void ptp_mutex_lock(struct PtpRuntime *r);

int ptp_buffer_resize(struct PtpRuntime *r, size_t size);

// Packet builder/unpacker helper functions. These accept a pointer-to-pointer
// and will advance the dereferenced pointer by amount read.
uint8_t ptp_read_uint8(void **dat);
Expand Down Expand Up @@ -228,7 +230,7 @@ int ptp_check_opcode(struct PtpRuntime *r, int op);
int ptp_check_prop(struct PtpRuntime *r, int code);

// Duplicate array, return malloc'd buffer
struct UintArray * ptp_dup_uint_array(struct UintArray *arr);
struct UintArray *ptp_dup_uint_array(struct UintArray *arr);

// Write r->data to a file called DUMP
int ptp_dump(struct PtpRuntime *r);
Expand Down
16 changes: 7 additions & 9 deletions src/cl_data.h
Original file line number Diff line number Diff line change
Expand Up @@ -75,15 +75,6 @@ struct PtpStorageInfo {
uint32_t free_objects;
};

struct ObjectRequest {
uint32_t storage_id;
uint32_t object_format;
uint32_t object_handle;
uint8_t all_storage_ids;
uint8_t all_formats;
uint8_t in_root;
};

struct PtpObjectInfo {
uint32_t storage_id;
uint16_t obj_format;
Expand Down Expand Up @@ -192,6 +183,13 @@ enum PtpMlBmpLvOption {
PTP_ML_BMP_LV_GET_SPEC = 1,
};

enum PtpCHDKCommands {
PTP_CHDK_Version = 0,
PTP_CHDK_UploadFile = 5,
};

void *ptp_pack_chdk_upload_file(struct PtpRuntime *r, char *in, char *out, int *length);

// Response to struct FujiInitPacket
struct PtpFujiInitResp {
uint32_t x1;
Expand Down
3 changes: 3 additions & 0 deletions src/cl_ops.h
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,9 @@ int ptp_liveview_type(struct PtpRuntime *r);
int ptp_ml_init_bmp_lv(struct PtpRuntime *r);
int ptp_ml_get_bmp_lv(struct PtpRuntime *r, uint32_t **buffer_ptr);

int ptp_chdk_get_version(struct PtpRuntime *r);
int ptp_chdk_upload_file(struct PtpRuntime *r, char *input, char *dest);

// Fuji vendor version of SendObjectInfo - same as standard, but no parameters
int ptp_fuji_send_object_info(struct PtpRuntime *r, struct PtpObjectInfo *oi);
int ptp_fuji_send_object(struct PtpRuntime *r, struct PtpObjectInfo *oi, void *data, int length);
Expand Down
26 changes: 26 additions & 0 deletions src/data.c
Original file line number Diff line number Diff line change
Expand Up @@ -114,6 +114,7 @@ int ptp_parse_object_info(struct PtpRuntime *r, struct PtpObjectInfo *oi) {
return 0;
}

// TODO: Different API
int ptp_pack_object_info(struct PtpRuntime *r, struct PtpObjectInfo *oi, void **dat, int max) {
if (1024 > max) {
return 0;
Expand All @@ -139,6 +140,31 @@ int ptp_pack_object_info(struct PtpRuntime *r, struct PtpObjectInfo *oi, void **
return length;
}

void *ptp_pack_chdk_upload_file(struct PtpRuntime *r, char *in, char *out, int *length) {
FILE *f = fopen(in, "rb");
if (f == NULL) {
ptp_verbose_log("Unable to open %s\n", in);
return NULL;
}

fseek(f, 0, SEEK_END);
long file_size = ftell(f);
fseek(f, 0, SEEK_SET);

int size_all = 4 + strlen(out) + 1 + file_size;
*length = size_all;
char *data = malloc(size_all);
if (data == NULL) return NULL;

void *d_ptr = (void *)data;
ptp_write_uint32(&d_ptr, strlen(out) + 1);
ptp_write_utf8_string(&d_ptr, out);

fread(d_ptr, 1, file_size, f);

return data;
}

int ptp_parse_device_info(struct PtpRuntime *r, struct PtpDeviceInfo *di) {
// Skip packet header
void *e = ptp_get_payload(r);
Expand Down
2 changes: 1 addition & 1 deletion src/ip.c
Original file line number Diff line number Diff line change
Expand Up @@ -98,7 +98,7 @@ int ptpip_new_timeout_socket(char *addr, int port) {

if (so_error == 0) {
ptp_verbose_log("Connection established %s:%d (%d)\n", addr, port, sockfd);
set_nonblocking_io(sockfd, 0);
set_nonblocking_io(sockfd, 0); // ????
return sockfd;
}
}
Expand Down
4 changes: 2 additions & 2 deletions src/libwpd.c
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,7 @@ int ptp_device_open(struct PtpRuntime *r, struct PtpDeviceEntry *entry) {
}

int ptp_send_bulk_packets(struct PtpRuntime *r, int length) {
struct PtpCommand cmd;
struct LibWPDPtpCommand cmd;
struct PtpBulkContainer *bulk = (struct PtpBulkContainer*)(r->data);

if (bulk->type == PTP_PACKET_TYPE_COMMAND) {
Expand Down Expand Up @@ -110,7 +110,7 @@ int ptp_receive_bulk_packets(struct PtpRuntime *r) {

struct PtpBulkContainer *bulk = (struct PtpBulkContainer*)(r->data);
if (bulk->type == PTP_PACKET_TYPE_COMMAND) {
struct PtpCommand cmd;
struct LibWPDPtpCommand cmd;
int b = wpd_receive_do_data(&backend_wpd, &cmd, (uint8_t *)(r->data + 12), r->data_length - 12);
if (b < 0) {
return PTP_IO_ERR;
Expand Down
17 changes: 13 additions & 4 deletions src/libwpd.h
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,15 @@ typedef enum tagWPD_DEVICE_TYPES {
WPD_DEVICE_TYPE_AUDIO_RECORDER = 6
}WPD_DEVICE_TYPES;

struct LibWPDPtpCommand {
int code;

uint32_t params[5];
int param_length;

int data_length;
};

// Initialize thread
int wpd_init(int verbose, wchar_t *app_name);

Expand All @@ -39,18 +48,18 @@ int wpd_get_device_type(struct WpdStruct *wpd);

// Send command packet with no data packet, but expect data packet (device may not send data packet, that is fine)
// Data packet should be recieved with wpd_receive_do_data
int wpd_receive_do_command(struct WpdStruct *wpd, struct PtpCommand *cmd);
int wpd_receive_do_command(struct WpdStruct *wpd, struct LibWPDPtpCommand *cmd);

// Get data payload from device, if any. cmd struct will be filled with response packet.
int wpd_receive_do_data(struct WpdStruct *wpd, struct PtpCommand *cmd, uint8_t *buffer, int length);
int wpd_receive_do_data(struct WpdStruct *wpd, struct LibWPDPtpCommand *cmd, uint8_t *buffer, int length);

// Send command packet with data phase, with no data packet response from device. Call wpd_send_do_data to get the response
// and data packets
int wpd_send_do_command(struct WpdStruct* wpd, struct PtpCommand* cmd, int length);
int wpd_send_do_command(struct WpdStruct* wpd, struct LibWPDPtpCommand* cmd, int length);

// Send the actual data packet, if wpd_send_do_command was called with length != 0
// cmd struct will be filled with the response packet
int wpd_send_do_data(struct WpdStruct* wpd, struct PtpCommand* cmd, uint8_t *buffer, int length);
int wpd_send_do_data(struct WpdStruct* wpd, struct LibWPDPtpCommand* cmd, uint8_t *buffer, int length);

#endif

2 changes: 1 addition & 1 deletion src/packet.c
Original file line number Diff line number Diff line change
Expand Up @@ -233,7 +233,7 @@ int ptp_new_cmd_packet(struct PtpRuntime *r, struct PtpCommand *cmd) {
}
}

// Get data start packet, then data end packet, then response packet
// PTPIP: Get data start packet, then data end packet, then response packet
static struct PtpIpResponseContainer *ptpip_get_response_packet(struct PtpRuntime *r) {
struct PtpIpStartDataPacket *ds = (struct PtpIpStartDataPacket*)(r->data);
if (ds->type == PTPIP_COMMAND_RESPONSE) {
Expand Down
16 changes: 16 additions & 0 deletions src/ptp.h
Original file line number Diff line number Diff line change
Expand Up @@ -130,6 +130,7 @@ struct PtpIpEndDataPacket {
#define PTP_OC_CANON_GetViewFinderImage 0x901D
#define PTP_OC_CANON_LockUI 0x9004
#define PTP_OC_CANON_UnlockUI 0x9005
#define PTP_OC_CANON_DoNothing 0x902F

// EOS specific
#define PTP_OC_EOS_GetStorageIDs 0x9101
Expand Down Expand Up @@ -157,6 +158,18 @@ struct PtpIpEndDataPacket {
#define PTP_OC_EOS_AfCancel 0x9160
#define PTP_OC_EOS_SetDefaultSetting 0x91BE

#define PTP_OC_CANON_ceresCreateFileValue 0x91c1
#define PTP_OC_CANON_ceresRemoveFileValue 0x91c2
#define PTP_OC_CANON_ceresCloseFileValue 0x91c3
#define PTP_OC_CANON_ceresGetWriteObject 0x91c4
#define PTP_OC_CANON_ceresSEndReadObject 0x91c5
#define PTP_OC_CANON_ceresFileAttributesValue 0x91c6
#define PTP_OC_CANON_ceresFileTimeValue 0x91c7
#define PTP_OC_CANON_ceresSeekFileValue 0x91c8
#define PTP_OC_CANON_ceresCreateDirectoryValue 0x91c9
#define PTP_OC_EOS_ceresSendFileInfo 0x91cb
#define PTP_OC_EOS_ceresSendFileInfoListEx 0x91cc

#define PTP_OC_EOS_EnableEventProc 0x9050
#define PTP_OC_EOS_ExecuteEventProc 0x9052
#define PTP_OC_EOS_GetEventProcReturnData 0x9053
Expand Down Expand Up @@ -609,6 +622,9 @@ struct PtpIpEndDataPacket {
#define PTP_OC_ML_LiveBmpRam 0x9996
#define PTP_OC_ML_Live360x240 0x9997

#define PTP_OC_MagicLantern 0x9998
#define PTP_OC_CHDK 0x9999

// Storage Types
#define PTP_ST_Undefined 0x0
#define PTP_ST_FixedROM 0x1
Expand Down

0 comments on commit 5a5e935

Please sign in to comment.