Skip to content

Commit ade6d0e

Browse files
committed
Issue 590 - PTT with GPIOD was broken by Debian 13 Trixie.
1 parent d51c16b commit ade6d0e

File tree

2 files changed

+82
-42
lines changed

2 files changed

+82
-42
lines changed

src/config.c

Lines changed: 71 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -683,7 +683,8 @@ static char *split (char *string, int rest_of_line)
683683
*
684684
* Purpose: Read configuration file when application starts up.
685685
*
686-
* Inputs: fname - Name of configuration file.
686+
* Inputs: fname - Name of configuration file. Either default of direwolf.conf
687+
* or specified by user with -c command line option.
687688
*
688689
* Outputs: p_audio_config - Radio channel parameters stored here.
689690
*
@@ -727,7 +728,6 @@ void config_init (char *fname, struct audio_s *p_audio_config,
727728
struct misc_config_s *p_misc_config)
728729
{
729730
FILE *fp;
730-
char filepath[128];
731731
char stuff[MAXCMDLEN];
732732
int line;
733733
int channel;
@@ -942,52 +942,63 @@ void config_init (char *fname, struct audio_s *p_audio_config,
942942
/* on the other end. */
943943
p_misc_config->noxid_count = 0;
944944

945+
channel = 0;
946+
adevice = 0;
947+
945948
/*
946949
* Try to extract options from a file.
947950
*
948-
* Windows: File must be in current working directory.
951+
* First look in cwd, then try home dir.
949952
*
950-
* Linux: Search current directory then home directory.
951-
*
952-
* Future possibility - Could also search home directory
953-
* for Windows by combinting two variables:
953+
* Try using this to get Windows home directory:
954+
* USERPROFILE=C:\Users\John
955+
* If that fails, we might combine two variables:
954956
* HOMEDRIVE=C:
955957
* HOMEPATH=\Users\John
956-
*
957-
* It's not clear if this always points to same location:
958-
* USERPROFILE=C:\Users\John
959958
*/
960959

961960

962-
channel = 0;
963-
adevice = 0;
964-
965-
// TODO: Would be better to have a search list and loop thru it.
966-
967-
strlcpy(filepath, fname, sizeof(filepath));
968-
969-
fp = fopen (filepath, "r");
970-
971-
#ifndef __WIN32__
972-
if (fp == NULL && strcmp(fname, "direwolf.conf") == 0) {
973-
/* Failed to open the default location. Try home dir. */
974-
char *p;
975-
976-
977-
strlcpy (filepath, "", sizeof(filepath));
961+
/*
962+
* There have been cases where someone had multiple direwolf.conf files
963+
* in different places and wasted a lot of time and effort because the
964+
* wrong one was being used.
965+
*
966+
* In version 1.8, I will attempt to display the full absolute path so there
967+
* is no confusion. First look in cwd, then in home direectory.
968+
*/
969+
fp = NULL;
970+
char absfilepath[PATH_MAX];
971+
#ifdef __WIN32__
972+
if (_fullpath (absfilepath, fname, sizeof(absfilepath)) != NULL) {
973+
#else
974+
if (realpath (fname, absfilepath) != NULL) {
975+
#endif
976+
fp = fopen (absfilepath, "r");
977+
if (fp == NULL) { // Failed. Next, try home dir
978+
strlcpy (absfilepath, "", sizeof(absfilepath));
979+
#ifdef __WIN32__
980+
char *h = getenv("USERPROFILE");
981+
if (h != NULL && fname[0] != '\\' && fname[1] != ':') {
982+
strlcat (absfilepath, h, sizeof(absfilepath));
983+
strlcat (absfilepath, "\\", sizeof(absfilepath));
984+
}
985+
#else
986+
// Don't prepend home dir if absolute path given.
987+
char *h = getenv("HOME");
988+
if (h != NULL && fname[0] != '/') {
989+
strlcat (absfilepath, h, sizeof(absfilepath));
990+
strlcat (absfilepath, "/", sizeof(absfilepath));
991+
}
992+
#endif
993+
strlcat (absfilepath, fname, sizeof(absfilepath));
978994

979-
p = getenv("HOME");
980-
if (p != NULL) {
981-
strlcpy (filepath, p, sizeof(filepath));
982-
strlcat (filepath, "/direwolf.conf", sizeof(filepath));
983-
fp = fopen (filepath, "r");
995+
fp = fopen (absfilepath, "r");
984996
}
985997
}
986-
#endif
998+
987999
if (fp == NULL) {
988-
// TODO: not exactly right for all situations.
9891000
text_color_set(DW_COLOR_ERROR);
990-
dw_printf ("ERROR - Could not open configuration file %s\n", filepath);
1001+
dw_printf ("ERROR - Could not open configuration file %s in cwd or homedir.\n", fname);
9911002
dw_printf ("Try using -c command line option for alternate location.\n");
9921003
#ifndef __WIN32__
9931004
dw_printf ("A sample direwolf.conf file should be found in one of:\n");
@@ -998,7 +1009,7 @@ void config_init (char *fname, struct audio_s *p_audio_config,
9981009
exit(EXIT_FAILURE);
9991010
}
10001011

1001-
dw_printf ("\nReading config file %s\n", filepath);
1012+
dw_printf ("\nReading config file %s\n", absfilepath);
10021013

10031014
line = 0;
10041015
while (fgets(stuff, sizeof(stuff), fp) != NULL) {
@@ -1950,8 +1961,32 @@ void config_init (char *fname, struct audio_s *p_audio_config,
19501961
dw_printf ("Use the \"gpioinfo\" command to get a list of gpio chip names and corresponding I/O lines.\n");
19511962
continue;
19521963
}
1953-
strlcpy(p_audio_config->achan[channel].octrl[ot].out_gpio_name, t,
1964+
1965+
// Issue 590. Originally we used the chip name, like gpiochip3, and fed it into
1966+
// gpiod_chip_open_by_name. This function has disappeared in Debian 13 Trixie.
1967+
// We must now specify the full device path, like /dev/gpiochip3, for the only
1968+
// remaining open function gpiod_chip_open.
1969+
// We will allow the user to specify either the name or full device path.
1970+
// While we are here, also allow only the number as used by the gpiod utilities.
1971+
1972+
if (t[0] == '/') { // Looks like device path. Use as given.
1973+
strlcpy(p_audio_config->achan[channel].octrl[ot].out_gpio_name, t,
19541974
sizeof(p_audio_config->achan[channel].octrl[ot].out_gpio_name));
1975+
}
1976+
1977+
else if (isdigit(t[0])) { // or if digit, prepend "/dev/gpiochip"
1978+
strlcpy(p_audio_config->achan[channel].octrl[ot].out_gpio_name, "/dev/gpiochip",
1979+
sizeof(p_audio_config->achan[channel].octrl[ot].out_gpio_name));
1980+
strlcat(p_audio_config->achan[channel].octrl[ot].out_gpio_name, t,
1981+
sizeof(p_audio_config->achan[channel].octrl[ot].out_gpio_name));
1982+
}
1983+
1984+
else { // otherwise, prepend "/dev/" to the name
1985+
strlcpy(p_audio_config->achan[channel].octrl[ot].out_gpio_name, "/dev/",
1986+
sizeof(p_audio_config->achan[channel].octrl[ot].out_gpio_name));
1987+
strlcat(p_audio_config->achan[channel].octrl[ot].out_gpio_name, t,
1988+
sizeof(p_audio_config->achan[channel].octrl[ot].out_gpio_name));
1989+
}
19551990

19561991
t = split(NULL,0);
19571992
if (t == NULL) {

src/ptt.c

Lines changed: 11 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -653,13 +653,15 @@ void export_gpio(int ch, int ot, int invert, int direction)
653653
}
654654

655655
#if defined(USE_GPIOD)
656-
int gpiod_probe(const char *chip_name, int line_number)
656+
int gpiod_probe(const char *chip_dev_path, int line_number)
657657
{
658+
// chip_dev_path must be complete device path such as /dev/gpiochip3
659+
658660
struct gpiod_chip *chip;
659-
chip = gpiod_chip_open_by_name(chip_name);
661+
chip = gpiod_chip_open(chip_dev_path);
660662
if (chip == NULL) {
661663
text_color_set(DW_COLOR_ERROR);
662-
dw_printf ("Can't open GPIOD chip %s.\n", chip_name);
664+
dw_printf ("Can't open GPIOD chip %s.\n", chip_dev_path);
663665
return -1;
664666
}
665667

@@ -672,7 +674,7 @@ int gpiod_probe(const char *chip_name, int line_number)
672674
}
673675
if (ptt_debug_level >= 2) {
674676
text_color_set(DW_COLOR_DEBUG);
675-
dw_printf("GPIOD probe OK. Chip: %s line: %d\n", chip_name, line_number);
677+
dw_printf("GPIOD probe OK. Chip: %s line: %d\n", chip_dev_path, line_number);
676678
}
677679
return 0;
678680
}
@@ -936,8 +938,11 @@ void ptt_init (struct audio_s *audio_config_p)
936938
int rc = gpiod_probe(chip_name, line_number);
937939
if (rc < 0) {
938940
text_color_set(DW_COLOR_ERROR);
939-
dw_printf ("Disable PTT for channel %d\n", ch);
940-
audio_config_p->achan[ch].octrl[ot].ptt_method = PTT_METHOD_NONE;
941+
//No, people won't notice the error message and be confused. Just terminate.
942+
//dw_printf ("Disable PTT for channel %d\n", ch);
943+
//audio_config_p->achan[ch].octrl[ot].ptt_method = PTT_METHOD_NONE;
944+
dw_printf ("Terminating due to failed PTT on channel %d\n", ch);
945+
exit (EXIT_FAILURE);
941946
} else {
942947
// Set initial state off ptt_set will invert output signal if appropriate.
943948
ptt_set (ot, ch, 0);

0 commit comments

Comments
 (0)