Thread: [Hamlib-developer] frontend API function reduction
Library to control radio transceivers and receivers
Brought to you by:
n0nb
From: Frank S. <vk...@ix...> - 2000-09-15 05:17:15
|
Hi, Well nothing compiles now (sob), so lets get the general API and interwork API firmed up... I am keen to get a good general (extensible) infrastructure in place. Also, just a note,, CVS checkins that impact clean compiles (and there will be many , I am sure) during later project stages we should flag. eg: If previous co compiles, and your or my next ci is known to break this, we should think about tagging it in CVS. Comments ?? Anyway Some API thoughts .... <snip> /* * * API Notes -- FS * */ I think it is more intuitive to code things as follows... backend must implement all opcodes (of course) this may infer function names like thus (at least according to yaesu docs not passing vfo as a parameter - aaarrrgh). eg 6 functions in backend .. int cmd_set_freq_main_vfo_hz(RIG *rig,freq_t freq, rig_mode_t mode); int cmd_set_freq_sat_rx_vfo_hz(RIG *rig,freq_t freq, rig_mode_t mode); int cmd_set_freq_sat_tx_vfo_hz(RIG *rig,freq_t freq, rig_mode_t mode); long int cmd_get_freq_mode_status_main_vfo(RIG *rig, unsigned char *mode); long int cmd_get_freq_mode_status_sat_rx_vfo(RIG *rig, unsigned char *mode); long int cmd_get_freq_mode_status_sat_tx_vfo(RIG *rig, unsigned char *mode); This creates a large function namespace, this is ok as there shall be wrappers for them up front anyway. Also, bakend must test all opcodes anyway. However, frontend should have reduced namespace for function calls. eg result, 2 functions up front .... cmd_set_freq(RIG *rig,freq_t freq, rig_mode_t mode, vfo_t vfo ) long int cmd_get_freq_mode_status(RIG *rig, unsigned char *mode, vfo_t vfo); ie: 3 to 1 reduction, and an emphasis on what parameters you are setting on the rig, driven more by the parameter list, than extending function names. so, lets create some enums enum rig_vfo_e { RIG_VFO_MAIN = 0, RIG_VFO_RX, RIG_VFO_TX, RIG_VFO_SUB, /* etc */ } typedef enum rig_vfo_e rig_vfo_t; enum rig_rptr_shift_e { RIG_RPT_SHIFT_NONE = 0, RIG_RPT_SHIFT_MINUS, RIG_RPT_SHIFT_PLUS, /* etc */ } <snip> /Frank.. (yawn...) -- Frank Singleton VK3FCS Email: victor kilo three foxtrot charlie sierra at ix dot netcom dot com |
From: Stephane F. <f4...@fr...> - 2000-09-16 00:59:29
|
On Fri, Sep 15, 2000, Frank Singleton wrote: > > Well nothing compiles now (sob), so lets get the > general API and interwork API firmed up... > Sorry about that, I forgot to let you know in my previous mail... Acutally, I was so eager to show off the new frontend/backend approach! Usually, we don't write the software specifications after the development :-) The same goes for an API implementation. So it doesn't matter much if the code is broken if the API is not yet specified! We're still in ALPHA stage, after all. Clean compiles is yet BETA (and considered stable for MS :). > I am keen to get a good general (extensible) infrastructure in place. > good! let's do it! > eg: If previous co compiles, and your or my next ci is known > to break this, we should think about tagging it in CVS. > Agree with you! To me, the hamlib-1.0.3 is the latest clean compile. Also about version numbers, would it be better to have odd numbers for development phases, and even number for stable code, ala Linux kernel? With 1.0.3, people might think that the library is already ready to use (which is not!) > > backend must implement all opcodes (of course) ..provided we have the specs. May be we can sumon some help by sending an announce on lin...@vg... and lin...@de... mailing lists. > This creates a large function namespace, this is ok as there > shall be wrappers for them up front anyway. Also, bakend must test > all opcodes anyway. > > However, frontend should have reduced namespace for function calls. > > eg result, 2 functions up front .... > > cmd_set_freq(RIG *rig,freq_t freq, rig_mode_t mode, vfo_t vfo ) > long int cmd_get_freq_mode_status(RIG *rig, unsigned char *mode, vfo_t > vfo); > Looks definitely better this way! Just a question: what if the application just wants to change the mode only? It might be troublesome in certain case to have to remember the current frequency or having to query it. > > so, lets create some enums > allright! more to come I'm sure. new stuff I've checked in: serial.c -------- serial_open() open and setup a serial port, fully RIG* aware, cloned from open_port2() write_block2() handles optional write_delay read_block() does passive blocking(select), and have timeout handling open_port2() has been busted (outdated refs to rig_caps), use serial_open()? Question: What do you think of write_block2() ? Would you agree to replace write_block() by write_block2() ? frontend: -------- rigcaps.h has been cut and pasted into rig.h in order to fix the cyclic forward references. Updated some data struct, added flow_control/retry/timeout See the testrig.c example to see how to use the frontend lib. Note: the Makefiles are still broken.. testrig.c --------- modified to use rig_init/rig_open. Should work with an operating backend.. Conclusion: ---------- The good news is hamlib now compiles OK back again. Next stage: the linking ;-) I'm sorry Frank, with the new API and frontend/backend, you'll have to modify your ft847 code. BTW, do all the Yeasu rigs have the same "CAT" protocol as Icoms do with "CI-V" ? In this case, may be it will be easier for you to factorize some code. -- Stephane Fillod F4CFE |
From: Frank S. <vk...@ix...> - 2000-09-16 05:23:01
|
Stephane Fillod wrote: > > ..provided we have the specs. May be we can sumon some help > by sending an announce on lin...@vg... > and lin...@de... mailing lists. > Yep, let me fix ft747 and ft847 asap, and we can announce for help and show some partly working stuff ;-) > > cmd_set_freq(RIG *rig,freq_t freq, rig_mode_t mode, vfo_t vfo ) > > long int cmd_get_freq_mode_status(RIG *rig, unsigned char *mode, vfo_t > > vfo); > > > Looks definitely better this way! > Just a question: what if the application just wants to change > the mode only? It might be troublesome in certain case to have > to remember the current frequency or having to query it. true, I guess we have some options... API provides cmd_set_freq_(RIG *rig,freq_t freq, rig_mode_t mode, vfo_t vfo ) and possibly cmd_set_mode(RIG *rig, rig_mode_t mode) cmd_set_vfo(RIG *rig, vfo_t vfo) and allow backend to if an app calls the generic function cmd_set_freq_mode_vfo(RIG *rig,freq_t freq, rig_mode_t mode, vfo_t vfo ) then if rig later sends cmd_set_mode(RIG *rig, rig_mode_t mode), we could.. 2. preserve last command params sent in the backend libs. this way a cmd_set_mode(rig_mode_t mode) can call a cmd_set_freq( ..freq,mode) if that rigs opcode command require all aparameters. Otherwise the backend just sends the cmd_set_mode() change.A small overhead, but covers both cases. (less yuck !) ps: my 2 yaesu can handle a mode change independant of other stuff 3. Pass NULL parameters into the cmd_set for those things you dont want to change since previos command ?? comments ????? > serial.c > -------- > serial_open() open and setup a serial port, fully RIG* aware, > cloned from open_port2() great ! > write_block2() handles optional write_delay > read_block() does passive blocking(select), and have timeout handling > open_port2() has been busted (outdated refs to rig_caps), use serial_open()? > yep, we can kill this. > Question: What do you think of write_block2() ? Would you agree > to replace write_block() by write_block2() ? > yep, that way it covers all rig types, I had to start somewhere :-) > Next stage: the linking ;-) ahh lovely stuff ! > > I'm sorry Frank, with the new API and frontend/backend, you'll have > to modify your ft847 code. will update this weekend, its Olympics in vk3 land (actually vk2) but I live and watch from texas USA. BTW, do all the Yeasu rigs have the same > "CAT" protocol as Icoms do with "CI-V" ? In this case, may be it will > be easier for you to factorize some code. so far the 2 yaesus have same 5 block cmd, but no commonality between opcodes and freq packing into BCD etc.. / Frank.. > > -- > Stephane Fillod F4CFE > _______________________________________________ > Hamlib-developer mailing list > Ham...@li... > http://lists.sourceforge.net/mailman/listinfo/hamlib-developer -- Frank Singleton VK3FCS Email: victor kilo three foxtrot charlie sierra at ix dot netcom dot com |
From: Frank S. <vk...@ix...> - 2000-09-16 06:34:17
|
Hi, previously, on this channel..... > > > > cmd_set_freq(RIG *rig,freq_t freq, rig_mode_t mode, vfo_t vfo ) > > > long int cmd_get_freq_mode_status(RIG *rig, unsigned char *mode, vfo_t > > > vfo); > > > > > Looks definitely better this way! > > Just a question: what if the application just wants to change > > the mode only? It might be troublesome in certain case to have > > to remember the current frequency or having to query it. > > true, I guess we have some options... > > API provides > cmd_set_freq_(RIG *rig,freq_t freq, rig_mode_t mode, vfo_t vfo ) > > and possibly > cmd_set_mode(RIG *rig, rig_mode_t mode) > cmd_set_vfo(RIG *rig, vfo_t vfo) I must have had too many beers during the Olympic opening ceremony :-) Actually now that I think about it, the cleanest approach is probably for the frontend API to provide as a minimum functions like cmd_set_mode(RIG *rig, rig_mode_t mode) cmd_set_vfo(RIG *rig, vfo_t vfo) cmd_set_freq_(RIG *rig, freq_t freq) cmd_set_filter_(RIG *rig, filter_t filter) and in general cmd_set_xxx_(RIG *rig, xxx_t xxx) and that optional convenience functions like cmd_set_channel_(RIG *rig,freq_t freq, rig_mode_t mode, vfo_t vfo ....,,,, filter_t filter..) is some frontend convenience function that backend libs can handle either directly as is toward the rig if the rig can handle it that way, or the backend lib breaks it into the simpler functions shown above if the rig needs it that way. We dont care up the front how its done int the back of course (apart from efficiency issues of course)! So, 1 frontend convenience functions may cause multiple backend calls to the rig as it iterates through the convenience functions argumant list and calls individual "primitives" towards the rig. Ok, now I sleep better !! Should be no state issues to deal with.. just trying to avoid long function names like cmd_set_freq_mode_vfo_filter_power_this_that_whatever(....) Comments ?? /Frank.. |
From: Frank S. <vk...@ix...> - 2000-09-16 22:15:24
|
Hi, Thinking about naming convention for maintenance :0 when we have all these functions in the backend mapping (via pointers )onto the frontend declarations.. frontend prototype says... <snip> from rig.h struct rig_caps { rig_model_t rig_model; /* eg. RIG_MODEL_FT847 */ unsigned char model_name[RIGNAMSIZ]; /* eg "ft847" */ unsigned char mfg_name[RIGNAMSIZ]; /* eg "Yeasu" */ char version[RIGVERSIZ]; /* driver version, eg "0.5" */ enum rig_status_e status; /* among ALPHA, BETA, STABLE, NEW */ enum rig_type_e rig_type; int serial_rate_min; /* eg 4800 */ int serial_rate_max; /* eg 9600 */ int serial_data_bits; /* eg 8 */ int serial_stop_bits; /* eg 2 */ enum serial_parity_e serial_parity; /* */ enum serial_handshake_e serial_handshake; /* */ int write_delay; /* delay in ms between each byte sent out */ int timeout; /* in ms */ int retry; /* maximum number of retries, 0 to disable */ struct freq_range_list rx_range_list[FRQRANGESIZ]; struct freq_range_list tx_range_list[FRQRANGESIZ]; int (*rig_init)(RIG *rig); /* setup *priv */ int (*rig_cleanup)(RIG *rig); int (*rig_open)(RIG *rig); /* called when port just opened */ int (*rig_close)(RIG *rig); /* called before port is to close */ int (*rig_probe)(RIG *rig); /* Experimental: may work.. */ /* cmd API below */ int (*set_freq_main_vfo_hz)(RIG *rig, freq_t freq, rig_mode_t mode); /* int (*set_freq)(RIG *rig, freq_t freq); int (*set_mode)(RIG *rig, rig_mode_t mode); int (*set_vfo)(RIG *rig, rig_vfo_t vfo); */ <snip> So if frontend API says int (*set_freq)(RIG *rig, freq_t freq); int (*set_mode)(RIG *rig, rig_mode_t mode); int (*set_vfo)(RIG *rig, rig_vfo_t vfo); backend equivalents for ft747 int ft747_set_freq(RIG *rig, freq_t freq); int ft747_set_mode(RIG *rig, rig_mode_t mode); int ft747_(RIG *rig, rig_vfo_t vfo); backend equivalents for ft847 int ft847_set_freq(RIG *rig, freq_t freq); int ft847_set_mode(RIG *rig, rig_mode_t mode); int ft847_(RIG *rig, rig_vfo_t vfo); etc.. What do you think ?? -- Frank |
From: Stephane F. <f4...@fr...> - 2000-09-19 06:19:19
|
Frank Singleton wrote: > > So if frontend API says > > int (*set_freq)(RIG *rig, freq_t freq); > int (*set_mode)(RIG *rig, rig_mode_t mode); > int (*set_vfo)(RIG *rig, rig_vfo_t vfo); > > backend equivalents for ft747 > > int ft747_set_freq(RIG *rig, freq_t freq); > int ft747_set_mode(RIG *rig, rig_mode_t mode); int ft747_set_vfo(RIG *rig, rig_vfo_t vfo); [...] > etc.. > > What do you think ?? make sense! freq_t cmd_get_freq(RIG *rig); Just a word about the {cmd,backend}_get_* functions. IMO, it's not a good idea to have them return the data immediately, because we may loose the return code in case of failure. So I would stick with something like this: int cmd_get_freq(RIG *rig, freq_t *freq); Your struct channel looks fine, we need also to support splits: So instead of having only one "freq_t freq" field, maybe we ought to have freq_t rxfreq; freq_t txfreq; and also: unsigned long func; /* bitwise OR'ed RIG_FUNC_AGC, NB, et al. */ unsigned long tuning_step; /* freq_t is not needed here */ rig_rptr_shift_t rptr_shift; /* repeater shift is not (cross)split */ Not to mention the Preamp/Att state (expressed in dB?), and the selected antenna too (provided the rig supports it of course). Correct me if I'm wrong, the purpose of the "struct channel" is designed to manage freq memories, right? Oh, yeah, it can be convenient to use it to get the state of the current vfo, all at once! is what you intended with get_channel/set_channel or is it for memory managment exclusively? maybe both if the memory number is not defined (eg. -1)? Comments? -- Stephane F4CFE |
From: Frank S. <vk...@ix...> - 2000-09-23 05:37:05
|
Stephane Fillod wrote: > ... > Just a word about the {cmd,backend}_get_* functions. IMO, it's not a good > idea to have them return the data immediately, because we may loose > the return code in case of failure. So I would stick with something like > this: > int cmd_get_freq(RIG *rig, freq_t *freq); > I like this format, set passes freq, get passes *freq etc.. and returning "int" covers return code.. > Your struct channel looks fine, we need also to support splits: > So instead of having only one "freq_t freq" field, > maybe we ought to have > > freq_t rxfreq; > freq_t txfreq; > > and also: > > unsigned long func; /* bitwise OR'ed RIG_FUNC_AGC, NB, et al. */ > unsigned long tuning_step; /* freq_t is not needed here */ > rig_rptr_shift_t rptr_shift; /* repeater shift is not (cross)split */ > > Not to mention the Preamp/Att state (expressed in dB?), and the selected > antenna too (provided the rig supports it of course). > > Correct me if I'm wrong, the purpose of the "struct channel" is designed > to manage freq memories, right? Yep.. >Oh, yeah, it can be convenient > to use it to get the state of the current vfo, all at once! is what > you intended with get_channel/set_channel or is it for memory managment > exclusively? maybe both if the memory number is not defined (eg. -1)? > Hopefully we can use it for both .. > Comments? frontend starting to look good. Perhaps a "general.c" file for stuff like hex_dump(), bcd conversions, dBm <-> milliwatts, whatever etc so I can rip them out of serial.[ch] Comments ?? /Frank -- Frank Singleton VK3FCS Email: victor kilo three foxtrot charlie sierra at ix dot netcom dot com |
From: Stephane F. <f4...@fr...> - 2000-09-18 06:17:24
|
Frank Singleton wrote: > > Actually now that I think about it, the cleanest approach > is probably for the frontend API to provide as a minimum functions > like > > cmd_set_mode(RIG *rig, rig_mode_t mode) > cmd_set_vfo(RIG *rig, vfo_t vfo) > cmd_set_freq_(RIG *rig, freq_t freq) > cmd_set_filter_(RIG *rig, filter_t filter) > > and in general > cmd_set_xxx_(RIG *rig, xxx_t xxx) and cmd_get_xxx(RIG *rig, xxx_t *xxx) REM: the problem with xxxx_t cmd_get_xxx(RIG *rig) would be the unability to check the return code. BTW, is the "_" in "cmd_set_xxx_" a typo ? Also, I'm thinking that the "cmd_" prefix can generate some namespace clashes (well, no if the other objects is not dealing with vfo's and ham specific stuff :). Anyway, would it be better to have this: rig_set_mode(RIG *rig, rig_mode_t mode) rig_set_vfo(RIG *rig, vfo_t vfo) rig_set_freq(RIG *rig, freq_t freq) rig_set_filter(RIG *rig, filter_t filter) Talking about namespace, I'd prefer to have mode_t instead of rig_mode_t. Should you see any concern? About convenience functions like: > > cmd_set_channel_(RIG *rig,freq_t freq, rig_mode_t mode, vfo_t vfo > ....,,,, filter_t filter..) > > is some frontend convenience function that backend libs can handle > either directly as is toward the rig if the rig can handle it that way, > or the backend lib breaks it into the simpler functions shown above if > the rig needs it that way. We dont care up the front how its done > int the back of course (apart from efficiency issues of course)! > In your previous mail, you were proposing that we can pass NULL parameters into the cmd_set for those things you dont want to change since previos command. Well, it depends on what your understanding of NULL. For instance, 0 can be meaningfull for the vfo_t type, etc. (anyway, we can use -1) > > Ok, now I sleep better !! > Sometimes, coding is like certain ham bands, it's only open at night :-) -- Stephane F4CFE |
From: Frank S. <vk...@ix...> - 2000-09-18 23:21:39
|
Stephane Fillod wrote: <snip> > REM: the problem with xxxx_t cmd_get_xxx(RIG *rig) would be the > unability to check the return code. I have seen in some circumstances the use of stuff like struct ret_val { return_value; int validity_indicator; } struct ret_val *get_whatever(..) So when you get a ptr to ret_val when returning from the function, you can always check the "data valid indicator" to see if there is a proper return_value, or if the indicator says, an error occurred. Could we use this for setting and getting data ?? Or, pass &result into functions so that it may be set like int rig_get_mode(RIG *rig, mode_t mode, int *result) ie: rig_get_mode updates mode and result. Comments ?? > > BTW, is the "_" in "cmd_set_xxx_" a typo ? TYPO !! :-() > > Also, I'm thinking that the "cmd_" prefix can generate some namespace > clashes (well, no if the other objects is not dealing with vfo's > and ham specific stuff :). Anyway, would it be better to have this: > > rig_set_mode(RIG *rig, rig_mode_t mode) > rig_set_vfo(RIG *rig, vfo_t vfo) > rig_set_freq(RIG *rig, freq_t freq) > rig_set_filter(RIG *rig, filter_t filter) > Thats fine, I am glad we can agree before the API gets too big :-) > Talking about namespace, I'd prefer to have mode_t instead of rig_mode_t. > Should you see any concern? mode_t looks good to me > > About convenience functions like: > > > > cmd_set_channel_(RIG *rig,freq_t freq, rig_mode_t mode, vfo_t vfo > > ....,,,, filter_t filter..) > > > > is some frontend convenience function that backend libs can handle > > either directly as is toward the rig if the rig can handle it that way, > > or the backend lib breaks it into the simpler functions shown above if > > the rig needs it that way. We dont care up the front how its done > > int the back of course (apart from efficiency issues of course)! > > > > In your previous mail, you were proposing that we can pass NULL > parameters into the cmd_set for those things you > dont want to change since previos command. Well, it depends > on what your understanding of NULL. For instance, 0 can be meaningfull > for the vfo_t type, etc. (anyway, we can use -1) I guess we should have a value that has no meaning in any other context than indicating PARAM_NULL (-1 is a candidate of course). But, using rig_set_mode(rig,mode) is maybe cleaner than rig_set_channel(rig,NULL_PARAM, mode, NULL_PARAM, NULL_PARAM ..) > > Ok, now I sleep better !! > > > > Sometimes, coding is like certain ham bands, > it's only open at night :-) > Yeah, I sometimes have bit too much D-layer absorbption in the neural net sometimes.. :) > -- > Stephane F4CFE > Also, many times I get the following errors from your mail ********************************************** ** THIS IS A WARNING MESSAGE ONLY ** ** YOU DO NOT NEED TO RESEND YOUR MESSAGE ** ********************************************** The original message was received at Mon, 18 Sep 2000 11:18:14 +0200 from cismrelais.univ-lyon1.fr [134.214.101.250] ----- The following addresses had transient non-fatal errors ----- ste...@en... (expanded from: <ste...@in...>) OR ********************************************** ** THIS IS A WARNING MESSAGE ONLY ** ** YOU DO NOT NEED TO RESEND YOUR MESSAGE ** ********************************************** The original message was received at Mon, 18 Sep 2000 07:59:37 +0200 from cismrelais.univ-lyon1.fr [134.214.101.250] ----- The following addresses had transient non-fatal errors ----- ste...@en... (expanded from: <ste...@in...>) ----- Transcript of session follows ----- ... while talking to hotu.ens.insa-rennes.fr.: >>> MAIL From:<vk...@ix...> SIZE=1811 <<< 451 <vk...@ix...>... Go away! ste...@en...... Deferred: 451 <vk...@ix...>... Go away! Warning: message still undelivered after 4 hours Will keep trying until message is 5 days old So, you may have to check hamlib-developer instead ?? /Frank.. -- Frank Singleton VK3FCS Email: victor kilo three foxtrot charlie sierra at ix dot netcom dot com |