diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 0cc4d34..fc9ba53 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -96,7 +96,7 @@ jobs: elif [ "$RUNNER_OS" == "macOS" ]; then # just to simplify I use homebrew but # we can use macports (latest direwolf is already available as port) - brew install portaudio hamlib gpsd + brew install portaudio hamlib gpsd hidapi elif [ "$RUNNER_OS" == "Windows" ]; then # add the folder to PATH echo "C:\msys64\mingw32\bin" >> $GITHUB_PATH diff --git a/CMakeLists.txt b/CMakeLists.txt index 58fcb09..966fbaf 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -350,6 +350,17 @@ elseif (HAVE_SNDIO) set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -DUSE_SNDIO") endif() +elseif (APPLE) + find_package(Portaudio REQUIRED) + if(PORTAUDIO_FOUND) + set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -DUSE_PORTAUDIO") + endif() + + find_package(hidapi REQUIRED) + if(HIDAPI_FOUND) + set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -DUSE_CM108") + endif() + elseif (NOT WIN32 AND NOT CYGWIN) find_package(Portaudio REQUIRED) if(PORTAUDIO_FOUND) @@ -375,7 +386,10 @@ add_subdirectory(data) # external libraries add_subdirectory(${CUSTOM_GEOTRANZ_DIR}) add_subdirectory(${CUSTOM_REGEX_DIR}) -add_subdirectory(${CUSTOM_HIDAPI_DIR}) +if(NOT APPLE) + # Mac builds use the hidapi library, not custom local files + add_subdirectory(${CUSTOM_HIDAPI_DIR}) +endif() add_subdirectory(${CUSTOM_MISC_DIR}) # direwolf source code and utilities diff --git a/README.md b/README.md index 3006a1e..f8de589 100644 --- a/README.md +++ b/README.md @@ -208,13 +208,43 @@ Results will vary depending on your hardware platform and operating system versi sudo yum install direwolf -### Macintosh OS X ### +### Macintosh macOS - Using Homebrew ### -Read the **User Guide** in the [**doc** directory](https://github.com/wb2osz/direwolf/tree/master/doc). It is more complicated than Linux. +The following instructions have been verified on macOS Ventura 13.6 (M2) and macOS High Sierra 10.13.6 (Intel). + +First make sure that you have the following tools installed on your Mac: + +- [Xcode or Xcode Command Line Tools](https://developer.apple.com/xcode/resources/) +- [Homebrew](https://brew.sh/) + +You will need to install the following packages using Homebrew: + + brew install cmake + brew install portaudio + brew install hidapi + +Then follow the same instructions as above for the Linux `git clone` build: + + cd ~ + git clone https://www.github.com/wb2osz/direwolf + cd direwolf + git checkout dev + mkdir build && cd build + cmake .. + make -j4 + sudo make install + make install-conf + +This gives you the latest development version. Leave out the "git checkout dev" to get the most recent stable release. + +For more information, see the ***User Guide*** in the [**doc** directory](https://github.com/wb2osz/direwolf/tree/master/doc). If you have problems, post them to the [Dire Wolf packet TNC](https://groups.io/g/direwolf) discussion group. -You can also install a pre-built version from Mac Ports. Keeping this up to date depends on volunteers who perform the packaging. This version could lag behind development. + +### Macintosh macOS - Prebuilt version ### + +You can also install a pre-built version from MacPorts. Keeping this up to date depends on volunteers who perform the packaging. This version could lag behind development. sudo port install direwolf diff --git a/cmake/modules/Findhidapi.cmake b/cmake/modules/Findhidapi.cmake new file mode 100644 index 0000000..163c8c2 --- /dev/null +++ b/cmake/modules/Findhidapi.cmake @@ -0,0 +1,44 @@ +# - Try to find hidapi +# +# HIDAPI_FOUND - system has hidapi +# HIDAPI_LIBRARIES - location of the library for hidapi +# HIDAPI_INCLUDE_DIRS - location of the include files for hidapi + +set(HIDAPI_ROOT_DIR + "${HIDAPI_ROOT_DIR}" + CACHE + PATH + "Directory to search for hidapi") + +# no need to check pkg-config + +find_path(HIDAPI_INCLUDE_DIRS + NAMES + hidapi.h + PATHS + /usr/local/include + /usr/include + /opt/local/include + HINTS + ${HIDAPI_ROOT_DIR} + PATH_SUFFIXES + hidapi + ) + +find_library(HIDAPI_LIBRARIES + NAMES + hidapi + PATHS + /usr/local/lib + /usr/lib + /usr/lib64 + /opt/local/lib + HINTS + ${HIDAPI_ROOT_DIR} + ) + + +include(FindPackageHandleStandardArgs) +find_package_handle_standard_args(HIDAPI DEFAULT_MSG HIDAPI_INCLUDE_DIRS HIDAPI_LIBRARIES) + +mark_as_advanced(HIDAPI_INCLUDE_DIRS HIDAPI_LIBRARIES) diff --git a/conf/generic.conf b/conf/generic.conf index 4fb63f6..0dff085 100644 --- a/conf/generic.conf +++ b/conf/generic.conf @@ -277,20 +277,14 @@ %C%# https://github.com/wb2osz/direwolf-doc/blob/main/Radio-Interface-Guide.pdf %C%# goes into detail about the various options. %C% -%L%# If using a C-Media CM108/CM119 or similar USB Audio Adapter, -%L%# you can use a GPIO pin for PTT control. This is very convenient -%L%# because a single USB connection is used for both audio and PTT. -%L%# Example: -%L% -%L%#PTT CM108 -%L% -%W%# If using a C-Media CM108/CM119 or similar USB Audio Adapter, -%W%# you can use a GPIO pin for PTT control. This is very convenient -%W%# because a single USB connection is used for both audio and PTT. -%W%# Example: -%W% -%W%#PTT CM108 -%W%%C%# +%C%# If using a C-Media CM108/CM119 or similar USB Audio Adapter, +%C%# you can use a GPIO pin for PTT control. This is very convenient +%C%# because a single USB connection is used for both audio and PTT. +%C%# Example: +%C% +%C%#PTT CM108 +%C% +%C%# %C%# The transmitter Push to Talk (PTT) control can be wired to a serial port %C%# with a suitable interface circuit. DON'T connect it directly! %C%# diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index f376b7d..44d1782 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -11,15 +11,21 @@ include_directories( ${SNDIO_INCLUDE_DIRS} ${CUSTOM_GEOTRANZ_DIR} ${GPIOD_INCLUDE_DIRS} - ${CUSTOM_HIDAPI_DIR} ) if(WIN32 OR CYGWIN) include_directories( + ${CUSTOM_HIDAPI_DIR} ${CUSTOM_REGEX_DIR} ) endif() +if(APPLE) + include_directories( + ${HIDAPI_INCLUDE_DIRS} + ) +endif() + # direwolf list(APPEND direwolf_SOURCES @@ -134,6 +140,7 @@ if(LINUX) else() # macOS freebsd list(APPEND direwolf_SOURCES audio_portaudio.c + cm108.c ) if(USE_MACOS_DNSSD) list(APPEND direwolf_SOURCES @@ -475,10 +482,11 @@ endif() # List USB audio adapters than can use GPIO for PTT. # Originally for Linux only (using udev). -# Version 1.7 adds it for Windows. Needs hidapi library. +# Version 1.7 adds it for Windows. Uses local hidapi code. +# Post-1.7 adds it for Mac. Uses hidapi library. # cm108 -if(UDEV_FOUND OR WIN32 OR CYGWIN) +if(UDEV_FOUND OR WIN32 OR CYGWIN OR HIDAPI_FOUND) list(APPEND cm108_SOURCES cm108.c textcolor.c @@ -502,6 +510,12 @@ if(UDEV_FOUND OR WIN32 OR CYGWIN) ) endif() + if (APPLE) + target_link_libraries(cm108 + ${HIDAPI_LIBRARIES} + ) + endif() + if (WIN32 OR CYGWIN) target_link_libraries(cm108 ${HIDAPI_LIBRARIES} @@ -574,6 +588,6 @@ install(TARGETS ttcalc DESTINATION ${INSTALL_BIN_DIR}) install(TARGETS kissutil DESTINATION ${INSTALL_BIN_DIR}) install(TARGETS tnctest DESTINATION ${INSTALL_BIN_DIR}) install(TARGETS appserver DESTINATION ${INSTALL_BIN_DIR}) -if(UDEV_FOUND OR WIN32 OR CYGWIN) +if(UDEV_FOUND OR WIN32 OR CYGWIN OR HIDAPI_FOUND) install(TARGETS cm108 DESTINATION ${INSTALL_BIN_DIR}) endif() diff --git a/src/cm108.c b/src/cm108.c index 787e7bb..d6791c0 100644 --- a/src/cm108.c +++ b/src/cm108.c @@ -138,6 +138,8 @@ int main (void) #if __WIN32__ #include #include "hidapi.h" +#elif __APPLE__ +#include "hidapi.h" #else #include #include @@ -240,7 +242,7 @@ static int cm108_write (char *name, int iomask, int iodata); // Used to process regular expression matching results. -#ifndef __WIN32__ +#if !defined(__WIN32__) && !defined(__APPLE__) static void substr_se (char *dest, const char *src, int start, int endp1) { @@ -318,7 +320,7 @@ static void usage(void) dw_printf ("Usage: cm108 [ device-path [ gpio-num ] ]\n"); dw_printf ("\n"); dw_printf ("With no command line arguments, this will produce a list of\n"); -#if __WIN32__ +#if __WIN32__ || __APPLE__ dw_printf ("Human Interface Devices (HID) and indicate which ones can be\n"); dw_printf ("used for GPIO PTT.\n"); #else @@ -376,11 +378,11 @@ int main (int argc, char **argv) num_things = cm108_inventory (things, MAXX_THINGS); -#if __WIN32__ +#if __WIN32__ || __APPLE__ -///////////////////////////////////////////////////// -// Windows - Remove the sound related columns for now. -///////////////////////////////////////////////////// +//////////////////////////////////////////////////////////// +// Windows & Mac - Remove the sound related columns for now. +//////////////////////////////////////////////////////////// dw_printf (" VID PID %-*s %-*s" "\n", (int)sizeof(things[0].product), "Product", @@ -540,7 +542,7 @@ int cm108_inventory (struct thing_s *things, int max_things) int num_things = 0; memset (things, 0, sizeof(struct thing_s) * max_things); -#if __WIN32__ +#if __WIN32__ || __APPLE__ struct hid_device_info *devs, *cur_dev; @@ -780,7 +782,7 @@ void cm108_find_ptt (char *output_audio_device, char *ptt_device, int ptt_devic // Possible improvement: Skip if inventory already taken. num_things = cm108_inventory (things, MAXX_THINGS); -#if __WIN32__ +#if __WIN32__ || __APPLE__ // FIXME - This is just a half baked implementation. // I have not been able to figure out how to find the connection // between the audio device and HID in the same package. @@ -935,7 +937,7 @@ int cm108_set_gpio_pin (char *name, int num, int state) static int cm108_write (char *name, int iomask, int iodata) { -#if __WIN32__ +#if __WIN32__ || __APPLE__ //text_color_set(DW_COLOR_DEBUG); //dw_printf ("TEMP DEBUG cm108_write: %s %d %d\n", name, iomask, iodata);