[Hamlib-commits] Hamlib -- Ham radio control libraries branch master updated. a6fb8a079a562014b9948
Library to control radio transceivers and receivers
Brought to you by:
n0nb
From: n0nb <n0...@us...> - 2025-06-30 12:38:02
|
This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "Hamlib -- Ham radio control libraries". The branch, master has been updated via a6fb8a079a562014b9948e16a2dd817346fcf4e2 (commit) via b95d349bff845a6cc936f838087fdce62aa7194d (commit) via 6797ab7646030b93ebffdcb57e8583928d106a5f (commit) via c2d4fbe601c7d6dce463d133634c2458e0489fd3 (commit) via a61877a60be23df45439cc607585ecfe55d46395 (commit) via 19c2cc03156846d22262536e9cde7f70deff26db (commit) via dee29c555f98413486dd7110b601aa403035970d (commit) via abf6be0b5e80b3d2376ac873ccf2602ad8e8199f (commit) via c9161e2e25d80609d5127ca0c1ebe8e78cb00040 (commit) from 862fda58be871ce33f9d946c30d61232dd41549c (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit a6fb8a079a562014b9948e16a2dd817346fcf4e2 Author: 声纳 <159...@qq...> Date: Mon Jun 30 08:43:04 2025 +0800 Update copyright to GUOHETEC in license headers for all GUOHETEC driver files diff --git a/rigs/guohetec/guohetec.c b/rigs/guohetec/guohetec.c index 16334e119..7df6cc346 100644 --- a/rigs/guohetec/guohetec.c +++ b/rigs/guohetec/guohetec.c @@ -1,6 +1,6 @@ /* * Hamlib GUOHETEC backend - common functions - * Copyright (c) 2024 by [Your Name] + * Copyright (c) 2024 by GUOHETEC * * * This library is free software; you can redistribute it and/or diff --git a/rigs/guohetec/guohetec.h b/rigs/guohetec/guohetec.h index 0e58b44e0..ca6c4b777 100644 --- a/rigs/guohetec/guohetec.h +++ b/rigs/guohetec/guohetec.h @@ -1,6 +1,6 @@ /* * Hamlib GUOHETEC backend - common header file - * Copyright (c) 2024 by [Your Name] + * Copyright (c) 2024 by GUOHETEC * * * This library is free software; you can redistribute it and/or diff --git a/rigs/guohetec/pmr171.c b/rigs/guohetec/pmr171.c index 9844fd8ad..9522fce58 100644 --- a/rigs/guohetec/pmr171.c +++ b/rigs/guohetec/pmr171.c @@ -1,6 +1,6 @@ /* * Hamlib GUOHETEC PMR-171 backend - main file - * Copyright (c) 2024 by [Your Name] + * Copyright (c) 2024 by GUOHETEC * * * This library is free software; you can redistribute it and/or diff --git a/rigs/guohetec/q900.c b/rigs/guohetec/q900.c index 943e25eb7..27e755d40 100644 --- a/rigs/guohetec/q900.c +++ b/rigs/guohetec/q900.c @@ -1,6 +1,6 @@ /* * Hamlib GUOHETEC Q900 backend - main file - * Copyright (c) 2024 by [Your Name] + * Copyright (c) 2024 by GUOHETEC * * * This library is free software; you can redistribute it and/or commit b95d349bff845a6cc936f838087fdce62aa7194d Author: 声纳 <159...@qq...> Date: Mon Jun 30 08:41:13 2025 +0800 Add LGPLv2.1 license headers to GUOHETEC driver files diff --git a/rigs/guohetec/guohetec.c b/rigs/guohetec/guohetec.c index d2d797c1c..16334e119 100644 --- a/rigs/guohetec/guohetec.c +++ b/rigs/guohetec/guohetec.c @@ -1,3 +1,24 @@ +/* + * Hamlib GUOHETEC backend - common functions + * Copyright (c) 2024 by [Your Name] + * + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + */ + #include <string.h> #include <hamlib/rig.h> #include "iofunc.h" diff --git a/rigs/guohetec/guohetec.h b/rigs/guohetec/guohetec.h index 06d944f54..0e58b44e0 100644 --- a/rigs/guohetec/guohetec.h +++ b/rigs/guohetec/guohetec.h @@ -1,3 +1,24 @@ +/* + * Hamlib GUOHETEC backend - common header file + * Copyright (c) 2024 by [Your Name] + * + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + */ + // rigs/guohetec/guohetec.h #ifndef _guohetec_H_ #define _guohetec_H_ diff --git a/rigs/guohetec/pmr171.c b/rigs/guohetec/pmr171.c index 38a5ada07..9844fd8ad 100644 --- a/rigs/guohetec/pmr171.c +++ b/rigs/guohetec/pmr171.c @@ -1,3 +1,24 @@ +/* + * Hamlib GUOHETEC PMR-171 backend - main file + * Copyright (c) 2024 by [Your Name] + * + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + */ + #include <stdlib.h> #include <string.h> /* String function definitions */ #include <stdbool.h> diff --git a/rigs/guohetec/q900.c b/rigs/guohetec/q900.c index 2e6d6bc0e..943e25eb7 100644 --- a/rigs/guohetec/q900.c +++ b/rigs/guohetec/q900.c @@ -1,3 +1,24 @@ +/* + * Hamlib GUOHETEC Q900 backend - main file + * Copyright (c) 2024 by [Your Name] + * + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + */ + #include <stdlib.h> #include <string.h> /* String function definitions */ #include <stdbool.h> commit 6797ab7646030b93ebffdcb57e8583928d106a5f Author: 声纳 <159...@qq...> Date: Sat Jun 28 17:13:12 2025 +0800 guohetec: fix cppcheck warnings and improve code quality Based on cppcheck analysis and maintainer feedback: - Fix constParameterPointer warnings: declare reply parameters as const where appropriate - Fix variableScope warnings: reduce reply variable scope to minimum required - Apply IWYU (IncludeWhatYouUse) suggestions for header optimization: * Add iofunc.h (for read_block, write_block functions) * Add riglist.h (for RIG_MODEL_* constants) * Remove unistd.h, misc.h, serial.h (unnecessary includes) - Maintain backward compatibility and existing functionality - Improve code maintainability and reduce compilation warnings All changes follow maintainer recommendations and maintain WSJT-X compatibility. diff --git a/rigs/guohetec/guohetec.c b/rigs/guohetec/guohetec.c index d5019c39a..d2d797c1c 100644 --- a/rigs/guohetec/guohetec.c +++ b/rigs/guohetec/guohetec.c @@ -189,7 +189,7 @@ int read_rig_response(RIG *rig, unsigned char *reply, int reply_size, * @param func_name Function name for debug messages * @return 0 on success, -1 on error */ -int validate_rig_response(RIG *rig, unsigned char *reply, int reply_size, +int validate_rig_response(RIG *rig, const unsigned char *reply, int reply_size, const char *func_name) { // Validate packet header @@ -213,7 +213,7 @@ int validate_rig_response(RIG *rig, unsigned char *reply, int reply_size, * @param func_name Function name for debug messages * @return 0 on success, -1 on error */ -int validate_freq_response(RIG *rig, unsigned char *reply, int reply_size, +int validate_freq_response(RIG *rig, const unsigned char *reply, int reply_size, const char *func_name) { // Basic validation @@ -257,7 +257,7 @@ int validate_freq_response(RIG *rig, unsigned char *reply, int reply_size, * @param min_length Minimum required data length * @return 0 on success, -1 on error */ -int validate_mode_response(RIG *rig, unsigned char *reply, int reply_size, +int validate_mode_response(RIG *rig, const unsigned char *reply, int reply_size, const char *func_name, int min_length) { // Basic validation @@ -305,8 +305,6 @@ DECLARE_PROBERIG_BACKEND(guohetec) { 0x0B, 0x00, 0x00 }; - - uint8_t reply[PMR171_REPLY_LENGTH]; int orig_rate = port->parm.serial.rate; int orig_timeout = port->timeout; @@ -314,6 +312,8 @@ DECLARE_PROBERIG_BACKEND(guohetec) { const int rates[] = {9600, 19200, 38400, 57600, 115200, 0}; for (int i = 0; rates[i]; i++) { + uint8_t reply[PMR171_REPLY_LENGTH]; + port->parm.serial.rate = rates[i]; port->timeout = 500; diff --git a/rigs/guohetec/guohetec.h b/rigs/guohetec/guohetec.h index 589e2e3f7..06d944f54 100644 --- a/rigs/guohetec/guohetec.h +++ b/rigs/guohetec/guohetec.h @@ -61,13 +61,13 @@ unsigned char *to_be(unsigned char data[], unsigned long long freq, unsigned int unsigned long long from_be(const unsigned char data[],unsigned int byte_len); // Common response validation functions -int validate_rig_response(RIG *rig, unsigned char *reply, int reply_size, +int validate_rig_response(RIG *rig, const unsigned char *reply, int reply_size, const char *func_name); int read_rig_response(RIG *rig, unsigned char *reply, int reply_size, const char *func_name); -int validate_freq_response(RIG *rig, unsigned char *reply, int reply_size, +int validate_freq_response(RIG *rig, const unsigned char *reply, int reply_size, const char *func_name); -int validate_mode_response(RIG *rig, unsigned char *reply, int reply_size, +int validate_mode_response(RIG *rig, const unsigned char *reply, int reply_size, const char *func_name, int min_length); #endif // _guohetec_H_ diff --git a/rigs/guohetec/pmr171.c b/rigs/guohetec/pmr171.c index 51183af98..38a5ada07 100644 --- a/rigs/guohetec/pmr171.c +++ b/rigs/guohetec/pmr171.c @@ -367,39 +367,39 @@ static int pmr171_open(RIG *rig) cmd[6] = crc >> 8; cmd[7] = crc & 0xFF; - // Receive buffer and send command - unsigned char reply[40]; - pmr171_send(rig, cmd, sizeof(cmd), reply, sizeof(reply)); - - // Validate response using common function - if (validate_freq_response(rig, reply, sizeof(reply), __func__) < 0) { - RETURN_CACHED_FREQ(rig, vfo, freq); - } + { + unsigned char reply[40]; + pmr171_send(rig, cmd, sizeof(cmd), reply, sizeof(reply)); - // Parse frequency (big-endian) - int freq_a_offset = 9; // VFOA frequency starting position - int freq_b_offset = 13; // VFOB frequency starting position + // Validate response using common function + if (validate_freq_response(rig, reply, sizeof(reply), __func__) < 0) { + RETURN_CACHED_FREQ(rig, vfo, freq); + } - uint32_t freq_a = (reply[freq_a_offset] << 24) | - (reply[freq_a_offset+1] << 16) | - (reply[freq_a_offset+2] << 8) | - reply[freq_a_offset+3]; + // Parse frequency (big-endian) + int freq_a_offset = 9; // VFOA frequency starting position + int freq_b_offset = 13; // VFOB frequency starting position - uint32_t freq_b = (reply[freq_b_offset] << 24) | - (reply[freq_b_offset+1] << 16) | - (reply[freq_b_offset+2] << 8) | - reply[freq_b_offset+3]; + uint32_t freq_a = (reply[freq_a_offset] << 24) | + (reply[freq_a_offset+1] << 16) | + (reply[freq_a_offset+2] << 8) | + reply[freq_a_offset+3]; - // Update cache - CACHE(rig)->freqMainA = (freq_t)freq_a; - CACHE(rig)->freqMainB = (freq_t)freq_b; + uint32_t freq_b = (reply[freq_b_offset] << 24) | + (reply[freq_b_offset+1] << 16) | + (reply[freq_b_offset+2] << 8) | + reply[freq_b_offset+3]; - // Return requested VFO frequency - *freq = (vfo == RIG_VFO_A) ? CACHE(rig)->freqMainA : CACHE(rig)->freqMainB; + // Update cache + CACHE(rig)->freqMainA = (freq_t)freq_a; + CACHE(rig)->freqMainB = (freq_t)freq_b; - rig_debug(RIG_DEBUG_VERBOSE, "%s: Successfully got VFOA=%.0f Hz, VFOB=%.0f Hz\n", - __func__, CACHE(rig)->freqMainA, CACHE(rig)->freqMainB); + // Return requested VFO frequency + *freq = (vfo == RIG_VFO_A) ? CACHE(rig)->freqMainA : CACHE(rig)->freqMainB; + rig_debug(RIG_DEBUG_VERBOSE, "%s: Successfully got VFOA=%.0f Hz, VFOB=%.0f Hz\n", + __func__, CACHE(rig)->freqMainA, CACHE(rig)->freqMainB); + } return RIG_OK; } @@ -407,28 +407,25 @@ static int pmr171_open(RIG *rig) { struct rig_cache *cachep = CACHE(rig); const pmr171_data_t *p = (pmr171_data_t *) STATE(rig)->priv; - unsigned char reply[40]; - - // Get latest status from hardware - pmr171_send_cmd1(rig, 0x0b, 0); - - // Read and validate response using common function - if (read_rig_response(rig, reply, sizeof(reply), __func__) < 0) { - RETURN_CACHED_MODE(rig, vfo, mode, width, cachep, p); - } - - // Validate mode response using common function - if (validate_mode_response(rig, reply, sizeof(reply), __func__, 5) < 0) { - RETURN_CACHED_MODE(rig, vfo, mode, width, cachep, p); + { + unsigned char reply[40]; + // Get latest status from hardware + pmr171_send_cmd1(rig, 0x0b, 0); + // Read and validate response using common function + if (read_rig_response(rig, reply, sizeof(reply), __func__) < 0) { + RETURN_CACHED_MODE(rig, vfo, mode, width, cachep, p); + } + // Validate mode response using common function + if (validate_mode_response(rig, reply, sizeof(reply), __func__, 5) < 0) { + RETURN_CACHED_MODE(rig, vfo, mode, width, cachep, p); + } + // Update cache + cachep->modeMainA = guohe2rmode(reply[7], pmr171_modes); + cachep->modeMainB = guohe2rmode(reply[8], pmr171_modes); + // Return requested mode + *mode = (vfo == RIG_VFO_A) ? cachep->modeMainA : cachep->modeMainB; + *width = p->filterBW; } - - // Update cache - cachep->modeMainA = guohe2rmode(reply[7], pmr171_modes); - cachep->modeMainB = guohe2rmode(reply[8], pmr171_modes); - - // Return requested mode - *mode = (vfo == RIG_VFO_A) ? cachep->modeMainA : cachep->modeMainB; - *width = p->filterBW; return RIG_OK; } @@ -445,25 +442,22 @@ static int pmr171_open(RIG *rig) static int pmr171_get_vfo(RIG *rig, vfo_t *vfo) { - unsigned char reply[40]; - - // Send status sync command to get current VFO state - pmr171_send_cmd1(rig, 0x0b, 0); - - // Read and validate response using common function - if (read_rig_response(rig, reply, sizeof(reply), __func__) < 0) { - RETURN_CACHED_VFO(rig, vfo); - } - - // Validate VFO status field index won't overflow - if (reply[4] < 13) { // Need at least 13 bytes to access reply[17] - rig_debug(RIG_DEBUG_ERR, "%s: Response too short for VFO data, using cached values\n", __func__); - RETURN_CACHED_VFO(rig, vfo); + { + unsigned char reply[40]; + // Send status sync command to get current VFO state + pmr171_send_cmd1(rig, 0x0b, 0); + // Read and validate response using common function + if (read_rig_response(rig, reply, sizeof(reply), __func__) < 0) { + RETURN_CACHED_VFO(rig, vfo); + } + // Validate VFO status field index won't overflow + if (reply[4] < 13) { // Need at least 13 bytes to access reply[17] + rig_debug(RIG_DEBUG_ERR, "%s: Response too short for VFO data, using cached values\n", __func__); + RETURN_CACHED_VFO(rig, vfo); + } + // According to protocol doc, reply[17] is A/B frequency status + *vfo = (reply[17] == 1) ? RIG_VFO_B : RIG_VFO_A; } - - // According to protocol doc, reply[17] is A/B frequency status - *vfo = (reply[17] == 1) ? RIG_VFO_B : RIG_VFO_A; - return RIG_OK; } @@ -471,25 +465,22 @@ static int pmr171_open(RIG *rig) static int pmr171_get_ptt(RIG *rig, vfo_t vfo, ptt_t *ptt) { struct rig_cache *cachep = CACHE(rig); - unsigned char reply[40]; - - pmr171_send_cmd1(rig, 0x0b, 0); - - // Read and validate response using common function - if (read_rig_response(rig, reply, sizeof(reply), __func__) < 0) { - RETURN_CACHED_PTT(rig, ptt, cachep); - } - - // Validate PTT status field index won't overflow - if (reply[4] < 2) { // Need at least 2 bytes to access reply[6] - rig_debug(RIG_DEBUG_ERR, "%s: Response too short for PTT data, using cached values\n", __func__); - RETURN_CACHED_PTT(rig, ptt, cachep); + { + unsigned char reply[40]; + pmr171_send_cmd1(rig, 0x0b, 0); + // Read and validate response using common function + if (read_rig_response(rig, reply, sizeof(reply), __func__) < 0) { + RETURN_CACHED_PTT(rig, ptt, cachep); + } + // Validate PTT status field index won't overflow + if (reply[4] < 2) { // Need at least 2 bytes to access reply[6] + rig_debug(RIG_DEBUG_ERR, "%s: Response too short for PTT data, using cached values\n", __func__); + RETURN_CACHED_PTT(rig, ptt, cachep); + } + // Get PTT status + cachep->ptt = reply[6]; + *ptt = cachep->ptt; } - - // Get PTT status - cachep->ptt = reply[6]; - *ptt = cachep->ptt; - return RIG_OK; } @@ -525,28 +516,24 @@ static int pmr171_open(RIG *rig) static int pmr171_send_cmd2(RIG *rig, unsigned char cmd, unsigned char value, int response) { - unsigned char reply[40]; + unsigned char buf[64] = { 0xa5, 0xa5, 0xa5, 0xa5, 0x04, 0x00, 0x00, 0x00, 0x00 }; hamlib_port_t *rp = RIGPORT(rig); rig_debug(RIG_DEBUG_VERBOSE, "%s: called\n", __func__); - unsigned char buf[64] = { 0xa5, 0xa5, 0xa5, 0xa5, 0x04, 0x00, 0x00, 0x00, 0x00 }; - buf[5] = cmd; buf[6] = value; unsigned int crc = CRC16Check(&buf[4], 3); buf[7] = crc >> 8; buf[8] = crc & 0xff; - rig_flush(rp); write_block(rp, buf, 9); - if (response) { + unsigned char reply[40]; // Use common response reading function if (read_rig_response(rig, reply, sizeof(reply), __func__) < 0) { return RIG_OK; // Return OK to use cached values } } - return pmr171_read_ack(rig); } diff --git a/rigs/guohetec/q900.c b/rigs/guohetec/q900.c index 059106f67..2e6d6bc0e 100644 --- a/rigs/guohetec/q900.c +++ b/rigs/guohetec/q900.c @@ -363,36 +363,32 @@ static int q900_get_freq(RIG *rig, vfo_t vfo, freq_t *freq) cmd[6] = crc >> 8; cmd[7] = crc & 0xFF; - unsigned char reply[40]; - q900_send(rig, cmd, sizeof(cmd), reply, sizeof(reply)); - - // Validate response using common function - if (validate_freq_response(rig, reply, sizeof(reply), __func__) < 0) { - RETURN_CACHED_FREQ(rig, vfo, freq); + { + unsigned char reply[40]; + q900_send(rig, cmd, sizeof(cmd), reply, sizeof(reply)); + // Validate response using common function + if (validate_freq_response(rig, reply, sizeof(reply), __func__) < 0) { + RETURN_CACHED_FREQ(rig, vfo, freq); + } + // Parse frequency (big-endian) + int freq_a_offset = 9; // VFOA frequency starting position + int freq_b_offset = 13; // VFOB frequency starting position + uint32_t freq_a = (reply[freq_a_offset] << 24) | + (reply[freq_a_offset+1] << 16) | + (reply[freq_a_offset+2] << 8) | + reply[freq_a_offset+3]; + uint32_t freq_b = (reply[freq_b_offset] << 24) | + (reply[freq_b_offset+1] << 16) | + (reply[freq_b_offset+2] << 8) | + reply[freq_b_offset+3]; + // Update cache + CACHE(rig)->freqMainA = (freq_t)freq_a; + CACHE(rig)->freqMainB = (freq_t)freq_b; + // Return requested VFO frequency + *freq = (vfo == RIG_VFO_A) ? CACHE(rig)->freqMainA : CACHE(rig)->freqMainB; + rig_debug(RIG_DEBUG_VERBOSE, "%s: Successfully got VFOA=%.0f Hz, VFOB=%.0f Hz\n", + __func__, CACHE(rig)->freqMainA, CACHE(rig)->freqMainB); } - - // Parse frequency (big-endian) - int freq_a_offset = 9; - int freq_b_offset = 13; - - uint32_t freq_a = (reply[freq_a_offset] << 24) | - (reply[freq_a_offset+1] << 16) | - (reply[freq_a_offset+2] << 8) | - reply[freq_a_offset+3]; - - uint32_t freq_b = (reply[freq_b_offset] << 24) | - (reply[freq_b_offset+1] << 16) | - (reply[freq_b_offset+2] << 8) | - reply[freq_b_offset+3]; - - CACHE(rig)->freqMainA = (freq_t)freq_a; - CACHE(rig)->freqMainB = (freq_t)freq_b; - - *freq = (vfo == RIG_VFO_A) ? CACHE(rig)->freqMainA : CACHE(rig)->freqMainB; - - rig_debug(RIG_DEBUG_VERBOSE, "%s: Successfully obtained VFOA=%.0f Hz, VFOB=%.0f Hz\n", - __func__, CACHE(rig)->freqMainA, CACHE(rig)->freqMainB); - return RIG_OK; } @@ -400,25 +396,25 @@ static int q900_get_freq(RIG *rig, vfo_t vfo, freq_t *freq) { struct rig_cache *cachep = CACHE(rig); const q900_data_t *p = (q900_data_t *) STATE(rig)->priv; - unsigned char reply[255]; - - q900_send_cmd1(rig, 0x0b, 0); - - // Read and validate response using common function - if (read_rig_response(rig, reply, sizeof(reply), __func__) < 0) { - RETURN_CACHED_MODE(rig, vfo, mode, width, cachep, p); - } - - // Validate mode response using common function - if (validate_mode_response(rig, reply, sizeof(reply), __func__, 5) < 0) { - RETURN_CACHED_MODE(rig, vfo, mode, width, cachep, p); + { + unsigned char reply[255]; + // Get latest status from hardware + q900_send_cmd1(rig, 0x0b, 0); + // Read and validate response using common function + if (read_rig_response(rig, reply, sizeof(reply), __func__) < 0) { + RETURN_CACHED_MODE(rig, vfo, mode, width, cachep, p); + } + // Validate mode response using common function + if (validate_mode_response(rig, reply, sizeof(reply), __func__, 5) < 0) { + RETURN_CACHED_MODE(rig, vfo, mode, width, cachep, p); + } + // Update cache + cachep->modeMainA = guohe2rmode(reply[7], q900_modes); + cachep->modeMainB = guohe2rmode(reply[8], q900_modes); + // Return requested mode + *mode = (vfo == RIG_VFO_A) ? cachep->modeMainA : cachep->modeMainB; + *width = p->filterBW; } - - cachep->modeMainA = guohe2rmode(reply[7], q900_modes); - cachep->modeMainB = guohe2rmode(reply[8], q900_modes); - - *mode = (vfo == RIG_VFO_A) ? cachep->modeMainA : cachep->modeMainB; - *width = p->filterBW; return RIG_OK; } @@ -435,29 +431,22 @@ static int q900_get_freq(RIG *rig, vfo_t vfo, freq_t *freq) static int q900_get_vfo(RIG *rig, vfo_t *vfo) { - unsigned char reply[255]; - - q900_send_cmd1(rig, 0x0b, 0); - - // Read and validate response using common function - if (read_rig_response(rig, reply, sizeof(reply), __func__) < 0) { - RETURN_CACHED_VFO(rig, vfo); - } - - // Validate VFO status field index won't overflow - if (reply[4] < 13) { // Need at least 13 bytes to access reply[17] - rig_debug(RIG_DEBUG_ERR, "%s: Response too short for VFO data, using cached values\n", __func__); - RETURN_CACHED_VFO(rig, vfo); - } - - // Validate VFO status value - if (reply[17] != 0 && reply[17] != 1) { - rig_debug(RIG_DEBUG_ERR, "%s: Invalid VFO status value %d, using cached values\n", __func__, reply[17]); - RETURN_CACHED_VFO(rig, vfo); + { + unsigned char reply[255]; + // Send status sync command to get current VFO state + q900_send_cmd1(rig, 0x0b, 0); + // Read and validate response using common function + if (read_rig_response(rig, reply, sizeof(reply), __func__) < 0) { + RETURN_CACHED_VFO(rig, vfo); + } + // Validate VFO status field index won't overflow + if (reply[4] < 13) { // Need at least 13 bytes to access reply[17] + rig_debug(RIG_DEBUG_ERR, "%s: Response too short for VFO data, using cached values\n", __func__); + RETURN_CACHED_VFO(rig, vfo); + } + // According to protocol doc, reply[17] is A/B frequency status + *vfo = (reply[17] == 1) ? RIG_VFO_B : RIG_VFO_A; } - - *vfo = (reply[17] == 1) ? RIG_VFO_B : RIG_VFO_A; - return RIG_OK; } @@ -465,30 +454,22 @@ static int q900_get_freq(RIG *rig, vfo_t vfo, freq_t *freq) static int q900_get_ptt(RIG *rig, vfo_t vfo, ptt_t *ptt) { struct rig_cache *cachep = CACHE(rig); - unsigned char reply[255]; - - q900_send_cmd1(rig, 0x0b, 0); - - // Read and validate response using common function - if (read_rig_response(rig, reply, sizeof(reply), __func__) < 0) { - RETURN_CACHED_PTT(rig, ptt, cachep); - } - - // Validate PTT status field index won't overflow - if (reply[4] < 2) { // Need at least 2 bytes to access reply[6] - rig_debug(RIG_DEBUG_ERR, "%s: Response too short for PTT data, using cached values\n", __func__); - RETURN_CACHED_PTT(rig, ptt, cachep); - } - - // Validate PTT status value - if (reply[6] != 0 && reply[6] != 1) { - rig_debug(RIG_DEBUG_ERR, "%s: Invalid PTT status value %d, using cached values\n", __func__, reply[6]); - RETURN_CACHED_PTT(rig, ptt, cachep); + { + unsigned char reply[255]; + q900_send_cmd1(rig, 0x0b, 0); + // Read and validate response using common function + if (read_rig_response(rig, reply, sizeof(reply), __func__) < 0) { + RETURN_CACHED_PTT(rig, ptt, cachep); + } + // Validate PTT status field index won't overflow + if (reply[4] < 2) { // Need at least 2 bytes to access reply[6] + rig_debug(RIG_DEBUG_ERR, "%s: Response too short for PTT data, using cached values\n", __func__); + RETURN_CACHED_PTT(rig, ptt, cachep); + } + // Get PTT status + cachep->ptt = reply[6]; + *ptt = cachep->ptt; } - - cachep->ptt = reply[6]; - *ptt = cachep->ptt; - return RIG_OK; } @@ -527,28 +508,24 @@ static int q900_get_ptt(RIG *rig, vfo_t vfo, ptt_t *ptt) static int q900_send_cmd2(RIG *rig, unsigned char cmd, unsigned char value, int response) { - unsigned char reply[256]; + unsigned char buf[64] = { 0xa5, 0xa5, 0xa5, 0xa5, 0x04, 0x00, 0x00, 0x00, 0x00 }; hamlib_port_t *rp = RIGPORT(rig); rig_debug(RIG_DEBUG_VERBOSE, "%s: called\n", __func__); - unsigned char buf[64] = { 0xa5, 0xa5, 0xa5, 0xa5, 0x04, 0x00, 0x00, 0x00, 0x00 }; - buf[5] = cmd; buf[6] = value; unsigned int crc = CRC16Check(&buf[4], 3); buf[7] = crc >> 8; buf[8] = crc & 0xff; - rig_flush(rp); write_block(rp, buf, 9); - if (response) { + unsigned char reply[256]; // Use common response reading function if (read_rig_response(rig, reply, sizeof(reply), __func__) < 0) { return RIG_OK; // Return OK to use cached values } } - return q900_read_ack(rig); } commit c2d4fbe601c7d6dce463d133634c2458e0489fd3 Author: 声纳 <159...@qq...> Date: Sat Jun 28 16:56:54 2025 +0800 guohetec: comprehensive code quality improvements - Fix compilation warnings by removing unnecessary dump_hex function calls - Resolve implicit function declaration warnings for validation macros - Remove duplicate GUOHE_MODE_TABLE_MAX definitions across files - Optimize header includes based on IWYU suggestions: * Add iofunc.h (for read_block/write_block functions) * Add riglist.h (for RIG_MODEL_* constants) * Remove unistd.h, misc.h, serial.h (unnecessary includes) - Convert validation macros to functions for better compiler compatibility - Maintain backward compatibility with existing macro definitions - Improve code structure and maintainability - Ensure WSJT-X compatibility with consistent error handling All changes maintain existing functionality while improving code quality and reducing compilation warnings. diff --git a/rigs/guohetec/guohetec.c b/rigs/guohetec/guohetec.c index 794425122..d5019c39a 100644 --- a/rigs/guohetec/guohetec.c +++ b/rigs/guohetec/guohetec.c @@ -1,11 +1,29 @@ -#include <unistd.h> #include <string.h> #include <hamlib/rig.h> -#include "serial.h" +#include "iofunc.h" #include "register.h" +#include "riglist.h" #include "guohetec.h" -#include "misc.h" +// Common response validation function implementations +int validate_packet_header(const unsigned char *reply, const char *func_name) +{ + if (reply[0] != 0xA5 || reply[1] != 0xA5 || + reply[2] != 0xA5 || reply[3] != 0xA5) { + rig_debug(RIG_DEBUG_ERR, "%s: Invalid packet header, using cached values\n", func_name); + return -1; + } + return 0; +} + +int validate_data_length(const unsigned char *reply, int reply_size, const char *func_name) +{ + if (reply[4] == 0 || reply[4] > reply_size - 5) { + rig_debug(RIG_DEBUG_ERR, "%s: Invalid data length %d, using cached values\n", func_name, reply[4]); + return -1; + } + return 0; +} // CRC16/CCITT-FALSE uint16_t CRC16Check(const unsigned char *buf, int len) @@ -175,10 +193,14 @@ int validate_rig_response(RIG *rig, unsigned char *reply, int reply_size, const char *func_name) { // Validate packet header - VALIDATE_PACKET_HEADER(reply, func_name); + if (validate_packet_header(reply, func_name) < 0) { + return -1; + } // Validate data length - VALIDATE_DATA_LENGTH(reply, reply_size, func_name); + if (validate_data_length(reply, reply_size, func_name) < 0) { + return -1; + } return 0; } diff --git a/rigs/guohetec/guohetec.h b/rigs/guohetec/guohetec.h index 90965a129..589e2e3f7 100644 --- a/rigs/guohetec/guohetec.h +++ b/rigs/guohetec/guohetec.h @@ -31,21 +31,13 @@ return RIG_OK; \ } while(0) -// Common response validation macros -#define VALIDATE_PACKET_HEADER(reply, func_name) do { \ - if (reply[0] != 0xA5 || reply[1] != 0xA5 || \ - reply[2] != 0xA5 || reply[3] != 0xA5) { \ - rig_debug(RIG_DEBUG_ERR, "%s: Invalid packet header, using cached values\n", func_name); \ - return -1; \ - } \ -} while(0) +// Common response validation function declarations +int validate_packet_header(const unsigned char *reply, const char *func_name); +int validate_data_length(const unsigned char *reply, int reply_size, const char *func_name); -#define VALIDATE_DATA_LENGTH(reply, reply_size, func_name) do { \ - if (reply[4] == 0 || reply[4] > (reply_size) - 5) { \ - rig_debug(RIG_DEBUG_ERR, "%s: Invalid data length %d, using cached values\n", func_name, reply[4]); \ - return -1; \ - } \ -} while(0) +// Keep the macro for backward compatibility +#define VALIDATE_PACKET_HEADER(reply, func_name) validate_packet_header(reply, func_name) +#define VALIDATE_DATA_LENGTH(reply, reply_size, func_name) validate_data_length(reply, reply_size, func_name) #define VALIDATE_READ_RESULT(ret, expected, func_name) do { \ if (ret < 0) { \ diff --git a/rigs/guohetec/pmr171.c b/rigs/guohetec/pmr171.c index e1ede9adf..51183af98 100644 --- a/rigs/guohetec/pmr171.c +++ b/rigs/guohetec/pmr171.c @@ -7,14 +7,12 @@ #endif #include "hamlib/rig.h" -#include "serial.h" +#include "iofunc.h" #include "guohetec.h" #include "cache.h" -#include "misc.h" #include "tones.h" #include "bandplan.h" #include "cal.h" -#include <unistd.h> typedef struct pmr171_data_s @@ -39,8 +37,6 @@ typedef struct pmr171_data_s char SWR; } pmr171_data_t; - -#define GUOHE_MODE_TABLE_MAX 8 static rmode_t pmr171_modes[GUOHE_MODE_TABLE_MAX] = { RIG_MODE_USB, @@ -598,17 +594,15 @@ static int pmr171_open(RIG *rig) return RIG_OK; } - dump_hex(reply, 16); - - // Update cache with requested frequency - if (vfo == RIG_VFO_B) - { - CACHE(rig)->freqMainB = freq; - } - else - { - CACHE(rig)->freqMainA = freq; - } + // Update cache with requested frequency + if (vfo == RIG_VFO_B) + { + CACHE(rig)->freqMainB = freq; + } + else + { + CACHE(rig)->freqMainA = freq; + } return RIG_OK; } @@ -684,8 +678,6 @@ static int pmr171_open(RIG *rig) return RIG_OK; } - dump_hex(reply, reply[4] + 5); - // Update cache with response data CACHE(rig)->modeMainA = guohe2rmode(reply[6], pmr171_modes); CACHE(rig)->modeMainB = guohe2rmode(reply[7], pmr171_modes); diff --git a/rigs/guohetec/q900.c b/rigs/guohetec/q900.c index 7bdcf8392..059106f67 100644 --- a/rigs/guohetec/q900.c +++ b/rigs/guohetec/q900.c @@ -7,14 +7,12 @@ #endif #include "hamlib/rig.h" -#include "serial.h" +#include "iofunc.h" #include "guohetec.h" #include "cache.h" -#include "misc.h" #include "tones.h" #include "bandplan.h" #include "cal.h" -#include <unistd.h> typedef struct q900_data_s { @@ -38,8 +36,6 @@ typedef struct q900_data_s char SWR; } q900_data_t; - -#define GUOHE_MODE_TABLE_MAX 8 static rmode_t q900_modes[GUOHE_MODE_TABLE_MAX] = { RIG_MODE_USB, @@ -599,17 +595,15 @@ static int q900_get_ptt(RIG *rig, vfo_t vfo, ptt_t *ptt) return RIG_OK; } - dump_hex(reply, 16); - - // Update cache with requested frequency - if (vfo == RIG_VFO_B) - { - CACHE(rig)->freqMainB = freq; - } - else - { - CACHE(rig)->freqMainA = freq; - } + // Update cache with requested frequency + if (vfo == RIG_VFO_B) + { + CACHE(rig)->freqMainB = freq; + } + else + { + CACHE(rig)->freqMainA = freq; + } return RIG_OK; } @@ -712,8 +706,6 @@ static int q900_get_ptt(RIG *rig, vfo_t vfo, ptt_t *ptt) return RIG_OK; } - dump_hex(reply, reply[4] + 5); - // Update cache with response data CACHE(rig)->modeMainA = guohe2rmode(reply[6], q900_modes); CACHE(rig)->modeMainB = guohe2rmode(reply[7], q900_modes); @@ -799,3 +791,4 @@ static int q900_set_ptt(RIG *rig, vfo_t vfo, ptt_t ptt) } /* ---------------------------------------------------------------------- */ + commit a61877a60be23df45439cc607585ecfe55d46395 Author: 声纳 <159...@qq...> Date: Sat Jun 28 11:07:50 2025 +0800 Fix duplicate stdint.h includes in pmr171.c and q900.c diff --git a/rigs/guohetec/pmr171.c b/rigs/guohetec/pmr171.c index 94704378f..e1ede9adf 100644 --- a/rigs/guohetec/pmr171.c +++ b/rigs/guohetec/pmr171.c @@ -14,7 +14,6 @@ #include "tones.h" #include "bandplan.h" #include "cal.h" -#include <stdint.h> #include <unistd.h> @@ -272,8 +271,6 @@ struct rig_caps pmr171_caps = .hamlib_check_rig_caps = HAMLIB_CHECK_RIG_CAPS }; -#include <stdint.h> - /* ---------------------------------------------------------------------- */ static int pmr171_init(RIG *rig) diff --git a/rigs/guohetec/q900.c b/rigs/guohetec/q900.c index 276861459..7bdcf8392 100644 --- a/rigs/guohetec/q900.c +++ b/rigs/guohetec/q900.c @@ -14,7 +14,6 @@ #include "tones.h" #include "bandplan.h" #include "cal.h" -#include <stdint.h> #include <unistd.h> typedef struct q900_data_s @@ -270,8 +269,6 @@ struct rig_caps q900_caps = .hamlib_check_rig_caps = HAMLIB_CHECK_RIG_CAPS }; -#include <stdint.h> - /* ---------------------------------------------------------------------- */ static int q900_init(RIG *rig) commit 19c2cc03156846d22262536e9cde7f70deff26db Author: 声纳 <159...@qq...> Date: Sat Jun 28 11:04:58 2025 +0800 Fix duplicate retval variable definition in guohetec.c probe function diff --git a/rigs/guohetec/guohetec.c b/rigs/guohetec/guohetec.c index 64e9be3d8..794425122 100644 --- a/rigs/guohetec/guohetec.c +++ b/rigs/guohetec/guohetec.c @@ -301,7 +301,6 @@ DECLARE_PROBERIG_BACKEND(guohetec) { rig_flush(port); - int retval = write_block(port, cmd, PMR171_CMD_LENGTH); int retval = write_block(port, cmd, PMR171_CMD_LENGTH); if (retval != RIG_OK) { continue; commit dee29c555f98413486dd7110b601aa403035970d Author: 声纳 <159...@qq...> Date: Sat Jun 28 10:55:20 2025 +0800 Implement consistent error handling for GUOHETEC drivers - Use unified error handling mechanism in send_cmd2 functions - Always return RIG_OK to prevent WSJT-X errors - Update cache with requested values even when communication fails - Use English comments and debug messages - Ensure graceful degradation with cached values on protocol/timeout errors diff --git a/rigs/guohetec/pmr171.c b/rigs/guohetec/pmr171.c index 386c71ff5..94704378f 100644 --- a/rigs/guohetec/pmr171.c +++ b/rigs/guohetec/pmr171.c @@ -548,22 +548,9 @@ static int pmr171_open(RIG *rig) if (response) { - // Read header - int ret = read_block(rp, reply, 5); - if (ret < 0) { - rig_debug(RIG_DEBUG_ERR, "%s: Failed to read header\n", __func__); - } - - // Validate data length - if (reply[4] == 0 || reply[4] > sizeof(reply) - 5) { - if (reply[4] == 0 || reply[4] > sizeof(reply) - 5) { - rig_debug(RIG_DEBUG_ERR, "%s: Invalid data length %d\n", __func__, reply[4]); - } - - // Read data section - ret = read_block(rp, &reply[5], reply[4]); - if (ret < 0) { - rig_debug(RIG_DEBUG_ERR, "%s: Failed to read data\n", __func__); + // Use common response reading function + if (read_rig_response(rig, reply, sizeof(reply), __func__) < 0) { + return RIG_OK; // Return OK to use cached values } } @@ -601,11 +588,22 @@ static int pmr171_open(RIG *rig) // Read response and validate length int ret = read_block(rp, reply, sizeof(reply)); if (ret < 0) { - rig_debug(RIG_DEBUG_ERR, "%s: Failed to read response\n", __func__); + rig_debug(RIG_DEBUG_ERR, "%s: Failed to read response, using cached values\n", __func__); + // Update cache with requested frequency even if response failed + if (vfo == RIG_VFO_B) + { + CACHE(rig)->freqMainB = freq; + } + else + { + CACHE(rig)->freqMainA = freq; + } + return RIG_OK; } dump_hex(reply, 16); + // Update cache with requested frequency if (vfo == RIG_VFO_B) { CACHE(rig)->freqMainB = freq; @@ -660,31 +658,38 @@ static int pmr171_open(RIG *rig) rig_flush(rp); write_block(rp, cmd, 10); - // Read header - int ret = read_block(rp, reply, 5); - if (ret < 0) { - rig_debug(RIG_DEBUG_ERR, "%s: read_block failed for header\n", __func__); - } - - // Validate data length - if (reply[4] == 0 || reply[4] > sizeof(reply) - 5) { - rig_debug(RIG_DEBUG_ERR, "%s: invalid reply length %d\n", __func__, reply[4]); - } - - // Read data section - ret = read_block(rp, &reply[5], reply[4]); - if (ret < 0) { - rig_debug(RIG_DEBUG_ERR, "%s: read_block failed for data\n", __func__); + // Use common response reading function + if (read_rig_response(rig, reply, sizeof(reply), __func__) < 0) { + // Update cache with requested mode even if response failed + if (vfo == RIG_VFO_B) + { + CACHE(rig)->modeMainB = mode; + } + else + { + CACHE(rig)->modeMainA = mode; + } + return RIG_OK; } // Validate mode field index won't overflow if (reply[4] < 3) { // Need at least 3 bytes to access reply[6] and reply[7] - rig_debug(RIG_DEBUG_ERR, "%s: Response too short for mode data\n", __func__); + rig_debug(RIG_DEBUG_ERR, "%s: Response too short for mode data, using cached values\n", __func__); + // Update cache with requested mode even if validation failed + if (vfo == RIG_VFO_B) + { + CACHE(rig)->modeMainB = mode; + } + else + { + CACHE(rig)->modeMainA = mode; + } + return RIG_OK; } dump_hex(reply, reply[4] + 5); - // Update cache + // Update cache with response data CACHE(rig)->modeMainA = guohe2rmode(reply[6], pmr171_modes); CACHE(rig)->modeMainB = guohe2rmode(reply[7], pmr171_modes); diff --git a/rigs/guohetec/q900.c b/rigs/guohetec/q900.c index 8d4b2c1cc..276861459 100644 --- a/rigs/guohetec/q900.c +++ b/rigs/guohetec/q900.c @@ -319,7 +319,6 @@ static int q900_open(RIG *rig) /* ---------------------------------------------------------------------- */ static int q900_send(RIG *rig, const unsigned char* buff, int len, unsigned char *reply, int rlen) - static int q900_send(RIG *rig, const unsigned char* buff, int len, unsigned char *reply, int rlen) { hamlib_port_t *rp = RIGPORT(rig); int retry = 5; @@ -539,43 +538,24 @@ static int q900_get_ptt(RIG *rig, vfo_t vfo, ptt_t *ptt) hamlib_port_t *rp = RIGPORT(rig); rig_debug(RIG_DEBUG_VERBOSE, "%s: called\n", __func__); unsigned char buf[64] = { 0xa5, 0xa5, 0xa5, 0xa5, 0x04, 0x00, 0x00, 0x00, 0x00 }; - + buf[5] = cmd; buf[6] = value; unsigned int crc = CRC16Check(&buf[4], 3); buf[7] = crc >> 8; buf[8] = crc & 0xff; - + rig_flush(rp); write_block(rp, buf, 9); - + if (response) { - // Read header - int ret = read_block(rp, reply, 5); - if (ret < 0) { - rig_debug(RIG_DEBUG_ERR, "%s: Failed to read header\n", __func__); - } - - // Validate data length - if (reply[4] == 0 || reply[4] > sizeof(reply) - 5) { - if (reply[4] == 0 || reply[4] > sizeof(reply) - 5) { - rig_debug(RIG_DEBUG_ERR, "%s: Invalid data length %d\n", __func__, reply[4]); - } - - // Read data section - ret = read_block(rp, &reply[5], reply[4]); - if (ret < 0) { - rig_debug(RIG_DEBUG_ERR, "%s: Failed to read data\n", __func__); - } - - // Validate response length matches expected - if (ret != reply[4]) { - rig_debug(RIG_DEBUG_ERR, "%s: Data read mismatch: expected %d, got %d\n", - __func__, reply[4], ret); + // Use common response reading function + if (read_rig_response(rig, reply, sizeof(reply), __func__) < 0) { + return RIG_OK; // Return OK to use cached values } } - + return q900_read_ack(rig); } @@ -586,7 +566,7 @@ static int q900_get_ptt(RIG *rig, vfo_t vfo, ptt_t *ptt) unsigned char cmd[16] = { 0xa5, 0xa5, 0xa5, 0xa5, 11, 0x09, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; unsigned char reply[16]; hamlib_port_t *rp = RIGPORT(rig); - + rig_debug(RIG_DEBUG_VERBOSE, "q900: requested freq = %"PRIfreq" Hz\n", freq); if (vfo == RIG_VFO_B) @@ -609,12 +589,22 @@ static int q900_get_ptt(RIG *rig, vfo_t vfo, ptt_t *ptt) // Read response int ret = read_block(rp, reply, 16); if (ret < 0) { - rig_debug(RIG_DEBUG_ERR, "%s: Failed to read response\n", __func__); + rig_debug(RIG_DEBUG_ERR, "%s: Failed to read response, using cached values\n", __func__); + // Update cache with requested frequency even if response failed + if (vfo == RIG_VFO_B) + { + CACHE(rig)->freqMainB = freq; + } + else + { + CACHE(rig)->freqMainA = freq; + } + return RIG_OK; } dump_hex(reply, 16); - + // Update cache with requested frequency if (vfo == RIG_VFO_B) { CACHE(rig)->freqMainB = freq; @@ -667,104 +657,67 @@ static int q900_get_ptt(RIG *rig, vfo_t vfo, ptt_t *ptt) rig_flush(rp); write_block(rp, cmd, 10); - // Read header - int ret = read_block(rp, reply, 5); - if (ret < 0) { - rig_debug(RIG_DEBUG_ERR, "%s: read_block failed for header\n", __func__); - } - - // Validate data length - if (reply[4] == 0 || reply[4] > sizeof(reply) - 5) { - rig_debug(RIG_DEBUG_ERR, "%s: invalid reply length %d\n", __func__, reply[4]); - } - - // Read data section - ret = read_block(rp, &reply[5], reply[4]); - if (ret < 0) { - rig_debug(RIG_DEBUG_ERR, "%s: read_block failed for data\n", __func__); - } - - // Validate response length matches expected - if (ret != reply[4]) { - rig_debug(RIG_DEBUG_ERR, "%s: Data read mismatch: expected %d, got %d\n", - __func__, reply[4], ret); - } - - // Validate mode field index won't overflow - if (reply[4] < 3) { // Need at least 3 bytes to access reply[6] and reply[7] - rig_debug(RIG_DEBUG_ERR, "%s: Response too short for mode data\n", __func__); - } - - // Validate mode field indices are within bounds - if (reply[6] >= GUOHE_MODE_TABLE_MAX) { - rig_debug(RIG_DEBUG_ERR, "%s: Invalid mode A index %d\n", __func__, reply[6]); - } - - if (reply[7] >= GUOHE_MODE_TABLE_MAX) { - rig_debug(RIG_DEBUG_ERR, "%s: Invalid mode B index %d\n", __func__, reply[7]); - } - - dump_hex(reply, reply[4] + 5); - - CACHE(rig)->modeMainA = guohe2rmode(reply[6], q900_modes); - CACHE(rig)->modeMainB = guohe2rmode(reply[7], q900_modes); - - if (vfo == RIG_VFO_B) - { - cmd[6] = rmode2guohe(CACHE(rig)->modeMainA, q900_modes); - cmd[7] = i; - } - else - { - cmd[6] = i; - cmd[7] = rmode2guohe(CACHE(rig)->modeMainB, q900_modes); - } - - int crc = CRC16Check(&cmd[4], 4); - cmd[8] = crc >> 8; - cmd[9] = crc & 0xff; - rig_flush(rp); - write_block(rp, cmd, 10); - - // Read header - int ret = read_block(rp, reply, 5); - if (ret < 0) { - rig_debug(RIG_DEBUG_ERR, "%s: read_block failed for header\n", __func__); - } - - // Validate data length - if (reply[4] == 0 || reply[4] > sizeof(reply) - 5) { - rig_debug(RIG_DEBUG_ERR, "%s: invalid reply length %d\n", __func__, reply[4]); - } - - // Read data section - ret = read_block(rp, &reply[5], reply[4]); - if (ret < 0) { - rig_debug(RIG_DEBUG_ERR, "%s: read_block failed for data\n", __func__); - } - - // Validate response length matches expected - if (ret != reply[4]) { - rig_debug(RIG_DEBUG_ERR, "%s: Data read mismatch: expected %d, got %d\n", - __func__, reply[4], ret); + // Use common response reading function + if (read_rig_response(rig, reply, sizeof(reply), __func__) < 0) { + // Update cache with requested mode even if response failed + if (vfo == RIG_VFO_B) + { + CACHE(rig)->modeMainB = mode; + } + else + { + CACHE(rig)->modeMainA = mode; + } + return RIG_OK; } // Validate mode field index won't overflow if (reply[4] < 3) { // Need at least 3 bytes to access reply[6] and reply[7] - rig_debug(RIG_DEBUG_ERR, "%s: Response too short for mode data\n", __func__); + rig_debug(RIG_DEBUG_ERR, "%s: Response too short for mode data, using cached values\n", __func__); + // Update cache with requested mode even if validation failed + if (vfo == RIG_VFO_B) + { + CACHE(rig)->modeMainB = mode; + } + else + { + CACHE(rig)->modeMainA = mode; + } + return RIG_OK; } // Validate mode field indices are within bounds if (reply[6] >= GUOHE_MODE_TABLE_MAX) { - rig_debug(RIG_DEBUG_ERR, "%s: Invalid mode A index %d\n", __func__, reply[6]); + rig_debug(RIG_DEBUG_ERR, "%s: Invalid mode A index %d, using cached values\n", __func__, reply[6]); + // Update cache with requested mode even if validation failed + if (vfo == RIG_VFO_B) + { + CACHE(rig)->modeMainB = mode; + } + else + { + CACHE(rig)->modeMainA = mode; + } + return RIG_OK; } if (reply[7] >= GUOHE_MODE_TABLE_MAX) { - rig_debug(RIG_DEBUG_ERR, "%s: Invalid mode B index %d\n", __func__, reply[7]); + rig_debug(RIG_DEBUG_ERR, "%s: Invalid mode B index %d, using cached values\n", __func__, reply[7]); + // Update cache with requested mode even if validation failed + if (vfo == RIG_VFO_B) + { + CACHE(rig)->modeMainB = mode; + } + else + { + CACHE(rig)->modeMainA = mode; + } + return RIG_OK; } dump_hex(reply, reply[4] + 5); + // Update cache with response data CACHE(rig)->modeMainA = guohe2rmode(reply[6], q900_modes); CACHE(rig)->modeMainB = guohe2rmode(reply[7], q900_modes); @@ -787,7 +740,6 @@ static int q900_set_ptt(RIG *rig, vfo_t vfo, ptt_t ptt) unsigned char reply[9]; q900_send(rig, cmd, sizeof(cmd), reply, sizeof(reply)); - q900_send(rig, cmd, sizeof(cmd), reply, sizeof(reply)); // Update cache CACHE(rig)->ptt = ptt; commit abf6be0b5e80b3d2376ac873ccf2602ad8e8199f Author: 声纳 <159...@qq...> Date: Sat Jun 28 10:22:26 2025 +0800 Fix compilation errors in GUOHETEC drivers - Remove duplicate function declarations in pmr171_send - Remove duplicate code blocks in pmr171_set_mode - Remove duplicate pmr171_send calls in pmr171_set_ptt - Add missing from_be function implementation - Fix syntax errors that were causing CI failures diff --git a/rigs/guohetec/guohetec.c b/rigs/guohetec/guohetec.c index 414bc42ae..64e9be3d8 100644 --- a/rigs/guohetec/guohetec.c +++ b/rigs/guohetec/guohetec.c @@ -96,6 +96,26 @@ uint16_t CRC16Check(const unsigned char *buf, int len) return data; } + /** + * Convert from big-endian byte order + * @param data Data pointer + * @param byte_len Byte length + * @return Converted value + */ + unsigned long long from_be(const unsigned char data[], unsigned int byte_len) + { + unsigned long long result = 0; + int i; + + rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); + + for (i = 0; i < byte_len; i++) + { + result = (result << 8) | data[i]; + } + + return result; + } // Common response validation functions diff --git a/rigs/guohetec/pmr171.c b/rigs/guohetec/pmr171.c index e3ca96877..386c71ff5 100644 --- a/rigs/guohetec/pmr171.c +++ b/rigs/guohetec/pmr171.c @@ -321,7 +321,6 @@ static int pmr171_open(RIG *rig) /* ---------------------------------------------------------------------- */ static int pmr171_send(RIG *rig, const unsigned char* buff, int len, unsigned char *reply, int rlen) - static int pmr171_send(RIG *rig, const unsigned char* buff, int len, unsigned char *reply, int rlen) { hamlib_port_t *rp = RIGPORT(rig); int retry = 5; @@ -644,16 +643,6 @@ static int pmr171_open(RIG *rig) unsigned char reply[10]; unsigned char i = rmode2guohe(mode, pmr171_modes); - if (vfo == RIG_VFO_B) - { - cmd[6] = rmode2guohe(CACHE(rig)->modeMainA, pmr171_modes); - cmd[7] = i; - } - else - { - cmd[6] = i; - cmd[7] = rmode2guohe(CACHE(rig)->modeMainB, pmr171_modes); - } if (vfo == RIG_VFO_B) { cmd[6] = rmode2guohe(CACHE(rig)->modeMainA, pmr171_modes); @@ -695,39 +684,6 @@ static int pmr171_open(RIG *rig) dump_hex(reply, reply[4] + 5); - // Update cache - CACHE(rig)->modeMainA = guohe2rmode(reply[6], pmr171_modes); - CACHE(rig)->modeMainB = guohe2rmode(reply[7], pmr171_modes); - int crc = CRC16Check(&cmd[4], 4); - cmd[8] = crc >> 8; - cmd[9] = crc & 0xff; - rig_flush(rp); - write_block(rp, cmd, 10); - - // Read header - int ret = read_block(rp, reply, 5); - if (ret < 0) { - rig_debug(RIG_DEBUG_ERR, "%s: read_block failed for header\n", __func__); - } - - // Validate data length - if (reply[4] == 0 || reply[4] > sizeof(reply) - 5) { - rig_debug(RIG_DEBUG_ERR, "%s: invalid reply length %d\n", __func__, reply[4]); - } - - // Read data section - ret = read_block(rp, &reply[5], reply[4]); - if (ret < 0) { - rig_debug(RIG_DEBUG_ERR, "%s: read_block failed for data\n", __func__); - } - - // Validate mode field index won't overflow - if (reply[4] < 3) { // Need at least 3 bytes to access reply[6] and reply[7] - rig_debug(RIG_DEBUG_ERR, "%s: Response too short for mode data\n", __func__); - } - - dump_hex(reply, reply[4] + 5); - // Update cache CACHE(rig)->modeMainA = guohe2rmode(reply[6], pmr171_modes); CACHE(rig)->modeMainB = guohe2rmode(reply[7], pmr171_modes); @@ -751,7 +707,6 @@ static int pmr171_set_ptt(RIG *rig, vfo_t vfo, ptt_t ptt) unsigned char reply[9]; pmr171_send(rig, cmd, sizeof(cmd), reply, sizeof(reply)); - pmr171_send(rig, cmd, sizeof(cmd), reply, sizeof(reply)); CACHE(rig)->ptt = ptt; commit c9161e2e25d80609d5127ca0c1ebe8e78cb00040 Author: 声纳 <159...@qq...> Date: Sat Jun 28 10:11:21 2025 +0800 Improve error handling for GUOHETEC drivers to enhance WSJT-X compatibility - Add graceful degradation for communication errors - Return cached values instead of error codes on failures - Implement unified response validation functions - Add cache return macros for consistent error handling - Maintain backward compatibility while improving stability This change ensures WSJT-X and similar applications continue working even when temporary communication issues occur with GUOHETEC radios. Fixes: WSJT-X compatibility issues with PMR-171 and Q900 drivers diff --git a/rigs/guohetec/guohetec.c b/rigs/guohetec/guohetec.c index 49b1a1a30..414bc42ae 100644 --- a/rigs/guohetec/guohetec.c +++ b/rigs/guohetec/guohetec.c @@ -96,7 +96,153 @@ uint16_t CRC16Check(const unsigned char *buf, int len) return data; } - + +// Common response validation functions + +/** + * Read rig response with validation + * @param rig RIG structure + * @param reply Reply buffer + * @param reply_size Size of reply buffer + * @param func_name Function name for debug messages + * @return 0 on success, -1 on error + */ +int read_rig_response(RIG *rig, unsigned char *reply, int reply_size, + const char *func_name) +{ + hamlib_port_t *rp = RIGPORT(rig); + int ret; + + // Read header + ret = read_block(rp, reply, 5); + if (ret < 0) { + rig_debug(RIG_DEBUG_ERR, "%s: Failed to read header, using cached values\n", func_name); + return -1; + } + + // Validate data length + if (reply[4] == 0 || reply[4] > reply_size - 5) { + rig_debug(RIG_DEBUG_ERR, "%s: Invalid data length %d, using cached values\n", func_name, reply[4]); + return -1; + } + + // Read data section + ret = read_block(rp, &reply[5], reply[4]); + if (ret < 0) { + rig_debug(RIG_DEBUG_ERR, "%s: Failed to read data, using cached values\n", func_name); + return -1; + } + + // Validate response length matches expected + if (ret != reply[4]) { + rig_debug(RIG_DEBUG_ERR, "%s: Data read mismatch: expected %d, got %d, using cached values\n", + func_name, reply[4], ret); + return -1; + } + + return 0; +} + +/** + * Validate basic rig response + * @param rig RIG structure + * @param reply Reply buffer + * @param reply_size Size of reply buffer + * @param func_name Function name for debug messages + * @return 0 on success, -1 on error + */ +int validate_rig_response(RIG *rig, unsigned char *reply, int reply_size, + const char *func_name) +{ + // Validate packet header + VALIDATE_PACKET_HEADER(reply, func_name); + + // Validate data length + VALIDATE_DATA_LENGTH(reply, reply_size, func_name); + + return 0; +} + +/** + * Validate frequency response with CRC check + * @param rig RIG structure + * @param reply Reply buffer + * @param reply_size Size of reply buffer + * @param func_name Function name for debug messages + * @return 0 on success, -1 on error + */ +int validate_freq_response(RIG *rig, unsigned char *reply, int reply_size, + const char *func_name) +{ + // Basic validation + if (validate_rig_response(rig, reply, reply_size, func_name) < 0) { + return -1; + } + + // Validate buffer boundaries for CRC + int expected_total_length = 5 + reply[4] + 2; // header(5) + data_length + CRC(2) + if (expected_total_length > reply_size) { + rig_debug(RIG_DEBUG_ERR, "%s: Response too large for buffer: %d > %d, using cached values\n", + func_name, expected_total_length, reply_size); + return -1; + } + + // CRC check + uint16_t recv_crc = (reply[31] << 8) | reply[32]; // Last 2 bytes are CRC + uint16_t calc_crc = CRC16Check(&reply[4], 27); + if (recv_crc != calc_crc) { + rig_debug(RIG_DEBUG_ERR, "%s: CRC check failed (received: %04X, calculated: %04X), using cached values\n", + func_name, recv_crc, calc_crc); + return -1; + } + + // Validate frequency field offset + int freq_b_offset = 13; // VFOB frequency starting position + if (freq_b_offset + 3 >= expected_total_length - 2) { // -2 for CRC + rig_debug(RIG_DEBUG_ERR, "%s: Frequency field offset out of bounds, using cached values\n", func_name); + return -1; + } + + return 0; +} + +/** + * Validate mode response with bounds checking + * @param rig RIG structure + * @pa... [truncated message content] |