[PATCH 03/11] Lift the OSTC3 INIT out of open
Jef Driesen
jef at libdivecomputer.org
Mon Dec 15 08:22:25 PST 2014
On 21-11-14 21:28, Anton Lundin wrote:
> --- a/src/hw_ostc3.c
> +++ b/src/hw_ostc3.c
> @@ -67,6 +67,11 @@ typedef struct hw_ostc3_device_t {
> dc_device_t base;
> serial_t *port;
> unsigned char fingerprint[5];
> + enum hw_ostc3_state {
> + NONE,
> + OPEN,
> + DOWNLOAD,
> + } state;
> } hw_ostc3_device_t;
Move the enum outside of the struct and give it a proper typedef. (This is
mainly for the msvc C++ compiler. When defined inside the struct you need to
prefix the values with the C++ hw_ostc3_device_t:: syntax. And that doesn't work
in C mode.)
> static dc_status_t hw_ostc3_device_set_fingerprint (dc_device_t *abstract, const unsigned char data[], unsigned int size);
> @@ -220,6 +225,7 @@ hw_ostc3_device_open (dc_device_t **out, dc_context_t *context, const char *name
> // Set the default values.
> device->port = NULL;
> memset (device->fingerprint, 0, sizeof (device->fingerprint));
> + device->state = NONE;
>
> // Open the device.
> int rc = serial_open (&device->port, context, name);
> @@ -249,18 +255,48 @@ hw_ostc3_device_open (dc_device_t **out, dc_context_t *context, const char *name
> // Make sure everything is in a sane state.
> serial_sleep (device->port, 300);
> serial_flush (device->port, SERIAL_QUEUE_BOTH);
> + device->state = OPEN;
> +
> + *out = (dc_device_t *) device;
> +
> + return DC_STATUS_SUCCESS;
> +}
Why do we need both NONE and OPEN? I don't see any difference between the two.
The api prevents you from returning an handle in the NONE state. So I see no
reason to keep the OPEN state.
> +static dc_status_t
> +hw_ostc3_device_init (dc_device_t *abstract)
> +{
> + hw_ostc3_device_t *device = (hw_ostc3_device_t*) abstract;
> + dc_context_t *context = (abstract ? abstract->context : NULL);
> +
> + if (device->state != OPEN)
> + return DC_STATUS_INVALIDARGS;
This condition can never happen. (see previous comment)
> @@ -269,14 +305,20 @@ static dc_status_t
> hw_ostc3_device_close (dc_device_t *abstract)
> {
> hw_ostc3_device_t *device = (hw_ostc3_device_t*) abstract;
> + dc_status_t status;
>
> - // Send the exit command.
> - dc_status_t status = hw_ostc3_transfer (device, NULL, EXIT, NULL, 0, NULL, 0);
> - if (status != DC_STATUS_SUCCESS) {
> - ERROR (abstract->context, "Failed to send the command.");
> - serial_close (device->port);
> - free (device);
> - return status;
> + if (device->state == NONE)
> + return DC_STATUS_INVALIDARGS;
Same here. If it where possible, you even have a memory leak here. The close
function should always clean up all resources. If the close fails, how are you
supposed to clean up? The return value is purely informational.
>
> // Close the device.
> @@ -313,6 +355,7 @@ dc_status_t
> hw_ostc3_device_version (dc_device_t *abstract, unsigned char data[], unsigned int size)
> {
> hw_ostc3_device_t *device = (hw_ostc3_device_t *) abstract;
> + dc_status_t rc;
Initialize variables as much as possible.
> if (!ISINSTANCE (abstract))
> return DC_STATUS_INVALIDARGS;
> @@ -320,8 +363,11 @@ hw_ostc3_device_version (dc_device_t *abstract, unsigned char data[], unsigned i
> if (size != SZ_VERSION)
> return DC_STATUS_INVALIDARGS;
>
> + if ((rc = hw_ostc3_check_state_or_init(abstract)) != DC_STATUS_SUCCESS)
> + return rc;
Move the assignment out of the if condition. That makes the code more readable.
More information about the devel
mailing list