From a1c8493c62d309488e2f41f50850372bc41e6052 Mon Sep 17 00:00:00 2001 From: Mike Black W9MDB Date: Wed, 1 Dec 2021 11:50:33 -0600 Subject: [PATCH] First cut at clock setting for IC7300/7800/785x/9700 https://github.com/Hamlib/Hamlib/issues/851 --- NEWS | 4 +- cppcheck.sh | 2 +- doc/man1/rigctl.1 | 24 ++++++ doc/man1/rigctld.1 | 23 ++++++ include/hamlib/rig.h | 4 + rigs/dummy/dummy.c | 55 +++++++++++- rigs/icom/ic7300.c | 193 ++++++++++++++++++++++++++++++++++++++++++- rigs/icom/ic7300.h | 8 ++ rigs/icom/ic7800.c | 101 +++++++++++++++++++++- rigs/icom/ic785x.c | 5 +- src/rig.c | 36 ++++++++ tests/rigctl_parse.c | 48 ++++++++++- 12 files changed, 495 insertions(+), 8 deletions(-) create mode 100644 rigs/icom/ic7300.h diff --git a/NEWS b/NEWS index 595ce892f..a272440a7 100644 --- a/NEWS +++ b/NEWS @@ -7,13 +7,15 @@ Copyright (C) 2000-2021 Michael Black W9MDB, and others Please send Hamlib bug reports to hamlib-developer@lists.sourceforge.net Version 4.4 - * 2021-??-?? + * 2021-12-01 * Icom rigs now default filter 2 when setting PKTUSB but user can override * Fix FTDX9000 meter readings * Add Android sensor as a rotator * Added rig_get_vfo to some Icom rigs that have XCHG or 0x25 command capability * Added ability to build hamlib with docker * Added M0NKA mcHF URP rig + * Faster serial i/o noticeable on higher baud rates + * IC7300 set_clock/get_clock routines added -- no auto set yet Version 4.3.1 * 2021-09-14 diff --git a/cppcheck.sh b/cppcheck.sh index d71b45ba9..8389b07c2 100755 --- a/cppcheck.sh +++ b/cppcheck.sh @@ -80,7 +80,7 @@ CHECK="\ if test $# -eq 0 ; then echo "See cppcheck.log when done" echo "This takes a while to run" - cppcheck --inline-suppr \ + strace -f cppcheck --inline-suppr \ -I src \ -I include \ --include=include/config.h \ diff --git a/doc/man1/rigctl.1 b/doc/man1/rigctl.1 index 71f0a8222..7d3e7dea0 100644 --- a/doc/man1/rigctl.1 +++ b/doc/man1/rigctl.1 @@ -1136,6 +1136,30 @@ option above, will terminate each command string sent to the radio. This character should not be a part of the input string. . .TP +.BR set_clock " \(aq" \fIDateTime\fP \(aq +Set +.RI \(aq DateTime \(aq +.IP +Sets rig clock -- note that some rigs do not handle seconds or milliseconds. +If you try to set sec/msec and rig does not support it you will get a debug warning message. +Format is ISO8601, +.EX +Formats accepted +YYYY-MM-DDTHH:MM:SS.SSS+ZZ (where +ZZ is either -/+ UTC offset) +YYYY-MM-DDTHH:MM:SS+ZZ +YYYY-MM-DDTHH:MM+ZZ +YYYY-MM-DD (sets date only) +.EE +. +.TP +.BR get_clock +Get +.RI \(aq RigTime \(aq +.IP +Gets rig clock -- note that some rigs do not handle seconds or milliseconds. +Format is ISO8601 YYYY-MM-DDTHH:MM:SS.sss+ZZ where +ZZ is either -/+ UTC offset +. +.TP .BR chk_vfo Get .RI \(aq Status \(aq diff --git a/doc/man1/rigctld.1 b/doc/man1/rigctld.1 index 09ba8c020..e5d4fcd94 100644 --- a/doc/man1/rigctld.1 +++ b/doc/man1/rigctld.1 @@ -1077,6 +1077,29 @@ and also need to be provided as output power may vary according to these values. .IP VFO parameter is not used in VFO mode. +.TP +.BR set_clock " \(aq" \fIDateTime\fP \(aq +Set +.RI \(aq DateTime \(aq +.IP +Sets rig clock -- note that some rigs do not handle seconds or milliseconds. +If you try to set that you will get a debug warning message. +Format is ISO8601. +.EX +Formats accepted +YYYY-MM-DDTHH:MM:SS.sss+ZZ (where +ZZ is either -/+ UTC offset) +YYYY-MM-DDTHH:MM:SS+ZZ +YYYY-MM-DDTHH:MM+ZZ +YYYY-MM-DD (sets date only) +.EE +. +.TP +.BR get_clock +Get +.RI \(aq RigTime \(aq +.IP +Gets rig clock -- note that some rigs do not handle seconds or milliseconds. +Format is ISO8601 YYYY-MM-DDTHH:MM:SS.sss+ZZ where +ZZ is either -/+ UTC offset . .TP .B chk_vfo diff --git a/include/hamlib/rig.h b/include/hamlib/rig.h index b041a4305..ddc05cb3c 100644 --- a/include/hamlib/rig.h +++ b/include/hamlib/rig.h @@ -1980,6 +1980,8 @@ struct rig_caps { rmode_t *mode, pbwidth_t *width, split_t *split); + int(*set_clock) (RIG *rig, int year, int month, int day, int hour, int min, int sec, double msec, int utc_offset); + int(*get_clock) (RIG *rig, int *year, int *month, int *day, int *hour, int *min, int *sec, double *msec, int *utc_offset); const char *clone_combo_set; /*!< String describing key combination to enter load cloning mode */ const char *clone_combo_get; /*!< String describing key combination to enter save cloning mode */ @@ -3175,6 +3177,8 @@ extern HAMLIB_EXPORT(int) rig_get_vfo_info(RIG *rig, vfo_t vfo, freq_t *freq, rm extern HAMLIB_EXPORT(int) rig_get_rig_info(RIG *rig, char *response, int max_response_len); extern HAMLIB_EXPORT(int) rig_get_cache(RIG *rig, vfo_t vfo, freq_t *freq, int * cache_ms_freq, rmode_t *mode, int *cache_ms_mode, pbwidth_t *width, int *cache_ms_width); +extern HAMLIB_EXPORT(int) rig_set_clock(RIG *rig, int year, int month, int day, int hour, int min, int sec, double msec, int utc_offset); +extern HAMLIB_EXPORT(int) rig_get_clock(RIG *rig, int *year, int *month, int *day, int *hour, int *min, int *sec, double *msec, int *utc_offset); typedef unsigned long rig_useconds_t; extern HAMLIB_EXPORT(int) hl_usleep(rig_useconds_t msec); diff --git a/rigs/dummy/dummy.c b/rigs/dummy/dummy.c index 9c5c8faee..df01574d7 100644 --- a/rigs/dummy/dummy.c +++ b/rigs/dummy/dummy.c @@ -2140,6 +2140,55 @@ static int dummy_mW2power(RIG *rig, float *power, unsigned int mwpower, RETURNFUNC(RIG_OK); } +static int m_year, m_month, m_day, m_hour, m_min, m_sec, m_utc_offset; +static double m_msec; + +int dummy_set_clock(RIG *rig, int year, int month, int day, int hour, int min, + int sec, double msec, int utc_offset) +{ + int retval = RIG_OK; + + rig_debug(RIG_DEBUG_VERBOSE, "%s: %04d-%02d-%02dT%02d:%02d:%02d.%.03f%s%02d\n", + __func__, year, + month, day, hour, min, sec, msec, utc_offset >= 0 ? "+" : "-", + (unsigned)(abs(utc_offset))); + m_year = year; + m_month = month; + m_day = day; + + if (hour >= 0) + { + m_hour = hour; + m_min = min; + m_sec = sec; + m_msec = msec; + m_utc_offset = utc_offset; + } + + return retval; +} + +int dummy_get_clock(RIG *rig, int *year, int *month, int *day, int *hour, + int *min, int *sec, double *msec, int *utc_offset) +{ + int retval = RIG_OK; + + *year = m_year; + *month = m_month; + *day = m_day; + *hour = m_hour; + *min = m_min; + *sec = m_sec; + *msec = m_msec; + *utc_offset = m_utc_offset; + + rig_debug(RIG_DEBUG_VERBOSE, + "%s: %02d-%02d-%02dT%02d:%02d:%02d:%0.3lf%s%02d\n'", + __func__, *year, *month, *day, *hour, *min, *sec, *msec, + *utc_offset >= 0 ? "+" : "-", (unsigned)abs(*utc_offset)); + return retval; +} + /* * Dummy rig capabilities. @@ -2195,7 +2244,7 @@ struct rig_caps dummy_caps = RIG_MODEL(RIG_MODEL_DUMMY), .model_name = "Dummy", .mfg_name = "Hamlib", - .version = "20210705.0", + .version = "20211130.0", .copyright = "LGPL", .status = RIG_STATUS_STABLE, .rig_type = RIG_TYPE_OTHER, @@ -2415,6 +2464,8 @@ struct rig_caps dummy_caps = .get_trn = dummy_get_trn, .power2mW = dummy_power2mW, .mW2power = dummy_mW2power, + .set_clock = dummy_set_clock, + .get_clock = dummy_get_clock }; struct rig_caps dummy_no_vfo_caps = @@ -2580,6 +2631,8 @@ struct rig_caps dummy_no_vfo_caps = .get_trn = dummy_get_trn, .power2mW = dummy_power2mW, .mW2power = dummy_mW2power, + .set_clock = dummy_set_clock, + .get_clock = dummy_get_clock }; DECLARE_INITRIG_BACKEND(dummy) diff --git a/rigs/icom/ic7300.c b/rigs/icom/ic7300.c index d2c6b79e7..9b3af86a7 100644 --- a/rigs/icom/ic7300.c +++ b/rigs/icom/ic7300.c @@ -35,9 +35,16 @@ #include "frame.h" #include "bandplan.h" #include "tones.h" +#include "misc.h" +#include "ic7300.h" static int ic7300_set_parm(RIG *rig, setting_t parm, value_t val); static int ic7300_get_parm(RIG *rig, setting_t parm, value_t *val); +int ic7300_set_clock(RIG *rig, int year, int month, int day, int hour, + int min, int sec, double msec, int utc_offset); +int ic7300_get_clock(RIG *rig, int *year, int *month, int *day, + int *hour, + int *min, int *sec, double *msec, int *utc_offset); #define IC7300_ALL_RX_MODES (RIG_MODE_FM|RIG_MODE_AM|RIG_MODE_CW|RIG_MODE_CWR|RIG_MODE_SSB|RIG_MODE_RTTY|RIG_MODE_RTTYR|RIG_MODE_PKTLSB|RIG_MODE_PKTUSB|RIG_MODE_PKTFM|RIG_MODE_PKTAM) @@ -754,7 +761,9 @@ const struct rig_caps ic7300_caps = .send_morse = icom_send_morse, .stop_morse = icom_stop_morse, .wait_morse = rig_wait_morse, - .send_voice_mem = icom_send_voice_mem + .send_voice_mem = icom_send_voice_mem, + .set_clock = ic7300_set_clock, + .get_clock = ic7300_get_clock }; const struct rig_caps ic9700_caps = @@ -1458,3 +1467,185 @@ int ic7300_get_parm(RIG *rig, setting_t parm, value_t *val) return RIG_OK; } + +// if hour < 0 then only date will be set +int ic7300_set_clock(RIG *rig, int year, int month, int day, int hour, int min, + int sec, double msec, int utc_offset) +{ + int cmd = 0x1a; + int subcmd = 0x05; + int retval = RIG_OK; + unsigned char prmbuf[MAXFRAMELEN]; + + if (year >= 0) + { + prmbuf[0] = 0x00; + prmbuf[1] = 0x94; + prmbuf[2] = year / 100; + prmbuf[3] = year % 100; + prmbuf[4] = month; + prmbuf[5] = day; + retval = icom_transaction(rig, cmd, subcmd, prmbuf, 6, NULL, NULL); + + if (retval != RIG_OK) + { + rig_debug(RIG_DEBUG_ERR, "%s(%d): %s\b", __func__, __LINE__, rigerror(retval)); + } + } + + if (hour >= 0) + { + prmbuf[0] = 0x00; + prmbuf[1] = 0x95; + prmbuf[2] = hour; + prmbuf[3] = min; + retval = icom_transaction(rig, cmd, subcmd, prmbuf, 4, NULL, NULL); + + if (retval != RIG_OK) + { + rig_debug(RIG_DEBUG_ERR, "%s(%d): %s\b", __func__, __LINE__, rigerror(retval)); + } + + prmbuf[0] = 0x00; + prmbuf[1] = 0x96; + prmbuf[2] = utc_offset / 100; + prmbuf[3] = utc_offset % 100; + prmbuf[4] = utc_offset >= 0 ? 0 : 1; + retval = icom_transaction(rig, cmd, subcmd, prmbuf, 5, NULL, NULL); + + if (retval != RIG_OK) + { + rig_debug(RIG_DEBUG_ERR, "%s(%d): %s\b", __func__, __LINE__, rigerror(retval)); + } + } + + return retval; +} + +int ic7300_get_clock(RIG *rig, int *year, int *month, int *day, int *hour, + int *min, int *sec, double *msec, int *utc_offset) +{ + int cmd = 0x1a; + int subcmd = 0x05; + int retval = RIG_OK; + int resplen; + unsigned char prmbuf[MAXFRAMELEN]; + unsigned char respbuf[MAXFRAMELEN]; + + prmbuf[0] = 0x00; + prmbuf[1] = 0x94; + resplen = sizeof(respbuf); + retval = icom_transaction(rig, cmd, subcmd, prmbuf, 2, respbuf, &resplen); + dump_hex(respbuf, resplen); + *year = respbuf[4]; + *month = respbuf[5]; + *day = respbuf[6]; + + if (hour >= 0) // + { + prmbuf[0] = 0x00; + prmbuf[1] = 0x95; + retval = icom_transaction(rig, cmd, subcmd, prmbuf, 2, respbuf, &resplen); + dump_hex(respbuf, resplen); + rig_debug(RIG_DEBUG_VERBOSE, "%s: %02d-%02d-%02dT%02d:%02d:%02d:%0.3lf\n'", + __func__, *year, *month, *day, *hour, *min, *sec, *msec); + } + + return retval; +} + +// if hour < 0 then only date will be set +int ic9700_set_clock(RIG *rig, int year, int month, int day, int hour, int min, + int sec, double msec, int utc_offset) +{ + int cmd = 0x1a; + int subcmd = 0x05; + int retval = RIG_OK; + unsigned char prmbuf[MAXFRAMELEN]; + + if (year >= 0) + { + prmbuf[0] = 0x00; + prmbuf[1] = 0x94; + prmbuf[2] = year / 100; + prmbuf[3] = year % 100; + prmbuf[4] = month; + prmbuf[5] = day; + retval = icom_transaction(rig, cmd, subcmd, prmbuf, 6, NULL, NULL); + + if (retval != RIG_OK) + { + rig_debug(RIG_DEBUG_ERR, "%s(%d): %s\b", __func__, __LINE__, rigerror(retval)); + } + } + + if (hour >= 0) + { + prmbuf[0] = 0x00; + prmbuf[1] = 0x95; + prmbuf[2] = hour; + prmbuf[3] = min; + retval = icom_transaction(rig, cmd, subcmd, prmbuf, 4, NULL, NULL); + + if (retval != RIG_OK) + { + rig_debug(RIG_DEBUG_ERR, "%s(%d): %s\b", __func__, __LINE__, rigerror(retval)); + } + + prmbuf[0] = 0x00; + prmbuf[1] = 0x96; + prmbuf[2] = utc_offset / 100; + prmbuf[3] = utc_offset % 100; + prmbuf[4] = utc_offset >= 0 ? 0 : 1; + retval = icom_transaction(rig, cmd, subcmd, prmbuf, 5, NULL, NULL); + + if (retval != RIG_OK) + { + rig_debug(RIG_DEBUG_ERR, "%s(%d): %s\b", __func__, __LINE__, rigerror(retval)); + } + } + + return retval; +} + +int ic9700_get_clock(RIG *rig, int *year, int *month, int *day, int *hour, + int *min, int *sec, double *msec, int *utc_offset) +{ + int cmd = 0x1a; + int subcmd = 0x05; + int retval = RIG_OK; + int resplen; + unsigned char prmbuf[MAXFRAMELEN]; + unsigned char respbuf[MAXFRAMELEN]; + + prmbuf[0] = 0x01; + prmbuf[1] = 0x79; + resplen = sizeof(respbuf); + retval = icom_transaction(rig, cmd, subcmd, prmbuf, 2, respbuf, &resplen); + dump_hex(respbuf, resplen); + *year = respbuf[4]; + *month = respbuf[5]; + *day = respbuf[6]; + + if (hour != NULL) + { + prmbuf[0] = 0x01; + prmbuf[1] = 0x80; + retval = icom_transaction(rig, cmd, subcmd, prmbuf, 2, respbuf, &resplen); + dump_hex(respbuf, resplen); + *hour = respbuf[4]; + *min = respbuf[5]; + *sec = respbuf[6]; + *msec = 0; + rig_debug(RIG_DEBUG_VERBOSE, "%s: %02d-%02d-%02dT%02d:%02d:%02d:%0.3lf\n'", + __func__, *year, *month, *day, *hour, *min, *sec, *msec); + prmbuf[0] = 0x01; + prmbuf[1] = 0x81; + retval = icom_transaction(rig, cmd, subcmd, prmbuf, 2, respbuf, &resplen); + dump_hex(respbuf, resplen); + *utc_offset = respbuf[4]; + if (respbuf[5] > 0) *utc_offset = *utc_offset*100 + respbuf[5]; + } + + return retval; +} diff --git a/rigs/icom/ic7300.h b/rigs/icom/ic7300.h new file mode 100644 index 000000000..a1973a011 --- /dev/null +++ b/rigs/icom/ic7300.h @@ -0,0 +1,8 @@ +#include "frame.h" +#include "misc.h" +extern int ic7300_set_clock(RIG *rig, int year, int month, int day, int hour, + int min, int sec, double msec, int utc_offset); +extern int ic7300_get_clock(RIG *rig, int *year, int *month, int *day, + int *hour, + int *min, int *sec, double *msec, int *utc_offset); + diff --git a/rigs/icom/ic7800.c b/rigs/icom/ic7800.c index 8bb138292..31d8a183e 100644 --- a/rigs/icom/ic7800.c +++ b/rigs/icom/ic7800.c @@ -32,6 +32,7 @@ #include "icom.h" #include "icom_defs.h" #include "bandplan.h" +#include "ic7300.h" #define IC7800_ALL_RX_MODES (RIG_MODE_AM|RIG_MODE_CW|RIG_MODE_CWR|RIG_MODE_SSB|RIG_MODE_RTTY|RIG_MODE_RTTYR|RIG_MODE_FM|RIG_MODE_PSK|RIG_MODE_PSKR|RIG_MODE_PKTLSB|RIG_MODE_PKTUSB|RIG_MODE_PKTAM|RIG_MODE_PKTFM) #define IC7800_1HZ_TS_MODES IC7800_ALL_RX_MODES @@ -154,7 +155,7 @@ const struct rig_caps ic7800_caps = RIG_MODEL(RIG_MODEL_IC7800), .model_name = "IC-7800", .mfg_name = "Icom", - .version = BACKEND_VER ".3", + .version = BACKEND_VER ".4", .copyright = "LGPL", .status = RIG_STATUS_STABLE, .rig_type = RIG_TYPE_TRANSCEIVER, @@ -328,7 +329,9 @@ const struct rig_caps ic7800_caps = .get_powerstat = icom_get_powerstat, .send_morse = icom_send_morse, .stop_morse = icom_stop_morse, - .wait_morse = rig_wait_morse + .wait_morse = rig_wait_morse, + .set_clock = ic7300_set_clock, + .get_clock = ic7300_get_clock, }; /* @@ -402,3 +405,97 @@ int ic7800_get_level(RIG *rig, vfo_t vfo, setting_t level, value_t *val) return RIG_OK; } + +// if hour < 0 then only date will be set +int ic7800_set_clock(RIG *rig, int year, int month, int day, int hour, int min, + int sec, double msec, int utc_offset) +{ + int cmd = 0x1a; + int subcmd = 0x05; + int retval = RIG_OK; + unsigned char prmbuf[MAXFRAMELEN]; + + if (year >= 0) + { + prmbuf[0] = 0x01; + prmbuf[1] = 0x20; + prmbuf[2] = year / 100; + prmbuf[3] = year % 100; + prmbuf[4] = month; + prmbuf[5] = day; + retval = icom_transaction(rig, cmd, subcmd, prmbuf, 6, NULL, NULL); + + if (retval != RIG_OK) + { + rig_debug(RIG_DEBUG_ERR, "%s(%d): %s\b", __func__, __LINE__, rigerror(retval)); + } + } + + if (hour >= 0) + { + prmbuf[0] = 0x01; + prmbuf[1] = 0x21; + prmbuf[2] = hour; + prmbuf[3] = min; + retval = icom_transaction(rig, cmd, subcmd, prmbuf, 4, NULL, NULL); + + if (retval != RIG_OK) + { + rig_debug(RIG_DEBUG_ERR, "%s(%d): %s\b", __func__, __LINE__, rigerror(retval)); + } + + prmbuf[0] = 0x01; + prmbuf[1] = 0x23; + prmbuf[2] = utc_offset / 100; + prmbuf[3] = utc_offset % 100; + prmbuf[4] = utc_offset >= 0 ? 0 : 1; + retval = icom_transaction(rig, cmd, subcmd, prmbuf, 5, NULL, NULL); + + if (retval != RIG_OK) + { + rig_debug(RIG_DEBUG_ERR, "%s(%d): %s\b", __func__, __LINE__, rigerror(retval)); + } + } + + return retval; +} + + +int ic7800_get_clock(RIG *rig, int *year, int *month, int *day, int *hour, + int *min, int *sec, double *msec, int *utc_offset) +{ + int cmd = 0x1a; + int subcmd = 0x05; + int retval = RIG_OK; + int resplen; + unsigned char prmbuf[MAXFRAMELEN]; + unsigned char respbuf[MAXFRAMELEN]; + + prmbuf[0] = 0x00; + prmbuf[1] = 0x94; + resplen = sizeof(respbuf); + retval = icom_transaction(rig, cmd, subcmd, prmbuf, 2, respbuf, &resplen); + dump_hex(respbuf, resplen); + *year = respbuf[4]; + *month = respbuf[5]; + *day = respbuf[6]; + + if (hour >= 0) // + { + prmbuf[0] = 0x00; + prmbuf[1] = 0x95; + retval = icom_transaction(rig, cmd, subcmd, prmbuf, 2, respbuf, &resplen); + dump_hex(respbuf, resplen); + rig_debug(RIG_DEBUG_VERBOSE, "%s: %02d-%02d-%02dT%02d:%02d:%02d:%0.3lf\n'", + __func__, *year, *month, *day, *hour, *min, *sec, *msec); + prmbuf[0] = 0x01; + prmbuf[1] = 0x81; + retval = icom_transaction(rig, cmd, subcmd, prmbuf, 2, respbuf, &resplen); + dump_hex(respbuf, resplen); + *utc_offset = respbuf[4]; + if (respbuf[5] > 0) *utc_offset = *utc_offset*100 + respbuf[5]; + } + + return retval; +} + diff --git a/rigs/icom/ic785x.c b/rigs/icom/ic785x.c index 5fe2afcf8..0d0c5304a 100644 --- a/rigs/icom/ic785x.c +++ b/rigs/icom/ic785x.c @@ -33,6 +33,7 @@ #include "icom.h" #include "icom_defs.h" #include "bandplan.h" +#include "ic7300.h" #define IC785x_ALL_RX_MODES (RIG_MODE_AM|RIG_MODE_CW|RIG_MODE_CWR|RIG_MODE_SSB|RIG_MODE_RTTY|RIG_MODE_RTTYR|RIG_MODE_FM|RIG_MODE_PSK|RIG_MODE_PSKR|RIG_MODE_PKTLSB|RIG_MODE_PKTUSB|RIG_MODE_PKTAM|RIG_MODE_PKTFM) #define IC785x_1HZ_TS_MODES IC785x_ALL_RX_MODES @@ -472,7 +473,9 @@ const struct rig_caps ic785x_caps = .get_powerstat = icom_get_powerstat, .send_morse = icom_send_morse, .stop_morse = icom_stop_morse, - .wait_morse = rig_wait_morse + .wait_morse = rig_wait_morse, + .set_clock = ic7300_set_clock, + .get_clock = ic7300_get_clock }; int ic785x_set_level(RIG *rig, vfo_t vfo, setting_t level, value_t val) diff --git a/src/rig.c b/src/rig.c index 6f1870cd1..3a66c15a9 100644 --- a/src/rig.c +++ b/src/rig.c @@ -6994,6 +6994,42 @@ int HAMLIB_API rig_get_vfo_list(RIG *rig, char *buf, int buflen) RETURNFUNC(RIG_OK); } +/** + * \brief set the rig's clock + * + */ +int HAMLIB_API rig_set_clock(RIG *rig, int year, int month, int day, int hour, + int min, int sec, double msec, int utc_offset) +{ + if (rig->caps->set_clock == NULL) + { + return -RIG_ENIMPL; + } + + RETURNFUNC(rig->caps->set_clock(rig, year, month, day, hour, min, sec, + msec, utc_offset)); +} + +/** + * \brief get the rig's clock + * + */ +int HAMLIB_API rig_get_clock(RIG *rig, int *year, int *month, int *day, + int *hour, + int *min, int *sec, double *msec, int *utc_offset) +{ + int retval; + + if (rig->caps->get_clock == NULL) + { + return -RIG_ENIMPL; + } + + retval = rig->caps->get_clock(rig, year, month, day, hour, min, sec, + msec, utc_offset); + RETURNFUNC(retval); +} + /** * \brief get the Hamlib license * diff --git a/tests/rigctl_parse.c b/tests/rigctl_parse.c index 014e2ec49..f0393f19d 100644 --- a/tests/rigctl_parse.c +++ b/tests/rigctl_parse.c @@ -244,6 +244,8 @@ declare_proto_rig(halt); declare_proto_rig(pause); declare_proto_rig(password); declare_proto_rig(set_password); +declare_proto_rig(set_clock); +declare_proto_rig(get_clock); /* @@ -344,11 +346,13 @@ static struct test_table test_list[] = { 0xf5, "get_rig_info", ACTION(get_rig_info), ARG_NOVFO | ARG_OUT, "RigInfo" }, /* get several vfo parameters at once */ { 0xf4, "get_vfo_list", ACTION(get_vfo_list), ARG_OUT | ARG_NOVFO, "VFOs" }, { 0xf6, "get_modes", ACTION(get_modes), ARG_OUT | ARG_NOVFO, "Modes" }, - { 0xf7, "get_mode_bandwidths", ACTION(get_mode_bandwidths), ARG_IN | ARG_NOVFO, "Mode" }, + { 0xf9, "get_clock", ACTION(get_clock), ARG_IN | ARG_NOVFO, "local/utc" }, + { 0xf8, "set_clock", ACTION(set_clock), ARG_IN | ARG_NOVFO, "YYYYMMDDHHMMSS.sss+ZZ" }, { 0xf1, "halt", ACTION(halt), ARG_NOVFO }, /* rigctld only--halt the daemon */ { 0x8c, "pause", ACTION(pause), ARG_IN, "Seconds" }, { 0x98, "password", ACTION(password), ARG_IN, "Password" }, { 0x99, "set_password", ACTION(set_password), ARG_IN, "Password" }, + { 0xf7, "get_mode_bandwidths", ACTION(get_mode_bandwidths), ARG_IN | ARG_NOVFO, "Mode" }, { 0x00, "", NULL }, }; @@ -5206,3 +5210,45 @@ declare_proto_rig(get_cache) RETURNFUNC(RIG_OK); } + +/* '0xf8' */ +declare_proto_rig(set_clock) +{ + int year, mon, day, hour = -1, min = -1, sec = -1; + double msec; + int utc_offset = 0; + int n; + + ENTERFUNC; + + n = sscanf(arg1, "%04d-%02d-%02dT%02d:%02d:%02d%lf%d", &year, &mon, &day, &hour, + &min, &sec, &msec, &utc_offset); + rig_debug(RIG_DEBUG_VERBOSE, + "%s: n=%d, %04d-%02d-%02dT%02d:%02d:%02d.%0.3f%s%02d\n", + __func__, n, year, mon, day, hour, min, sec, msec, utc_offset >= 0 ? "+" : "-", + (unsigned)abs(utc_offset)); + + RETURNFUNC(rig_set_clock(rig, year, mon, day, hour, min, sec, msec, + utc_offset)); +} + +/* '0xf9' */ +declare_proto_rig(get_clock) +{ + char option[64]; + int year, month, day, hour, min, sec, utc_offset; + int retval; + double msec; + + ENTERFUNC; + + CHKSCN1ARG(sscanf(arg1, "%63s", option)); + + retval = rig_get_clock(rig, &year, &month, &day, &hour, &min, &sec, &msec, + &utc_offset); + + fprintf(fout, "%04d-%02d-%02dT%02d:%02d:%02d.%0.3f%s%02d\n", year, month, day, + hour, min, sec, msec, utc_offset >= 0 ? "+" : "-", (unsigned)abs(utc_offset)); + + return retval; +}