From 676c39a9d0d42385d04285474d3a4f24d32ac4b7 Mon Sep 17 00:00:00 2001 From: George Baltz N3GB Date: Wed, 4 Sep 2024 17:25:39 -0400 Subject: [PATCH 1/5] Declare local functions as local --- rigs/kenwood/ts890s.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/rigs/kenwood/ts890s.c b/rigs/kenwood/ts890s.c index a4dbd6182..c8b5d9291 100644 --- a/rigs/kenwood/ts890s.c +++ b/rigs/kenwood/ts890s.c @@ -41,7 +41,7 @@ #define TS890_VFO_OPS (RIG_OP_UP|RIG_OP_DOWN|RIG_OP_BAND_UP|RIG_OP_BAND_DOWN|RIG_OP_CPY|RIG_OP_TUNE) -int kenwood_ts890_set_level(RIG *rig, vfo_t vfo, setting_t level, value_t val) +static int kenwood_ts890_set_level(RIG *rig, vfo_t vfo, setting_t level, value_t val) { char levelbuf[16], *command_string; int kenwood_val, retval; @@ -109,7 +109,7 @@ int kenwood_ts890_set_level(RIG *rig, vfo_t vfo, setting_t level, value_t val) return kenwood_transaction(rig, levelbuf, NULL, 0); } -int kenwood_ts890_get_level(RIG *rig, vfo_t vfo, setting_t level, value_t *val) +static int kenwood_ts890_get_level(RIG *rig, vfo_t vfo, setting_t level, value_t *val) { char ackbuf[50]; size_t ack_len, ack_len_expected, len; @@ -403,7 +403,7 @@ int kenwood_ts890_get_level(RIG *rig, vfo_t vfo, setting_t level, value_t *val) return -RIG_EINTERNAL; } -int ts890_set_func(RIG *rig, vfo_t vfo, setting_t func, int status) +static int ts890_set_func(RIG *rig, vfo_t vfo, setting_t func, int status) { int mask, retval; char current[4]; @@ -434,7 +434,7 @@ int ts890_set_func(RIG *rig, vfo_t vfo, setting_t func, int status) return kenwood_transaction(rig, current, NULL, 0); } -int ts890_get_func(RIG *rig, vfo_t vfo, setting_t func, int *status) +static int ts890_get_func(RIG *rig, vfo_t vfo, setting_t func, int *status) { int mask, retval; char current[4]; From 99535c06822b7b66885e164d327c273fb14fc42a Mon Sep 17 00:00:00 2001 From: George Baltz N3GB Date: Fri, 6 Sep 2024 04:20:42 -0400 Subject: [PATCH 2/5] Implement rig_get_clock for TS-890S Should also work for TS-990S, but no H/W to test Plus stub for set_clock. --- rigs/kenwood/kenwood.c | 59 ++++++++++++++++++++++++++++++++++++++++++ rigs/kenwood/kenwood.h | 2 ++ rigs/kenwood/ts890s.c | 2 ++ rigs/kenwood/ts990s.c | 4 ++- 4 files changed, 66 insertions(+), 1 deletion(-) diff --git a/rigs/kenwood/kenwood.c b/rigs/kenwood/kenwood.c index 0db3466ac..d2edaca8a 100644 --- a/rigs/kenwood/kenwood.c +++ b/rigs/kenwood/kenwood.c @@ -6006,6 +6006,65 @@ int kenwood_set_ext_parm(RIG *rig, hamlib_token_t token, value_t val) RETURNFUNC(-RIG_EINVAL); } +/* + * kenwood_set_clock + */ +int kenwood_set_clock(RIG *rig, int year, int month, int day, int hour, int min, int sec, double msec, int utc_offset) +{ + return -RIG_ENIMPL; +} + +/* + * kenwood_get_clock + */ +int kenwood_get_clock(RIG *rig, int *year, int *month, int *day, int *hour, int *min, int *sec, double *msec, int *utc_offset) +{ + int retval; + int fields, zone; + char ans[20]; + + // Make sure the clock has been set at least once + retval = kenwood_transaction(rig, "CK1", ans, sizeof(ans)); + if (retval != RIG_OK) {return retval;} + + if (ans[3] != '1') + { + return -RIG_ENAVAIL; + } + + // Get the local clock + retval = kenwood_transaction(rig, "CK0", ans, sizeof(ans)); + if (retval != RIG_OK) {return retval;} + + fields = sscanf(ans, "CK0%2d%2d%2d%2d%2d%2d", year, month, day, hour, min, sec); + + // TS-890S doesn't define what P6 is, but it sure looks like seconds to me. + // TS-990S doesn't have a P6, so set it to 0 + if (fields < 6) + { + *sec = 0; + } + // Add the century + if (*year <= 20) //TODO: Update this every decade or so + { + *year += 100; + } + *year += 2000; //TODO: Update this every century or so + + // Now figure out the time zone + retval = kenwood_transaction(rig, "CK2", ans, sizeof(ans)); + if (retval != RIG_OK) {return retval;} + + zone = atoi(&ans[3]); // UTC offset in 15 minute intervals, centered on 56 + zone = (zone / 4) * 100 + (zone % 4) * 15; // Pack as hours * 100 + minutes + *utc_offset = zone - 1400; + + // No msec available + *msec = 0; + + return RIG_OK; +} + int kenwood_get_ext_parm(RIG *rig, hamlib_token_t token, value_t *val) { int err; diff --git a/rigs/kenwood/kenwood.h b/rigs/kenwood/kenwood.h index 54082c091..3d39d0480 100644 --- a/rigs/kenwood/kenwood.h +++ b/rigs/kenwood/kenwood.h @@ -264,6 +264,8 @@ int kenwood_get_id(RIG *rig, char *buf); int kenwood_get_if(RIG *rig); int kenwood_send_voice_mem(RIG *rig, vfo_t vfo, int bank); int kenwood_stop_voice_mem(RIG *rig, vfo_t vfo); +int kenwood_get_clock(RIG *rig, int *year, int *month, int *day, int *hour, int *min, int *sec, double *msec, int *utc_offset); +int kenwood_set_clock(RIG *rig, int year, int month, int day, int hour, int min, int sec, double msec, int utc_offset); int kenwood_set_trn(RIG *rig, int trn); int kenwood_get_trn(RIG *rig, int *trn); diff --git a/rigs/kenwood/ts890s.c b/rigs/kenwood/ts890s.c index c8b5d9291..fca6846c1 100644 --- a/rigs/kenwood/ts890s.c +++ b/rigs/kenwood/ts890s.c @@ -661,5 +661,7 @@ struct rig_caps ts890s_caps = .has_set_func = TS890_FUNC_ALL, .set_func = ts890_set_func, .get_func = ts890_get_func, + .get_clock = kenwood_get_clock, + .set_clock = kenwood_set_clock, .hamlib_check_rig_caps = HAMLIB_CHECK_RIG_CAPS }; diff --git a/rigs/kenwood/ts990s.c b/rigs/kenwood/ts990s.c index 2785d981e..b8d58fff9 100644 --- a/rigs/kenwood/ts990s.c +++ b/rigs/kenwood/ts990s.c @@ -373,6 +373,8 @@ struct rig_caps ts990s_caps = .set_powerstat = kenwood_set_powerstat, .get_powerstat = kenwood_get_powerstat, .reset = kenwood_reset, + .get_clock = kenwood_get_clock, + .set_clock = kenwood_set_clock, .hamlib_check_rig_caps = HAMLIB_CHECK_RIG_CAPS }; @@ -381,7 +383,7 @@ struct rig_caps ts990s_caps = */ /* - * ts2000_get_level + * ts990s_get_level * Assumes rig!=NULL, val!=NULL */ From b667e31dcf56fd6a65512eb88e59ef55437c8577 Mon Sep 17 00:00:00 2001 From: George Baltz N3GB Date: Tue, 10 Sep 2024 03:33:43 -0400 Subject: [PATCH 3/5] Fix wrong utc_offset Only compare magnitude when checking for only hours given. Offsets west of UTC could be off by a factor of 100. --- tests/rigctl_parse.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/rigctl_parse.c b/tests/rigctl_parse.c index 09f49dc20..c4ea871c7 100644 --- a/tests/rigctl_parse.c +++ b/tests/rigctl_parse.c @@ -5657,7 +5657,7 @@ declare_proto_rig(set_clock) __func__, n, year, mon, day, hour, min, sec, msec, utc_offset >= 0 ? "+" : "-", (unsigned)abs(utc_offset)); - if (utc_offset < 24) { utc_offset *= 100; } // allow for minutes offset too + if (abs(utc_offset) < 24) { utc_offset *= 100; } // allow for minutes offset too rig_debug(RIG_DEBUG_VERBOSE, "%s: utc_offset=%d\n", __func__, utc_offset); From 5f6554c797cb57d8053f47d4f72a27a570436ead Mon Sep 17 00:00:00 2001 From: George Baltz N3GB Date: Tue, 10 Sep 2024 04:54:57 -0400 Subject: [PATCH 4/5] Use a reliable source for TZ offset Both the POSIX and Linux man pages for localtime_r() state that localtime_r need not set the global variable timezone. I found that '\set_clock local' was using an offset of -0500 instead of -0400 (EDT). Change date_strget to use tm_gmtoff. --- src/misc.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/misc.c b/src/misc.c index 9ae1facad..c6a40809c 100644 --- a/src/misc.c +++ b/src/misc.c @@ -2834,7 +2834,7 @@ char *date_strget(char *buf, int buflen, int localtime) if (localtime) { mytm = localtime_r(&t, &result); - mytimezone = timezone; + mytimezone = - (int)result.tm_gmtoff; } else { From 1ff85278640c8f4da639ee2a8640abc1a9d7d386 Mon Sep 17 00:00:00 2001 From: George Baltz N3GB Date: Tue, 10 Sep 2024 17:11:30 -0400 Subject: [PATCH 5/5] Add just enough to simts890.c to fake kenwood_get_clock. Still needs a settable synthetic clock for kenwood_set_clock. Time zone offsets need to be tied to both clocks, and to strftime. When finished copy to simts990.c, dropping P6 from CK0. --- simulators/simts890.c | 82 ++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 81 insertions(+), 1 deletion(-) diff --git a/simulators/simts890.c b/simulators/simts890.c index 22c44c891..a91bd32d4 100644 --- a/simulators/simts890.c +++ b/simulators/simts890.c @@ -46,7 +46,8 @@ int ra=0; int rl=0; int is=0; int sp=0; - +int tzs[2] = {40, 56}; // 0=primary(EDT), 1=auxiiary(UTC) +char auxtzc = 'U'; // Auxiliary clock identifier (UTC) #if defined(WIN32) || defined(_WIN32) int openPort(char *comport) // doesn't matter for using pts devices @@ -629,6 +630,85 @@ int main(int argc, char *argv[]) { sscanf(buf,"SP%d", &sp); } + else if (strncmp(buf, "CK", 2) == 0) + { // All the clock functions + switch (buf[2]) { + case '0': // Get/Set Local clock + { + time_t t; + struct tm *localtm; + + if (buf[3] == ';') + { + t = time(NULL); + localtm = localtime(&t); + strftime(&buf[3], BUFSIZ - 3, "%y%m%d%H%M%S;", localtm); + write(fd, buf, strlen(buf)); + } + else + { + printf("Sorry, can't set time (yet)\n"); + } + break; + } + case '1': // Setting status + buf[3] = '1'; + buf[4] = ';'; + buf[5] = 0; + write(fd, buf, 6); + break; + case '2': // Local clock time zone + case '3': // Secondary clock time zone + { + int idx = buf[2] - '2'; + if (buf[3] == ';') + { + sprintf(&buf[3], "%3d;", tzs[idx]); + write(fd, buf, strlen(buf)); + } + else + { + sscanf(&buf[3], "%3d;", &tzs[idx]); + } + break; + } + case '4': // ID character for secondary clock + if (buf[3] == ';') + { + buf[3] = auxtzc; + buf[4] = ';'; + buf[5] = '\0'; + write(fd, buf, 6); + } + else + { + auxtzc = buf[3]; + } + break; + case '5': // Date format + break; + case '6': // Automatic date/time retrieval (NTP) + //For the time being, assume this is always on. + //TODO: Fix this when we can set the clock + if (buf[3] == ';') + { + buf[3] = 1; + buf[4] = ';'; + buf[5] = 0; + write(fd, buf, strlen(buf)); + } + else + { + printf("Can't run without NTP, sorry\n"); + } + break; + case '7': // NTP server address + case '8': // Force time update via NTP + case '9': // Clock display (primary/secondary/both) + default: + printf("Bad clock command - %s\n", buf); + } + } else if (strlen(buf) > 0) { fprintf(stderr, "Unknown command: %s\n", buf);