From 3e2fb1a56292d63813842601011630177f13c3b9 Mon Sep 17 00:00:00 2001 From: Daniel C Date: Fri, 29 Nov 2024 16:40:12 -0500 Subject: [PATCH] Improve documentation --- Doxyfile | 12 +- Makefile | 2 +- docs/DoxygenLayout.xml | 248 +++++++++++++++++++++++++++++++++++++++++ examples/pktest.c | 1 - examples/usb.c | 12 +- examples/wifi.c | 7 +- src/camlib.h | 21 +--- src/cl_backend.h | 25 ++--- src/cl_bind.h | 1 + src/cl_data.h | 15 +-- src/cl_enum.h | 8 ++ src/cl_ops.h | 33 ++---- src/data.c | 3 +- src/lua/lua.c | 4 +- src/ptp.h | 1 + 15 files changed, 303 insertions(+), 90 deletions(-) create mode 100644 docs/DoxygenLayout.xml diff --git a/Doxyfile b/Doxyfile index e673981..893b4f8 100644 --- a/Doxyfile +++ b/Doxyfile @@ -1,4 +1,14 @@ PROJECT_NAME = "camlib" PROJECT_BRIEF = "Documentation for camlib is still a work-in-progress" -INPUT = README.md docs/chdk.md docs/ml.md docs/ptp.md src/camlib.h src/cl_ops.h +INPUT = README.md docs/chdk.md docs/ml.md docs/ptp.md \ +rc/camlib.h src/cl_backend.h src/cl_bind.h src/cl_data.h src/cl_enum.h src/cl_ops.h src/ptp.h USE_MDFILE_AS_MAINPAGE = README.md +GENERATE_LATEX = NO +GENERATE_HTML = YES +SOURCE_BROWSER = YES +LAYOUT_FILE = docs/DoxygenLayout.xml + +VERBATIM_HEADERS = NO + +EXAMPLE_PATH = examples/usb.c +EXAMPLE_PATTERNS = * diff --git a/Makefile b/Makefile index d4552a2..69658a0 100644 --- a/Makefile +++ b/Makefile @@ -1,6 +1,6 @@ -include config.mak -CFLAGS := -Isrc/ -g -fpic -Wall -Wshadow -Wcast-qual -Wpedantic -Werror=incompatible-pointer-types -Werror=deprecated-declarations +CFLAGS := -Isrc/ -g -fpic -Wall -Wshadow -Wcast-qual -Wpedantic -Werror=incompatible-pointer-types -Werror=deprecated-declarations -Wstrict-aliasing=3 CFLAGS += -D CAMLIB_NO_COMPAT -D VERBOSE # Camlib needs to be compiled with these files, with some exceptions: diff --git a/docs/DoxygenLayout.xml b/docs/DoxygenLayout.xml new file mode 100644 index 0000000..1f84b82 --- /dev/null +++ b/docs/DoxygenLayout.xml @@ -0,0 +1,248 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/examples/pktest.c b/examples/pktest.c index ec0a932..2b08f16 100644 --- a/examples/pktest.c +++ b/examples/pktest.c @@ -30,7 +30,6 @@ int main() { cmd.code = PTP_OC_OpenSession; cmd.params[0] = 1; cmd.param_length = 1; - cmd.data_length = 0; int l = ptp_new_cmd_packet(&r, &cmd); print_bytes(r.data, l); diff --git a/examples/usb.c b/examples/usb.c index 27c2e6e..d50f124 100644 --- a/examples/usb.c +++ b/examples/usb.c @@ -1,4 +1,5 @@ -// Test device list API +/// @file +/// @brief Example of using the device list API #include #include #include @@ -15,7 +16,7 @@ static int connect(struct PtpRuntime *r) { } if (ptp_device_init(r)) { - puts("Device connection error"); + printf("Device connection error\n"); return 1; } @@ -27,11 +28,10 @@ static int connect(struct PtpRuntime *r) { } int main() { - struct PtpRuntime r; - ptp_generic_init(&r); + struct PtpRuntime *r = ptp_new(PTP_USB); - if (connect(&r)) return 1; - if (connect(&r)) return 1; + if (connect(r)) return 1; + if (connect(r)) return 1; return 0; } diff --git a/examples/wifi.c b/examples/wifi.c index 7be6bf9..aa52b18 100644 --- a/examples/wifi.c +++ b/examples/wifi.c @@ -1,4 +1,5 @@ -// Test basic opcode, get device properties +/// @file +/// @brief Hello #include #include #include @@ -23,10 +24,8 @@ int main() { r.connection_type = PTP_IP; char *ip = "192.168.1.2"; - ip = "127.0.0.1"; - int port = PTP_IP_PORT; - if (ptpip_connect(&r, ip, port)) { + if (ptpip_connect(&r, ip, PTP_IP_PORT)) { puts("Device connection error"); return 0; } diff --git a/src/camlib.h b/src/camlib.h index 5cbf54e..e746bf3 100644 --- a/src/camlib.h +++ b/src/camlib.h @@ -186,94 +186,74 @@ struct PtpArray { /// @brief Returns the return code (RC) currently in the data buffer. /// @note Not thread safe. -/// @memberof PtpRuntime PUB int ptp_get_return_code(struct PtpRuntime *r); /// @brief Get number of parameters in packet in data buffer /// @note Not thread safe. -/// @memberof PtpRuntime PUB int ptp_get_param_length(struct PtpRuntime *r); /// @brief Get parameter at index i /// @note Not thread safe. -/// @memberof PtpRuntime PUB uint32_t ptp_get_param(struct PtpRuntime *r, int i); /// @brief Get transaction ID of packet in the data buffer /// @note Not thread safe. -/// @memberof PtpRuntime PUB int ptp_get_last_transaction_id(struct PtpRuntime *r); /// @brief Get ptr of packet payload in data buffer, after packet header /// @note Not thread safe. -/// @memberof PtpRuntime PUB uint8_t *ptp_get_payload(struct PtpRuntime *r); /// @brief Get length of payload returned by ptp_get_payload /// @note Not thread safe. -/// @memberof PtpRuntime PUB int ptp_get_payload_length(struct PtpRuntime *r); /// @brief Allocate new PtpRuntime based on bitfield options - see PtpConnType -/// @memberof PtpRuntime PUB struct PtpRuntime *ptp_new(int options); /// @brief Reset all session-specific fields of PtpRuntime - both libusb and libwpd backends call /// this before establishing connection, so calling this is not required -/// @memberof PtpRuntime PUB void ptp_reset(struct PtpRuntime *r); /// @brief Init PtpRuntime locally - uses default recommended settings (USB) -/// @memberof PtpRuntime PUB void ptp_init(struct PtpRuntime *r); /// @brief Frees PtpRuntime data buffer - doesn't free the actual structure, or device info (yet) -/// @memberof PtpRuntime PUB void ptp_close(struct PtpRuntime *r); /// @brief Send a command request to the device with no data phase -/// @memberof PtpRuntime PUB int ptp_send(struct PtpRuntime *r, struct PtpCommand *cmd); /// @brief Send a command request to the device with a data phase (thread safe) -/// @memberof PtpRuntime PUB int ptp_send_data(struct PtpRuntime *r, struct PtpCommand *cmd, void *data, int length); /// @brief Try and get an event from the camera over int endpoint (USB-only) -/// @memberof PtpRuntime PUB int ptp_get_event(struct PtpRuntime *r, struct PtpEventContainer *ec); /// @brief Unlock the IO mutex (unless it was kept locked) -/// @memberof PtpRuntime PUB void ptp_mutex_unlock(struct PtpRuntime *r); /// @brief Completely unlock the mutex for the current thread, to ensure there isn't a deadlock. /// This is normally used on handling errors, and when exiting a thread. -/// @memberof PtpRuntime PUB void ptp_mutex_unlock_thread(struct PtpRuntime *r); /// @brief Lock the IO mutex - only should be used by backend -/// @memberof PtpRuntime PUB void ptp_mutex_lock(struct PtpRuntime *r); /// @brief Gets type of device from r->di /// @returns enum PtpDeviceType -/// @memberof PtpRuntime PUB int ptp_device_type(struct PtpRuntime *r); /// @brief Check if an opcode is supported by looking through supported props in r->di /// @returns 1 if yes, 0 if no -/// @memberof PtpRuntime PUB int ptp_check_opcode(struct PtpRuntime *r, int opcode); /// @brief Check if a property code is supported by looking through supported props in r->di /// @returns 1 if yes, 0 if no -/// @memberof PtpRuntime PUB int ptp_check_prop(struct PtpRuntime *r, int code); /// @brief Mostly for internal use - realloc the data buffer /// @note r->data will be reassigned, any old references must be updated -/// @memberof PtpRuntime PUB int ptp_buffer_resize(struct PtpRuntime *r, size_t size); // Data structure functions @@ -285,6 +265,7 @@ PUB int ptp_write_string(uint8_t *dat, const char *string); PUB int ptp_write_utf8_string(void *dat, const char *string); PUB int ptp_read_uint16_array(const uint8_t *dat, uint16_t *buf, int max, int *length); PUB int ptp_read_uint16_array_s(uint8_t *bs, uint8_t *be, uint16_t *buf, int max, int *length); +// TODO: This is bad inline static int ptp_write_u8 (void *buf, uint8_t out) { ((uint8_t *)buf)[0] = out; return 1; } inline static int ptp_write_u16(void *buf, uint16_t out) { ((uint16_t *)buf)[0] = out; return 2; } inline static int ptp_write_u32(void *buf, uint32_t out) { ((uint32_t *)buf)[0] = out; return 4; } diff --git a/src/cl_backend.h b/src/cl_backend.h index 5e92397..a28806f 100644 --- a/src/cl_backend.h +++ b/src/cl_backend.h @@ -1,6 +1,12 @@ +/** \file */ #ifndef CL_BACKEND_H #define CL_BACKEND_H +/// @defgroup Backend Backend interface +/// @brief Layer over OS-dependent I/O interface +/// @addtogroup Backend +/// @{ + #define PTP_TIMEOUT 1000 /// @brief Linked-list entry for a single USB device @@ -24,64 +30,47 @@ struct PtpDeviceEntry { /// @brief Get a linked list of USB or PTP Devices /// @returns linked list of devices or NULL if no devices are connected (or OS error) -/// @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 /// @note Sets kill switch to 0 -/// @memberof PTP/USB int ptp_device_open(struct PtpRuntime *r, struct PtpDeviceEntry *entry); /// @brief Connects to the first PTP device it finds int ptp_device_init(struct PtpRuntime *r); /// @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); /// @brief Reset the USB endpoints if possible -/// @memberof PTP/USB int ptp_device_reset(struct PtpRuntime *r); /// @brief Send packets in r->data -/// @memberof PTP/USB int ptp_send_packet(struct PtpRuntime *r, int length); /// @brief Receive all packets into r->data -/// @memberof PTP/USB int ptp_receive_all_packets(struct PtpRuntime *r); /// @brief Poll the interrupt endpoint -/// @memberof PTP/USB int ptp_read_int(struct PtpRuntime *r, void *to, int length); /// @brief Disconnect from the current device -/// @memberof PTP/USB int ptp_device_close(struct PtpRuntime *r); /// @brief Connect to a TCP port on the default network adapter /// @note Sets kill switch to 0 -/// @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); -/// @memberof PTP/IP int ptpip_close(struct PtpRuntime *r); void ptpusb_free_device_list_entry(void *); @@ -89,4 +78,6 @@ void ptpusb_free_device_list_entry(void *); /// @brief Get status of connected device int ptpusb_get_status(struct PtpRuntime *r); +/// @} + #endif diff --git a/src/cl_bind.h b/src/cl_bind.h index d056401..913c728 100644 --- a/src/cl_bind.h +++ b/src/cl_bind.h @@ -1,3 +1,4 @@ +/** \file */ #ifndef CL_BIND_H #define CL_BIND_H diff --git a/src/cl_data.h b/src/cl_data.h index 8a623c7..9d25021 100644 --- a/src/cl_data.h +++ b/src/cl_data.h @@ -1,12 +1,12 @@ +/** \file */ // PTP data structures - some very similar to the exact MTP/PTP spec. -// Variable sized arrays/strings are replaced with fixed arrays, to allow -// packing and unpacking in the same struct. #ifndef CL_DATA_H #define CL_DATA_H -// Need to avoid structure packing - most architectures are fine with this -// (accessing a 32 bit integer at an unaligned address - but some might have problems) -#pragma pack(push, 1) +/// @defgroup Data Data structures +/// @brief Functions to pack/unpack PTP data structures +/// @addtogroup Data +/// @{ struct PtpStorageIds { uint32_t length; @@ -161,9 +161,6 @@ enum PtpCHDKCommands { PTP_CHDK_UploadFile = 5, }; -#pragma pack(pop) - -#ifdef CAMLIB_INCLUDE_IMPL int ptp_pack_object_info(struct PtpRuntime *r, struct PtpObjectInfo *oi, uint8_t *buf, int max); int ptp_parse_prop_value(struct PtpRuntime *r); @@ -191,5 +188,3 @@ int ptp_eos_get_imgformat_value(uint32_t data[5]); void *ptp_pack_chdk_upload_file(struct PtpRuntime *r, char *in, char *out, int *length); #endif - -#endif diff --git a/src/cl_enum.h b/src/cl_enum.h index 142ebe2..983f616 100644 --- a/src/cl_enum.h +++ b/src/cl_enum.h @@ -1,8 +1,14 @@ +/** \file */ #ifndef CL_ENUM_H #define CL_ENUM_H #define MAX_ENUM_LENGTH 64 +/// @defgroup Enums Enums +/// @brief API to get string that represents PTP code +/// @addtogroup Enums +/// @{ + int ptp_enum_all(char *string); int ptp_enum(int type, char *string); char *ptp_get_enum(int type, int vendor, int id); @@ -33,4 +39,6 @@ struct PtpEnum { extern int ptp_enums_length; extern struct PtpEnum ptp_enums[]; +/// @} + #endif diff --git a/src/cl_ops.h b/src/cl_ops.h index 8da0b3b..b370e16 100644 --- a/src/cl_ops.h +++ b/src/cl_ops.h @@ -21,62 +21,52 @@ struct PtpLiveviewParams { enum PtpLiveViewFormat format; }; +/// @defgroup Operations PTP Operations +/// @brief PTP opcode functions - may also call unpack data structures +/// @addtogroup Operations +/// @{ + int ptp_liveview_params(struct PtpRuntime *r, struct PtpLiveviewParams *params); /// @brief Set a generic property - abstraction over SetDeviceProp /// @note May reject writes if an invalid property is found (see event code) -/// @memberof PtpRuntime int ptp_set_generic_property(struct PtpRuntime *r, const char *name, int value); /// @brief Call before taking a picture - this is generally for 'focusing' /// On some cameras this does nothing. /// @note This is meant for a onMouseDown-like event. ptp_take_picture should be called on onMouseUp -/// @memberof PtpRuntime int ptp_pre_take_picture(struct PtpRuntime *r); /// @brief Call after calling ptp_pre_take_picture - this time a picture will be taken. -/// @memberof PtpRuntime int ptp_take_picture(struct PtpRuntime *r); /// @brief Open a new session - required for most commands -/// @memberof PtpRuntime int ptp_open_session(struct PtpRuntime *r); -/// @memberof PtpRuntime int ptp_close_session(struct PtpRuntime *r); -/// @memberof PtpRuntime int ptp_get_device_info(struct PtpRuntime *r, struct PtpDeviceInfo *di); /// @brief Returns allocated array of storage IDs /// call free() afterwards int ptp_get_storage_ids(struct PtpRuntime *r, struct PtpArray **a); -/// @memberof PtpRuntime int ptp_init_capture(struct PtpRuntime *r, int storage_id, int object_format); -/// @memberof PtpRuntime int ptp_init_open_capture(struct PtpRuntime *r, int storage_id, int object_format); -/// @memberof PtpRuntime int ptp_terminate_open_capture(struct PtpRuntime *r, int trans); -/// @memberof PtpRuntime int ptp_get_storage_info(struct PtpRuntime *r, int id, struct PtpStorageInfo *si); -/// @memberof PtpRuntime int ptp_send_object_info(struct PtpRuntime *r, int storage_id, int handle, struct PtpObjectInfo *oi); -/// @memberof PtpRuntime int ptp_get_prop_value(struct PtpRuntime *r, int code); -/// @memberof PtpRuntime int ptp_set_prop_value(struct PtpRuntime *r, int code, int value); -/// @memberof PtpRuntime int ptp_set_prop_value_data(struct PtpRuntime *r, int code, void *data, int length); -/// @memberof PtpRuntime int ptp_get_prop_desc(struct PtpRuntime *r, int code, struct PtpPropDesc *pd); /// @brief Gets a list of object handles in a storage device or folder. @@ -84,48 +74,37 @@ int ptp_get_prop_desc(struct PtpRuntime *r, int code, struct PtpPropDesc *pd); // @param format Can specify file format ID, or zero for all IDs // @param in Can be folder object ID, or 0 for recursive (entire filesystem) // @param[out] a Output array is a pointer to data packet, and will be overwritten by new operations -/// @memberof PtpRuntime int ptp_get_object_handles(struct PtpRuntime *r, int id, int format, int in, struct PtpArray **a); -/// @memberof PtpRuntime int ptp_get_object_info(struct PtpRuntime *r, uint32_t handle, struct PtpObjectInfo *oi); -/// @memberof PtpRuntime int ptp_move_object(struct PtpRuntime *r, int storage_id, int handle, int folder); -/// @memberof PtpRuntime int ptp_delete_object(struct PtpRuntime *r, int handle, int format_code); /// @brief Raw JPEG data is accessible from ptp_get_payload() /// @note Not thread safe. -/// @memberof PtpRuntime int ptp_get_thumbnail(struct PtpRuntime *r, int handle); /// @note Not thread safe. -/// @memberof PtpRuntime int ptp_get_partial_object(struct PtpRuntime *r, uint32_t handle, int offset, int max); /// @brief Download an object -/// @memberof PtpRuntime int ptp_get_object(struct PtpRuntime *r, int handle); /// @brief Download an object from handle, to a local file (uses GetPartialObject) -/// @memberof PtpRuntime 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. /// @param[out] s Output structure, caller must free -/// @memberof PtpRuntime int ptp_get_all_known(struct PtpRuntime *r, struct PtpGenericEvent **s, int *length); /// @note PTP/IP only -/// @memberof PtpRuntime int ptpip_init_events(struct PtpRuntime *r); /// @note PTP/IP only -/// @memberof PtpRuntime int ptpip_init_command_request(struct PtpRuntime *r, const char *device_name); // EOS Only functions - not for Canon point and shoot @@ -175,4 +154,6 @@ int ptp_eos_fa_get_build_version(struct PtpRuntime *r, char *buffer, int max); /// @returns enum PtpGeneralError, 0 for 'camera is busy', or the size of the image in the payload int ptp_eos_get_liveview(struct PtpRuntime *r); +/** @}*/ + #endif diff --git a/src/data.c b/src/data.c index 58dcbeb..9563d6f 100644 --- a/src/data.c +++ b/src/data.c @@ -63,6 +63,7 @@ int ptp_get_prop_size(uint8_t *d, int type) { return 0; } +// Cheap dumb function int ptp_parse_data_u32(void *d, int type, int *out) { uint8_t a; uint16_t b; @@ -80,8 +81,6 @@ int ptp_parse_data_u32(void *d, int type, int *out) { ptp_read_u32(d, &c); (*out) = (int)c; return 4; } - // TODO: function to preserve signedness - // skip the array return ptp_get_prop_size(d, type); } diff --git a/src/lua/lua.c b/src/lua/lua.c index 9473d90..8c6d550 100644 --- a/src/lua/lua.c +++ b/src/lua/lua.c @@ -104,9 +104,9 @@ static int mylua_send_operation(lua_State *L) { int rc = 0; if (data_array == NULL) { - rc = ptp_generic_send(r, &cmd); + rc = ptp_send(r, &cmd); } else { - rc = ptp_generic_send_data(r, &cmd, data_array, data_length); + rc = ptp_send_data(r, &cmd, data_array, data_length); } lua_newtable(L); diff --git a/src/ptp.h b/src/ptp.h index a5dc9f0..10fde26 100644 --- a/src/ptp.h +++ b/src/ptp.h @@ -1,3 +1,4 @@ +/** \file */ // This file describes Picture Transfer Protocol (ISO 15740) // And many vendor opcodes, property codes, and event codes.