# Some common URLs
FS_LIBS_URL:=https://files.freeswitch.org/downloads/libs
-FS_SPHINX_URL:=@SF/cmusphinx
+FS_POCKETSPHINX_URL:=@SF/cmusphinx/pocketsphinx
+FS_SPHINX_URL:=@SF/cmusphinx/sphinxbase
# mod_event_zmq
FS_ZEROMQ_FILE:=zeromq-2.1.9.tar.gz
FS_ZEROMQ_URL:=http://download.zeromq.org
# mod_pocketsphinx
-FS_POCKETSPHINX_FILE:=pocketsphinx-0.8.tar.gz
-FS_POCKETSPHINX_HASH:=874c4c083d91c8ff26a2aec250b689e537912ff728923c141c4dac48662cce7a
+FS_POCKETSPHINX_FILE:=pocketsphinx-5prealpha.tar.gz
+FS_POCKETSPHINX_HASH:=ef5bb5547e2712bdf571f256490ef42a47962033892efd9d7df8eed7fe573ed9
-FS_SPHINXBASE_FILE:=sphinxbase-0.8.tar.gz
-FS_SPHINXBASE_HASH:=55708944872bab1015b8ae07b379bf463764f469163a8fd114cbb16c5e486ca8
+FS_SPHINXBASE_FILE:=sphinxbase-5prealpha.tar.gz
+FS_SPHINXBASE_HASH:=f72bdb59e50b558bed47cc2105777200d2b246a0f328e913de16a9b22f9a246f
FS_SPHINXMODEL_FILE:=communicator_semi_6000_20080321.tar.gz
FS_SPHINXMODEL_HASH:=dbb5e9fb85000a7cb97d6958a3ef8d77532dc55fc730ac6979705e8645cb0c18
endif
ifneq ($(CONFIG_PACKAGE_freeswitch-mod-pocketsphinx)$(CONFIG_PACKAGE_freeswitch-misc-grammar),)
-$(eval $(call Download/files,pocketsphinx,$(FS_POCKETSPHINX_FILE),$(FS_SPHINX_URL),$(FS_POCKETSPHINX_HASH)))
-$(eval $(call Download/files,sphinxbase,$(FS_SPHINXBASE_FILE),$(FS_SPHINX_URL),$(FS_SPHINXBASE_HASH)))
+TARGET_CFLAGS += -DPOCKETSPHINX_MAJOR_VERSION=5
+
+$(eval $(call Download/files,pocketsphinx,$(FS_POCKETSPHINX_FILE),$(FS_POCKETSPHINX_URL)/5prealpha,$(FS_POCKETSPHINX_HASH)))
+$(eval $(call Download/files,sphinxbase,$(FS_SPHINXBASE_FILE),$(FS_SPHINX_URL)/5prealpha,$(FS_SPHINXBASE_HASH)))
$(eval $(call Download/files,communicator,$(FS_SPHINXMODEL_FILE),$(FS_LIBS_URL),$(FS_SPHINXMODEL_HASH)))
endif
--- /dev/null
+From 76458fafc5a9cd0eebe94455ed39f41eac986c67 Mon Sep 17 00:00:00 2001
+Date: Tue, 4 Feb 2025 15:54:26 -0500
+Subject: [PATCH] [mod_spandsp] Fix compilation against >=2023/06/02 spandsp
+
+* [mod_spandsp] Fix compilation against >=2023/06/02 spandsp
+
+spandsp, beginning with commit d9681c37 and coinciding with the
+SPANDSP_RELEASE_DATE of 20230620, introduced the following changes to
+its V.18 protocol API, which FreeSWITCH is not able to compile against:
+- Certain V.18 constants were renamed.
+- The v18_init function now requires passing a third function, handling
+the V.18 modem's status changes.
+
+This patch allows FreeSWITCH to build against current versions of
+spandsp by:
+- Using the new V.18 constant names.
+- Implementing a simple status reporter callback function and passing it
+as the third function to v18_init.
+
+Additionally, it retains backward compatibility with prior versions of
+spandp through #if conditions checking the value of
+SPANDSP_RELEASE_DATE.
+
+
+* [mod_spandsp] Pass session to handle_v18_status.
+
+---------
+
+---
+ .../applications/mod_spandsp/mod_spandsp.c | 1 -
+ .../applications/mod_spandsp/mod_spandsp.h | 6 ++++
+ .../mod_spandsp/mod_spandsp_dsp.c | 32 ++++++++++++++++---
+ 3 files changed, 34 insertions(+), 5 deletions(-)
+
+--- a/src/mod/applications/mod_spandsp/mod_spandsp.c
++++ b/src/mod/applications/mod_spandsp/mod_spandsp.c
+@@ -37,7 +37,6 @@
+
+
+ #include "mod_spandsp.h"
+-#include <spandsp/version.h>
+ #include "mod_spandsp_modem.h"
+
+ /* **************************************************************************
+--- a/src/mod/applications/mod_spandsp/mod_spandsp.h
++++ b/src/mod/applications/mod_spandsp/mod_spandsp.h
+@@ -58,6 +58,12 @@ typedef int zap_socket_t;
+ #define SPANDSP_EVENT_TXFAXNEGOCIATERESULT "spandsp::txfaxnegociateresult"
+ #define SPANDSP_EVENT_RXFAXNEGOCIATERESULT "spandsp::rxfaxnegociateresult"
+
++#include <spandsp/version.h>
++
++#if SPANDSP_RELEASE_DATE < 20230620
++#define V18_MODE_WEITBRECHT_5BIT_4545 V18_MODE_5BIT_4545
++#define V18_MODE_WEITBRECHT_5BIT_50 V18_MODE_5BIT_50
++#endif
+
+
+ /* The global stuff */
+--- a/src/mod/applications/mod_spandsp/mod_spandsp_dsp.c
++++ b/src/mod/applications/mod_spandsp/mod_spandsp_dsp.c
+@@ -152,17 +152,27 @@ static void put_text_msg(void *user_data
+
+ }
+
++#if SPANDSP_RELEASE_DATE >= 20230620
++static void handle_v18_status(void *user_data, int status)
++{
++ switch_core_session_t *session = (switch_core_session_t *) user_data;
++ switch_channel_t *channel = switch_core_session_get_channel(session);
++
++ switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_INFO, "%s detected V.18 modem: %s\n", switch_channel_get_name(channel), v18_status_to_str(status));
++}
++#endif
++
+ static int get_v18_mode(switch_core_session_t *session)
+ {
+ switch_channel_t *channel = switch_core_session_get_channel(session);
+ const char *var;
+- int r = V18_MODE_5BIT_4545;
++ int r = V18_MODE_WEITBRECHT_5BIT_4545;
+
+ if ((var = switch_channel_get_variable(channel, "v18_mode"))) {
+ if (!strcasecmp(var, "5BIT_45") || !strcasecmp(var, "baudot")) {
+- r = V18_MODE_5BIT_4545;
++ r = V18_MODE_WEITBRECHT_5BIT_4545;
+ } else if (!strcasecmp(var, "5BIT_50")) {
+- r = V18_MODE_5BIT_50;
++ r = V18_MODE_WEITBRECHT_5BIT_50;
+ } else if (!strcasecmp(var, "DTMF")) {
+ r = V18_MODE_DTMF;
+ } else if (!strcasecmp(var, "EDT")) {
+@@ -213,8 +223,11 @@ switch_status_t spandsp_tdd_send_session
+ return SWITCH_STATUS_FALSE;
+ }
+
++#if SPANDSP_RELEASE_DATE >= 20230620
++ tdd_state = v18_init(NULL, TRUE, get_v18_mode(session), V18_AUTOMODING_GLOBAL, put_text_msg, NULL, handle_v18_status, session);
++#else
+ tdd_state = v18_init(NULL, TRUE, get_v18_mode(session), V18_AUTOMODING_GLOBAL, put_text_msg, NULL);
+-
++#endif
+
+ v18_put(tdd_state, text, -1);
+
+@@ -260,7 +273,13 @@ switch_status_t spandsp_tdd_encode_sessi
+ }
+
+ pvt->session = session;
++
++#if SPANDSP_RELEASE_DATE >= 20230620
++ pvt->tdd_state = v18_init(NULL, TRUE, get_v18_mode(session), V18_AUTOMODING_GLOBAL, put_text_msg, NULL, handle_v18_status, session);
++#else
+ pvt->tdd_state = v18_init(NULL, TRUE, get_v18_mode(session), V18_AUTOMODING_GLOBAL, put_text_msg, NULL);
++#endif
++
+ pvt->head_lead = TDD_LEAD;
+
+ v18_put(pvt->tdd_state, text, -1);
+@@ -338,7 +357,12 @@ switch_status_t spandsp_tdd_decode_sessi
+ }
+
+ pvt->session = session;
++
++#if SPANDSP_RELEASE_DATE >= 20230620
++ pvt->tdd_state = v18_init(NULL, FALSE, get_v18_mode(session), V18_AUTOMODING_GLOBAL, put_text_msg, pvt, handle_v18_status, session);
++#else
+ pvt->tdd_state = v18_init(NULL, FALSE, get_v18_mode(session), V18_AUTOMODING_GLOBAL, put_text_msg, pvt);
++#endif
+
+ if ((status = switch_core_media_bug_add(session, "spandsp_tdd_decode", NULL,
+ tdd_decode_callback, pvt, 0, SMBF_READ_REPLACE | SMBF_NO_PAUSE, &bug)) != SWITCH_STATUS_SUCCESS) {
--- /dev/null
+From 2e825dd3eccc782685f7bb8d50b48eded5c62937 Mon Sep 17 00:00:00 2001
+Date: Tue, 15 Jul 2025 13:31:28 +0300
+Subject: [PATCH] [mod_http_cache] Fix error: curl_easy_setopt expects a long
+ argument [-Werror=attribute-warning]
+
+---
+ src/mod/applications/mod_http_cache/mod_http_cache.c | 8 ++++----
+ 1 file changed, 4 insertions(+), 4 deletions(-)
+
+--- a/src/mod/applications/mod_http_cache/mod_http_cache.c
++++ b/src/mod/applications/mod_http_cache/mod_http_cache.c
+@@ -1131,10 +1131,10 @@ static switch_status_t http_get(url_cach
+ #else
+ if ((get_data.fd = open(get_data.url->filename, O_CREAT | O_RDWR | O_TRUNC, S_IRUSR | S_IWUSR)) > -1) {
+ #endif
+- switch_curl_easy_setopt(curl_handle, CURLOPT_FOLLOWLOCATION, 1);
+- switch_curl_easy_setopt(curl_handle, CURLOPT_MAXREDIRS, 10);
+- switch_curl_easy_setopt(curl_handle, CURLOPT_FAILONERROR, 1);
+- switch_curl_easy_setopt(curl_handle, CURLOPT_NOSIGNAL, 1);
++ switch_curl_easy_setopt(curl_handle, CURLOPT_FOLLOWLOCATION, (long)1);
++ switch_curl_easy_setopt(curl_handle, CURLOPT_MAXREDIRS, (long)10);
++ switch_curl_easy_setopt(curl_handle, CURLOPT_FAILONERROR, (long)1);
++ switch_curl_easy_setopt(curl_handle, CURLOPT_NOSIGNAL, (long)1);
+ if (headers) {
+ switch_curl_easy_setopt(curl_handle, CURLOPT_HTTPHEADER, headers);
+ }
--- /dev/null
+From d0993872c793edf1b78bd79e3cd9a5bb2309d214 Mon Sep 17 00:00:00 2001
+Date: Sun, 13 Jul 2025 01:38:29 +0300
+Subject: [PATCH] [mod_pocketsphinx] Use system libraries when possible
+
+---
+ configure.ac | 20 +++++++++++++
+ debian/control-modules | 1 +
+ src/mod/asr_tts/mod_pocketsphinx/Makefile.am | 14 +++++++--
+ .../mod_pocketsphinx.2017.vcxproj | 9 +++---
+ .../mod_pocketsphinx/mod_pocketsphinx.c | 29 +++++++++++++++++++
+ w32/pocketsphinx-version.props | 20 +++++++++++++
+ w32/pocketsphinx.props | 18 ++++++++++++
+ 7 files changed, 104 insertions(+), 7 deletions(-)
+ create mode 100644 w32/pocketsphinx-version.props
+ create mode 100644 w32/pocketsphinx.props
+
+--- a/src/mod/asr_tts/mod_pocketsphinx/mod_pocketsphinx.c
++++ b/src/mod/asr_tts/mod_pocketsphinx/mod_pocketsphinx.c
+@@ -203,7 +203,12 @@ static switch_status_t pocketsphinx_asr_
+ }
+ switch_mutex_unlock(ps->flag_mutex);
+
++#if POCKETSPHINX_MAJOR_VERSION < 1
+ ps_start_utt(ps->ps, NULL);
++#else
++ ps_start_utt(ps->ps);
++#endif
++
+ ps->silence_time = switch_micro_time_now();
+ switch_clear_flag(ps, PSFLAG_START_OF_SPEECH);
+ switch_clear_flag(ps, PSFLAG_NOINPUT_TIMEOUT);
+@@ -338,22 +343,38 @@ static switch_status_t pocketsphinx_asr_
+ char const *hyp;
+
+ switch_mutex_lock(ps->flag_mutex);
++#if POCKETSPHINX_MAJOR_VERSION < 1
+ if ((hyp = ps_get_hyp(ps->ps, &ps->score, &ps->uttid))) {
++#else
++ if ((hyp = ps_get_hyp(ps->ps, &ps->score))) {
++#endif
+ if (!zstr(hyp)) {
+ ps_end_utt(ps->ps);
+ switch_clear_flag(ps, PSFLAG_READY);
++#if POCKETSPHINX_MAJOR_VERSION < 1
+ if ((hyp = ps_get_hyp(ps->ps, &ps->score, &ps->uttid))) {
++#else
++ if ((hyp = ps_get_hyp(ps->ps, &ps->score))) {
++#endif
+ if (zstr(hyp)) {
+ if (!switch_test_flag(ps, PSFLAG_SPEECH_TIMEOUT)) {
+ switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "Lost the text, never mind....\n");
++#if POCKETSPHINX_MAJOR_VERSION < 1
+ ps_start_utt(ps->ps, NULL);
++#else
++ ps_start_utt(ps->ps);
++#endif
+ switch_set_flag(ps, PSFLAG_READY);
+ }
+ } else {
+ /* get match and confidence */
+ int32_t conf;
+
++#if POCKETSPHINX_MAJOR_VERSION < 1
+ conf = ps_get_prob(ps->ps, &ps->uttid);
++#else
++ conf = ps_get_prob(ps->ps);
++#endif
+
+ ps->confidence = (conf + 20000) / 200;
+
+@@ -427,7 +448,11 @@ static switch_status_t pocketsphinx_asr_
+ if (!switch_test_flag(ps, PSFLAG_READY)) {
+ switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Manually Resuming\n");
+
++#if POCKETSPHINX_MAJOR_VERSION < 1
+ if (ps_start_utt(ps->ps, NULL)) {
++#else
++ if (ps_start_utt(ps->ps)) {
++#endif
+ status = SWITCH_STATUS_GENERR;
+ } else {
+ switch_set_flag(ps, PSFLAG_READY);
+@@ -474,7 +499,11 @@ static switch_status_t pocketsphinx_asr_
+ switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Auto Resuming\n");
+ switch_set_flag(ps, PSFLAG_READY);
+
++#if POCKETSPHINX_MAJOR_VERSION < 1
+ ps_start_utt(ps->ps, NULL);
++#else
++ ps_start_utt(ps->ps);
++#endif
+ }
+
+ status = SWITCH_STATUS_SUCCESS;
--- /dev/null
+From 64a2ce52515821c27757e19a44a970ace3bf1c78 Mon Sep 17 00:00:00 2001
+Date: Fri, 21 Nov 2025 19:46:16 +0100
+Subject: [PATCH] libs: iksemel: fix compilation error for iks_stack_delete
+
+Fix compilation error
+
+hash.c: In function 'hash_delete':
+hash.c:141:28: error: passing argument 1 of 'iks_stack_delete' from incompatible pointer type [-Wincompatible-pointer-types]
+ 141 | iks_stack_delete (h->s);
+ | ~^~~
+ | |
+ | ikstack * {aka struct ikstack_struct *}
+In file included from hash.c:8:
+../include/iksemel.h:27:34: note: expected 'ikstack **' {aka 'struct ikstack_struct **'} but argument is of type 'ikstack *' {aka 'struct ikstack_struct *'}
+ 27 | void iks_stack_delete (ikstack **sp);
+ | ~~~~~~~~~~^~
+
+---
+ libs/iksemel/tools/hash.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/libs/iksemel/tools/hash.c
++++ b/libs/iksemel/tools/hash.c
+@@ -138,7 +138,7 @@ hash_print (hash *h, char *title_fmt, ch
+ void
+ hash_delete (hash *h)
+ {
+- iks_stack_delete (h->s);
++ iks_stack_delete (&h->s);
+ free (h->table);
+ free (h);
+ }
--- /dev/null
+From 907612ee1c609b1e1498d2d2cd1f5f462d3e5c60 Mon Sep 17 00:00:00 2001
+Date: Wed, 9 Jul 2025 22:43:21 +0300
+Subject: [PATCH] [mod_xml_rpc] Fix incompatible pointer type
+
+---
+ src/mod/xml_int/mod_xml_rpc/mod_xml_rpc.c | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+--- a/src/mod/xml_int/mod_xml_rpc/mod_xml_rpc.c
++++ b/src/mod/xml_int/mod_xml_rpc/mod_xml_rpc.c
+@@ -321,7 +321,7 @@ static abyss_bool user_attributes(const
+ static abyss_bool is_authorized(const TSession * r, const char *command)
+ {
+ char *user = NULL, *domain_name = NULL;
+- char *allowed_commands = NULL;
++ const char *allowed_commands = NULL;
+ char *dp;
+ char *dup = NULL;
+ char *argv[256] = { 0 };
+@@ -922,7 +922,7 @@ abyss_bool handler_hook(TSession * r)
+ if (len > 0) {
+ int succeeded = TRUE;
+ char *qp = qbuf;
+- char *readError;
++ const char *readError;
+
+ do {
+ int blen = r->connP->buffersize - r->connP->bufferpos;
--- /dev/null
+From 3b9c1443f42085dea823a6d50acc8613ada29605 Mon Sep 17 00:00:00 2001
+Date: Fri, 21 Nov 2025 17:46:00 +0100
+Subject: [PATCH] [mod_pocketsphinx] Use sphinxbase-5prealpha
+
+use latest version of sphinxbase 5prealpha.
+
+---
+ debian/util.sh | 2 +-
+ src/mod/asr_tts/mod_pocketsphinx/Makefile.am | 3 +-
+ 2 files changed, 5 insertions(+), 5 deletions(-)
+
+--- a/debian/util.sh
++++ b/debian/util.sh
+@@ -100,8 +100,8 @@ getlib () {
+
+ getlibs () {
+ # get pinned libraries
+- getlib http://files.freeswitch.org/downloads/libs/sphinxbase-0.8.tar.gz
+- getlib http://files.freeswitch.org/downloads/libs/pocketsphinx-0.8.tar.gz
++ getlib http://files.freeswitch.org/downloads/libs/sphinxbase-5prealpha.tar.gz
++ getlib http://files.freeswitch.org/downloads/libs/pocketsphinx-5prealpha.tar.gz
+ getlib http://files.freeswitch.org/downloads/libs/communicator_semi_6000_20080321.tar.gz
+ #getlib http://download.zeromq.org/zeromq-2.1.9.tar.gz \
+ # || getlib http://download.zeromq.org/historic/zeromq-2.1.9.tar.gz
+--- a/src/mod/asr_tts/mod_pocketsphinx/Makefile.am
++++ b/src/mod/asr_tts/mod_pocketsphinx/Makefile.am
+@@ -1,10 +1,10 @@
+ include $(top_srcdir)/build/modmake.rulesam
+ MODNAME=mod_pocketsphinx
+
+-SPHINXBASE=sphinxbase-0.8
++SPHINXBASE=sphinxbase-5prealpha
+ SPHINXBASE_DIR=$(switch_srcdir)/libs/$(SPHINXBASE)
+ SPHINXBASE_BUILDDIR=$(switch_builddir)/libs/$(SPHINXBASE)
+-POCKETSPHINX=pocketsphinx-0.8
++POCKETSPHINX=pocketsphinx-5prealpha
+ POCKETSPHINX_DIR=$(switch_srcdir)/libs/$(POCKETSPHINX)
+ POCKETSPHINX_BUILDDIR=$(switch_builddir)/libs/$(POCKETSPHINX)
+ SPHINXBASE_LA=$(SPHINXBASE_BUILDDIR)/src/libsphinxbase/libsphinxbase.la
+@@ -64,7 +64,7 @@ $(DESTDIR)$(grammardir)/model/communicat
+ cp -rp $(switch_srcdir)/libs/Communicator_semi_40.cd_semi_6000/* $(DESTDIR)$(grammardir)/model/communicator
+
+ dictionary:
+- @install -m0644 $(POCKETSPHINX_DIR)/model/lm/en_US/cmu07a.dic $(DESTDIR)$(grammardir)/default.dic
++ @install -m0644 $(POCKETSPHINX_DIR)/model/en-us/cmudict-en-us.dict $(DESTDIR)$(grammardir)/default.dic
+
+ install-data-local: $(DESTDIR)$(grammardir)/model $(DESTDIR)$(grammardir)/model/communicator dictionary
+