[PATCH] Revisions requested
Jef Driesen
jef at libdivecomputer.org
Sun Nov 2 10:13:31 PST 2014
John,
Nice work. This is already a huge step in the right direction, but we're not
there yet.
There is a problem in the way you store the cochran_data_t structure in the
device handle. Most of this info only used by the dump/foreach function (or one
of its helpers), so it doesn't really belong inside the handle. This results in
a number of problems. For example you allocate several pieces of data (id,
config, etc) in those functions and store them in the handle. But if someone
calls one of those functions a second time, you allocate them again and
overwrite the original pointers. So you'll end up with a memory leak. You can
free the old data first, but I think you're better off using local data
structures because there is no reason why any of this data needs to persist
between the high-level calls.
Overall, I find the logic rather hard to follow because it's spread over all
your cochran_read_* functions. These functions do not only download some data,
but also sets some fields, which are then used in one of the other functions. I
think it would be easier if the processing was a bit more separated from the
downloading. I have the feeling that there's something wrong, but I can't really
tell what or where. Maybe it's just that I don't understand the format very
well. Do you have some data files available?
Note that several of those data pieces have a fixed size, so why even allocate
them? Just use a byte array with the right size. Some like:
struct {
...
unsigned char id0[67];
unsigned char id1[67];
unsigned char config1[512];
unsigned char config2[512];
...
};
Now you no longer have to worry about freeing them. Instead of config1, config2,
etc you could even use an array here. That will make your code even more
generic. Instead of repeating the same code, you can use a loop.
BTW, I'm not sure what's in these config pages, but based on the name, I assume
it contains settings. So this is something applications may want to access
directly. I suspect there the protocol also support changing those settings.
Have a look at the hw_ostc_device_eeprom_{read,write}. (This is certainly not a
must have feature right now, but it's something you may want to keep in mind
already.)
You have the same problem with the progress field. Again, I think it makes more
sense to make this a local variable, and pass it as a parameter to the internal
read function. Note that you're also reporting progress for each individual
step, rather than the entire download.
Those high baudrates are indeed a bit odd. Do they even work? You don't check
the return value of the serial_configure() function. So if the underlying driver
(or OS) doesn't support it, unexpected results may happen. I implemented the
support for non-standard baudrates long time ago, and unfortunately it's not
guaranteed to work everywhere. Initially it was needed for the iconhd backend,
in the end it turned out that this baudrate was a bug in the mares application.
The iconhd uses some microchip with CDC-ACM, where the baudrate doesn't matter
at all. So every value works equally well.
On 28-10-14 01:18, John Van Ostrand wrote:
> Removed dependency on packed structure.
Nice. I noticed that you introduced CMD_* and EMC_* constants to keep the code
readable. An alternative I have used in some backends, is to have a layout
structure containing those offsets. And then you define one such structure for
each model, and store a pointer to the correct table in the device/parser
handle. This allows you to write code like this:
value = array_uint16_le (log + layout->xxx);
You can see this for example in the hw_ostc_parser.c file. The nice thing is
that you can re-use the same code for all models. Adding a new model is just a
matter of adding a new structure.
I'm not saying you can or must use this technique in your backend, but it's
maybe something to consider.
> Removed extraneous close/opens.
I'm glad those are not necessary after all.
> Formated lines to 78 chars.
This wasn't needed. I have no strict limits on the line length. Of course you
should try to keep the line length reasonable, but if you have a longer one once
in a while, I won't complain. Artificially limiting the lines to 78 chars makes
the code only less readable. So please don't do that.
For example some of those long lines are because you have assignments in if
conditions:
if ((rc = cochran_common_serial_open(device, context))
!= DC_STATUS_SUCCESS)
return rc;
replace that with:
rc = cochran_common_serial_open(device, context);
if (rc != DC_STATUS_SUCCESS)
return rc;
Much more readable and shorter too!
> Merged EMC and Commander backends to common.
Great. Just a few issues remaining here.
You named your backend DC_FAMILY_COCHRAN and the corresponding functions
cochran_common_{device,parser}_*. Please name them after one specific model. For
example DC_FAMILY_COCHRAN_COMMANDER and cochran_commander_{device,parser}_*,
etc. That's because in the future, there might be more than one cochran backend.
The backend name is purely internal (except for the family name), so it doesn't
really matter that the commander backend also supports the emc.
For the public header files, make one cochran_commander.h file containing the
open and create functions (e.g. your current cochran.h file), and then a new
cochran.h file that just includes this file. See the existing files for examples.
> Change nanosleep() calls to serial_sleep().
We're getting closer, but the windows build is still broken:
CC cochran_common_parser.lo
In file included from ../../source/src/cochran_common_parser.c:33:
../../source/src/cochran_common.h:73: error: expected specifier-qualifier-list
before 'time_t'
../../source/src/cochran_common_parser.c: In function
'cochran_common_parser_get_datetime':
../../source/src/cochran_common_parser.c:113: error: 'cochran_data_t' has no
member named 'date_format'
../../source/src/cochran_common_parser.c: In function
'cochran_common_parser_get_field':
../../source/src/cochran_common_parser.c:147: warning: control reaches end of
non-void function
../../source/src/cochran_common_parser.c: In function
'cochran_common_parser_samples_foreach':
../../source/src/cochran_common_parser.c:166: warning: control reaches end of
non-void function
../../source/src/cochran_common_parser.c: In function 'cochran_common_handle_event':
../../source/src/cochran_common_parser.c:175: warning: unused variable 'data'
make[1]: *** [cochran_common_parser.lo] Error 1
I think you're missing an #include <time.h> somewhere for the use of time_t in
the cochran_data_t structure. But you shouldn't need that because
libdivecomputer has its own time functions and structures. Use those instead.
> Change cochran_common_dump to use dc_buffer properly.
I still need to look at the details of your new dump implementation. One thing I
did notice is that you forgot to remove the cochran_data_dump from the public
header :-)
That's it for now.
Jef
More information about the devel
mailing list