diff --git a/.github/issue_template b/.github/issue_template new file mode 100644 index 000000000..2b237e22d --- /dev/null +++ b/.github/issue_template @@ -0,0 +1,16 @@ +Please make sure that the issue subject starts with `: ` + +Also make sure that the package is maintained in this repository and not in base which should be submitted at https://bugs.openwrt.org or in the LuCI repository which should be submitted at https://github.com/openwrt/luci/issues. + +Issues related to releases below 18.06 and forks are not supported or maintained and will be closed. + +# Issue template (remove lines from top till here) + +Maintainer: @\ (find it by checking history of the package Makefile) +Environment: (put here arch, model, OpenWrt version) + +Description: + +``` +Format code blocks by wrapping them with pairs of ``` +``` diff --git a/.github/pull_request_template b/.github/pull_request_template new file mode 100644 index 000000000..4bc4af61e --- /dev/null +++ b/.github/pull_request_template @@ -0,0 +1,5 @@ +Maintainer: me / @\ (find it by checking history of the package Makefile) +Compile tested: (put here arch, model, OpenWrt version) +Run tested: (put here arch, model, OpenWrt version, tests done) + +Description: diff --git a/.github/workflows/Dockerfile b/.github/workflows/Dockerfile new file mode 100644 index 000000000..fbd17fc1f --- /dev/null +++ b/.github/workflows/Dockerfile @@ -0,0 +1,6 @@ +ARG ARCH=x86-64 +FROM openwrt/rootfs:$ARCH + +ADD entrypoint.sh /entrypoint.sh + +CMD ["/entrypoint.sh"] diff --git a/.github/workflows/check-autorelease-deprecation.yml b/.github/workflows/check-autorelease-deprecation.yml new file mode 100644 index 000000000..b85b3243f --- /dev/null +++ b/.github/workflows/check-autorelease-deprecation.yml @@ -0,0 +1,91 @@ +name: Check autorelease deprecation + +on: + pull_request_target: + types: [opened, synchronize, converted_to_draft, ready_for_review, edited] + +jobs: + build: + name: Check autorelease deprecation + runs-on: ubuntu-latest + strategy: + fail-fast: false + + permissions: + pull-requests: write + + steps: + - uses: actions/checkout@v3 + with: + ref: ${{ github.event.pull_request.head.sha }} + fetch-depth: 0 + + - name: Determine branch name + run: | + BRANCH="${GITHUB_BASE_REF#refs/heads/}" + echo "Building for $BRANCH" + echo "BRANCH=$BRANCH" >> $GITHUB_ENV + + - name: Determine changed packages + run: | + RET=0 + + # only detect packages with changes + PKG_ROOTS=$(find . -name Makefile | \ + grep -v ".*/src/Makefile" | \ + sed -e 's@./\(.*\)/Makefile@\1/@') + CHANGES=$(git diff --diff-filter=d --name-only origin/$BRANCH...) + + for ROOT in $PKG_ROOTS; do + for CHANGE in $CHANGES; do + if [[ "$CHANGE" == "$ROOT"* ]]; then + if grep -q '$(AUTORELEASE)' "$ROOT/Makefile"; then + CONTAINS_AUTORELEASE+="$ROOT" + fi + break + fi + done + done + + if [ -n "$CONTAINS_AUTORELEASE" ]; then + RET=1 + cat > "$GITHUB_WORKSPACE/pr_comment.md" << EOF + Please do no longer set *PKG_RELEASE* to *AUTORELEASE* as the + feature is deprecated. Please use an integer instead. Below is a + list of affected packages including correct *PKG_RELEASE*: + + EOF + fi + + for ROOT in $CONTAINS_AUTORELEASE; do + echo -n " - ${ROOT}Makefile: PKG_RELEASE:=" >> "$GITHUB_WORKSPACE/pr_comment.md" + last_bump="$(git log --pretty=format:'%h %s' "$ROOT" | + grep --max-count=1 -e ': [uU]pdate to ' -e ': [bB]ump to ' | + cut -f 1 -d ' ')" + + if [ -n "$last_bump" ]; then + echo -n $(($(git rev-list --count "$last_bump..HEAD" "$ROOT") + 2)) >> "$GITHUB_WORKSPACE/pr_comment.md" + else + echo -n $(($(git rev-list --count HEAD "$ROOT") + 2)) >> "$GITHUB_WORKSPACE/pr_comment.md" + fi + echo >> "$GITHUB_WORKSPACE/pr_comment.md" + done + + exit $RET + + - name: Find Comment + uses: peter-evans/find-comment@v2 + if: ${{ failure() }} + id: fc + with: + issue-number: ${{ github.event.pull_request.number }} + comment-author: 'github-actions[bot]' + + - name: Create or update comment + uses: peter-evans/create-or-update-comment@v2 + if: ${{ failure() }} + with: + comment-id: ${{ steps.fc.outputs.comment-id }} + issue-number: ${{ github.event.pull_request.number }} + body-file: 'pr_comment.md' + edit-mode: replace diff --git a/.github/workflows/ci_helpers.sh b/.github/workflows/ci_helpers.sh new file mode 100644 index 000000000..60dcd4ee1 --- /dev/null +++ b/.github/workflows/ci_helpers.sh @@ -0,0 +1,26 @@ +#!/bin/sh + +color_out() { + printf "\e[0;$1m$PKG_NAME: %s\e[0;0m\n" "$2" +} + +success() { + color_out 32 "$1" +} + +info() { + color_out 36 "$1" +} + +err() { + color_out 31 "$1" +} + +warn() { + color_out 33 "$1" +} + +err_die() { + err "$1" + exit 1 +} diff --git a/.github/workflows/entrypoint.sh b/.github/workflows/entrypoint.sh new file mode 100755 index 000000000..6af84b8e7 --- /dev/null +++ b/.github/workflows/entrypoint.sh @@ -0,0 +1,43 @@ +#!/bin/sh + +# not enabling `errtrace` and `pipefail` since those are bash specific +set -o errexit # failing commands causes script to fail +set -o nounset # undefined variables causes script to fail + +mkdir -p /var/lock/ + +opkg update + +[ -n "${CI_HELPER:=''}" ] || CI_HELPER="/ci/.github/workflows/ci_helpers.sh" + +for PKG in /ci/*.ipk; do + tar -xzOf "$PKG" ./control.tar.gz | tar xzf - ./control + # package name including variant + PKG_NAME=$(sed -ne 's#^Package: \(.*\)$#\1#p' ./control) + # package version without release + PKG_VERSION=$(sed -ne 's#^Version: \(.*\)-[0-9]*$#\1#p' ./control) + # package source contianing test.sh script + PKG_SOURCE=$(sed -ne 's#^Source: .*/\(.*\)$#\1#p' ./control) + + echo "Testing package $PKG_NAME in version $PKG_VERSION from $PKG_SOURCE" + + opkg install "$PKG" + + export PKG_NAME PKG_VERSION CI_HELPER + + TEST_SCRIPT=$(find /ci/ -name "$PKG_SOURCE" -type d)/test.sh + + if [ -f "$TEST_SCRIPT" ]; then + echo "Use package specific test.sh" + if sh "$TEST_SCRIPT" "$PKG_NAME" "$PKG_VERSION"; then + echo "Test successful" + else + echo "Test failed" + exit 1 + fi + else + echo "No test.sh script available" + fi + + opkg remove "$PKG_NAME" --force-removal-of-dependent-packages --force-remove +done diff --git a/.github/workflows/formal.yml b/.github/workflows/formal.yml new file mode 100644 index 000000000..b3f824c52 --- /dev/null +++ b/.github/workflows/formal.yml @@ -0,0 +1,63 @@ +name: Test Formalities + +on: + pull_request: + +jobs: + build: + name: Test Formalities + runs-on: ubuntu-latest + strategy: + fail-fast: false + + steps: + - uses: actions/checkout@v3 + with: + ref: ${{ github.event.pull_request.head.sha }} + fetch-depth: 0 + + - name: Determine branch name + run: | + BRANCH="${GITHUB_BASE_REF#refs/heads/}" + echo "Building for $BRANCH" + echo "BRANCH=$BRANCH" >> $GITHUB_ENV + + - name: Test formalities + run: | + source .github/workflows/ci_helpers.sh + + RET=0 + for commit in $(git rev-list HEAD ^origin/$BRANCH); do + info "=== Checking commit '$commit'" + if git show --format='%P' -s $commit | grep -qF ' '; then + err "Pull request should not include merge commits" + RET=1 + fi + + author="$(git show -s --format=%aN $commit)" + if echo $author | grep -q '\S\+\s\+\S\+'; then + success "Author name ($author) seems ok" + else + err "Author name ($author) need to be your real name 'firstname lastname'" + RET=1 + fi + + subject="$(git show -s --format=%s $commit)" + if echo "$subject" | grep -q -e '^[0-9A-Za-z,+/_-]\+: ' -e '^Revert '; then + success "Commit subject line seems ok ($subject)" + else + err "Commit subject line MUST start with ': ' ($subject)" + RET=1 + fi + + body="$(git show -s --format=%b $commit)" + sob="$(git show -s --format='Signed-off-by: %aN <%aE>' $commit)" + if echo "$body" | grep -qF "$sob"; then + success "Signed-off-by match author" + else + err "Signed-off-by is missing or doesn't match author (should be '$sob')" + RET=1 + fi + done + + exit $RET diff --git a/.github/workflows/multi-arch-test-build.yml b/.github/workflows/multi-arch-test-build.yml new file mode 100644 index 000000000..514c276f2 --- /dev/null +++ b/.github/workflows/multi-arch-test-build.yml @@ -0,0 +1,164 @@ +name: Test Build + +on: + pull_request: + +jobs: + build: + name: Test ${{ matrix.arch }} + runs-on: ubuntu-latest + strategy: + fail-fast: false + matrix: + include: + - arch: arm_cortex-a9_vfpv3-d16 + target: mvebu-cortexa9 + runtime_test: false + + - arch: mips_24kc + target: ath79-generic + runtime_test: false + + - arch: mipsel_24kc + target: mt7621 + runtime_test: false + + - arch: powerpc_464fp + target: apm821xx-nand + runtime_test: false + + - arch: powerpc_8548 + target: mpc85xx-p1010 + runtime_test: false + + - arch: aarch64_cortex-a53 + target: mvebu-cortexa53 + runtime_test: true + + - arch: arm_cortex-a15_neon-vfpv4 + target: armvirt-32 + runtime_test: true + + - arch: i386_pentium-mmx + target: x86-geode + runtime_test: true + + - arch: x86_64 + target: x86-64 + runtime_test: true + + steps: + - uses: actions/checkout@v3 + with: + fetch-depth: 0 + + - name: Determine branch name + run: | + BRANCH="${GITHUB_BASE_REF#refs/heads/}" + echo "Building for $BRANCH" + echo "BRANCH=$BRANCH" >> $GITHUB_ENV + + - name: Determine changed packages + run: | + # only detect packages with changes + PKG_ROOTS=$(find . -name Makefile | \ + grep -v ".*/src/Makefile" | \ + sed -e 's@./\(.*\)/Makefile@\1/@') + CHANGES=$(git diff --diff-filter=d --name-only origin/$BRANCH...) + + for ROOT in $PKG_ROOTS; do + for CHANGE in $CHANGES; do + if [[ "$CHANGE" == "$ROOT"* ]]; then + PACKAGES+=$(echo "$ROOT" | sed -e 's@.*/\(.*\)/@\1 @') + break + fi + done + done + + # fallback to test packages if nothing explicitly changes this is + # should run if other mechanics in packages.git changed + PACKAGES="${PACKAGES:-vim attendedsysupgrade-common bmon}" + + echo "Building $PACKAGES" + echo "PACKAGES=$PACKAGES" >> $GITHUB_ENV + + - name: Build + uses: openwrt/gh-action-sdk@v5 + env: + ARCH: ${{ matrix.arch }}-${{ env.BRANCH }} + FEEDNAME: packages_ci + + - name: Move created packages to project dir + run: cp bin/packages/${{ matrix.arch }}/packages_ci/*.ipk . || true + + - name: Collect metadata + run: | + MERGE_ID=$(git rev-parse --short HEAD) + echo "MERGE_ID=$MERGE_ID" >> $GITHUB_ENV + echo "BASE_ID=$(git rev-parse --short HEAD^1)" >> $GITHUB_ENV + echo "HEAD_ID=$(git rev-parse --short HEAD^2)" >> $GITHUB_ENV + PRNUMBER=${GITHUB_REF_NAME%/merge} + echo "PRNUMBER=$PRNUMBER" >> $GITHUB_ENV + echo "ARCHIVE_NAME=${{matrix.arch}}-PR$PRNUMBER-$MERGE_ID" >> $GITHUB_ENV + + - name: Generate metadata + run: | + cat << _EOF_ > PKG-INFO + Metadata-Version: 2.1 + Name: ${{env.ARCHIVE_NAME}} + Version: $BRANCH + Author: $GITHUB_ACTOR + Home-page: $GITHUB_SERVER_URL/$GITHUB_REPOSITORY/pull/$PRNUMBER + Download-URL: $GITHUB_SERVER_URL/$GITHUB_REPOSITORY/actions/runs/$GITHUB_RUN_ID + Summary: $PACKAGES + Platform: ${{ matrix.arch }} + + Packages for OpenWrt $BRANCH running on ${{matrix.arch}}, built from PR $PRNUMBER + at commit $HEAD_ID, against $BRANCH at commit $BASE_ID, with merge SHA $MERGE_ID. + + Modified packages: + _EOF_ + for p in $PACKAGES + do + echo " "$p >> PKG-INFO + done + echo >> PKG-INFO + echo Full file listing: >> PKG-INFO + ls -al *.ipk >> PKG-INFO || true + cat PKG-INFO + + - name: Store packages + uses: actions/upload-artifact@v3 + with: + name: ${{env.ARCHIVE_NAME}}-packages + path: | + *.ipk + PKG-INFO + + - name: Store logs + uses: actions/upload-artifact@v3 + with: + name: ${{env.ARCHIVE_NAME}}-logs + path: | + logs/ + PKG-INFO + + - name: Remove logs + run: sudo rm -rf logs/ || true + + - name: Register QEMU + if: ${{ matrix.runtime_test }} + run: | + sudo docker run --rm --privileged aptman/qus -s -- -p + + - name: Build Docker container + if: ${{ matrix.runtime_test }} + run: | + docker build -t test-container --build-arg ARCH .github/workflows/ + env: + ARCH: ${{ matrix.arch }}-${{ env.BRANCH }} + + - name: Test via Docker container + if: ${{ matrix.runtime_test }} + run: | + docker run --rm -v $GITHUB_WORKSPACE:/ci test-container diff --git a/MAINTAINERS b/MAINTAINERS new file mode 100644 index 000000000..fd917b18e --- /dev/null +++ b/MAINTAINERS @@ -0,0 +1,14 @@ +# _______ ________ __ +# | |.-----.-----.-----.| | | |.----.| |_ +# | - || _ | -__| || | | || _|| _| +# |_______|| __|_____|__|__||________||__| |____| +# |__| W I R E L E S S F R E E D O M +# +# People listed here are managing the OpenWrt telephony feed. Use +# alphabetical order when updating the list. + +Daniel Golle +Jiri Slachta +Luka Perkov +Mazi Lo +Sebastian Kemper diff --git a/README.md b/README.md new file mode 100644 index 000000000..54fb978a9 --- /dev/null +++ b/README.md @@ -0,0 +1,23 @@ +# Telephony packages feed + +## Description + +This is an OpenWrt package feed containing community maintained telephony packages. + +## Usage + +To use these packages, add the following line to the feeds.conf +in the OpenWrt buildroot: + +``` +src-git telephony https://github.com/openwrt/telephony.git +``` + +This feed should be included and enabled by default in the OpenWrt buildroot. To install all its package definitions, run: + +``` +./scripts/feeds update telephony +./scripts/feeds install -a -p telephony +``` + +The telephony packages should now appear in menuconfig. diff --git a/libs/bcg729/Makefile b/libs/bcg729/Makefile new file mode 100644 index 000000000..7ae59223c --- /dev/null +++ b/libs/bcg729/Makefile @@ -0,0 +1,70 @@ +# +# Copyright (C) 2006-2018 OpenWrt.org +# +# This is free software, licensed under the GNU General Public License v2. +# See /LICENSE for more information. +# + +include $(TOPDIR)/rules.mk + +PKG_NAME:=bcg729 +PKG_VERSION:=1.1.1 +PKG_RELEASE:=1 + +PKG_SOURCE_URL_FILE:=$(PKG_VERSION).tar.gz +PKG_SOURCE:=$(PKG_NAME)-$(PKG_SOURCE_URL_FILE) +PKG_SOURCE_URL:=https://github.com/BelledonneCommunications/$(PKG_NAME)/archive +PKG_HASH:=68599a850535d1b182932b3f86558ac8a76d4b899a548183b062956c5fdc916d + +PKG_BUILD_DIR:=$(BUILD_DIR)/$(PKG_NAME)-$(PKG_VERSION) +CMAKE_INSTALL:=1 + +PKG_LICENSE:=GPL-3.0-or-later +PKG_LICENSE_FILES:=LICENSE.txt +PKG_MAINTAINER:=Alex Samorukov + +include $(INCLUDE_DIR)/package.mk +include $(INCLUDE_DIR)/cmake.mk + +define Package/bcg729 + SUBMENU:=Telephony + SECTION:=libs + CATEGORY:=Libraries + TITLE:=Software G729A encoder and decoder library written in C + URL:=http://www.linphone.org/technical-corner/bcg729.html +endef + +define Package/bcg729/description + Bcg729 is a software G729A encoder and decoder library written in C, developed + by Belledonne Communications, the company supporting the Linphone project. + It was written from scratch and is NOT a derivative work of ITU reference + source code in any kind. +endef + +# Otherwise OpenWrt's CPPFLAGS are ignored +TARGET_CFLAGS += $(TARGET_CPPFLAGS) + +CMAKE_OPTIONS += \ + -DCMAKE_VERBOSE_MAKEFILE=TRUE \ + -DENABLE_SHARED=YES \ + -DENABLE_STATIC=NO \ + -DENABLE_TESTS=NO + +define Build/InstallDev + $(INSTALL_DIR) $(1)/usr/include/bcg729 + $(INSTALL_DATA) $(PKG_INSTALL_DIR)/usr/include/bcg729/*.h \ + $(1)/usr/include/bcg729 + $(INSTALL_DIR) $(1)/usr/lib/{cmake/Bcg729,pkgconfig} + $(CP) $(PKG_INSTALL_DIR)/usr/lib/libbcg729.so* $(1)/usr/lib + $(INSTALL_DATA) $(PKG_INSTALL_DIR)/usr/lib/pkgconfig/lib$(PKG_NAME).pc \ + $(1)/usr/lib/pkgconfig + $(INSTALL_DATA) $(PKG_INSTALL_DIR)/usr/share/Bcg729/cmake/*.cmake \ + $(1)/usr/lib/cmake/Bcg729 +endef + +define Package/bcg729/install + $(INSTALL_DIR) $(1)/usr/lib + $(CP) $(PKG_INSTALL_DIR)/usr/lib/libbcg729.so* $(1)/usr/lib/ +endef + +$(eval $(call BuildPackage,bcg729)) diff --git a/libs/dahdi-linux/Makefile b/libs/dahdi-linux/Makefile new file mode 100644 index 000000000..168d404c2 --- /dev/null +++ b/libs/dahdi-linux/Makefile @@ -0,0 +1,111 @@ +# +# Copyright (C) 2014 - 2018 OpenWrt.org +# +# This is free software, licensed under the GNU General Public License v2. +# See /LICENSE for more information. +# + +include $(TOPDIR)/rules.mk +include $(INCLUDE_DIR)/kernel.mk + +PKG_NAME:=dahdi-linux +PKG_RELEASE:=2 + +PKG_SOURCE_PROTO:=git +PKG_SOURCE_URL:=https://github.com/asterisk/dahdi-linux.git +PKG_SOURCE_DATE=2023-09-21 +PKG_SOURCE_VERSION:=1bb9088f2baff8c4e3fec536044cc48072cf9905 +PKG_MIRROR_HASH:=6a15a0383deeb7f9cc36a55bfa5bec13d225e738b1723faf15b25df74665198b + +PKG_LICENSE:=GPL-2.0 +PKG_LICENSE_FILES:=LICENSE +PKG_MAINTAINER:=Vittorio Gambaletta + +# With below variable set, $(PKG_SYMVERS_DIR)/dahdi-linux.symvers gets +# generated from drivers/dahdi/Module.symvers. +PKG_EXTMOD_SUBDIRS:=drivers/dahdi + +include $(INCLUDE_DIR)/package.mk + +define KernelPackage/dahdi + SUBMENU:=Voice over IP + TITLE:=DAHDI basic infrastructure + DEPENDS:=@USB_SUPPORT +kmod-lib-crc-ccitt + URL:=http://www.asterisk.org/ + FILES:= $(PKG_BUILD_DIR)/drivers/dahdi/dahdi.$(LINUX_KMOD_SUFFIX) + AUTOLOAD:=$(call AutoProbe,dahdi) +endef + +define KernelPackage/dahdi/description + This package contains DAHDI basic infrastructure. +endef + +define KernelPackage/dahdi-echocan-oslec + SUBMENU:=Voice over IP + TITLE:=DAHDI OSLEC echo canceller support + DEPENDS:=kmod-dahdi +kmod-echo + URL:=http://www.asterisk.org/ + FILES:=$(PKG_BUILD_DIR)/drivers/dahdi/dahdi_echocan_oslec.$(LINUX_KMOD_SUFFIX) + AUTOLOAD:=$(call AutoProbe,dahdi_echocan_oslec) +endef + +define KernelPackage/dahdi-echocan-oslec/description + This package contains DAHDI OSLEC echo canceller support. +endef + +define KernelPackage/dahdi-hfcs + SUBMENU:=Voice over IP + TITLE:=DAHDI driver for HFC-S PCI + DEPENDS:=@PCI_SUPPORT kmod-dahdi + URL:=http://sourceforge.net/projects/dahdi-hfcs/ + FILES:= $(PKG_BUILD_DIR)/drivers/dahdi/hfcs/dahdi_hfcs.$(LINUX_KMOD_SUFFIX) + AUTOLOAD:=$(call AutoProbe,dahdi_hfcs) +endef + +define KernelPackage/dahdi-hfcs/description + This package contains DAHDI driver for HFC-S based PCI BRI adapters. +endef + +define KernelPackage/dahdi-dummy + SUBMENU:=Voice over IP + TITLE:=dummy DAHDI driver + DEPENDS:=kmod-dahdi + URL:=http://www.asterisk.org/ + FILES:= $(PKG_BUILD_DIR)/drivers/dahdi/dahdi_dummy.$(LINUX_KMOD_SUFFIX) + AUTOLOAD:=$(call AutoProbe,dahdi_dummy) +endef + +define KernelPackage/dahdi-dummy/description + This package contains the dummy DAHDI driver providing only DAHDI timing + without any real telephony hardware. +endef + + +define Build/Configure +endef + +define Build/Prepare + $(Build/Prepare/Default) + mkdir -p $(PKG_BUILD_DIR)/drivers/staging/echo/ + $(CP) ./files/oslec.h $(PKG_BUILD_DIR)/drivers/staging/echo/ +endef + +define Build/Compile + $(MAKE) $(PKG_JOBS) -C $(PKG_BUILD_DIR) \ + $(KERNEL_MAKE_FLAGS) \ + KSRC="$(LINUX_DIR)" +endef + +define Build/InstallDev + mkdir -p $(1)/usr/include/dahdi + $(CP) $(PKG_BUILD_DIR)/include/dahdi/dahdi_config.h $(1)/usr/include/dahdi/ + $(CP) $(PKG_BUILD_DIR)/include/dahdi/fasthdlc.h $(1)/usr/include/dahdi/ + $(CP) $(PKG_BUILD_DIR)/include/dahdi/kernel.h $(1)/usr/include/dahdi/ + $(CP) $(PKG_BUILD_DIR)/include/dahdi/user.h $(1)/usr/include/dahdi/ + $(CP) $(PKG_BUILD_DIR)/include/dahdi/wctdm_user.h $(1)/usr/include/dahdi/ +endef + +$(eval $(call KernelPackage,dahdi)) +$(eval $(call KernelPackage,dahdi-echocan-oslec)) +$(eval $(call KernelPackage,dahdi-dummy)) +$(eval $(call KernelPackage,dahdi-hfcs)) diff --git a/libs/dahdi-linux/files/oslec.h b/libs/dahdi-linux/files/oslec.h new file mode 100644 index 000000000..f4175360c --- /dev/null +++ b/libs/dahdi-linux/files/oslec.h @@ -0,0 +1,94 @@ +/* + * OSLEC - A line echo canceller. This code is being developed + * against and partially complies with G168. Using code from SpanDSP + * + * Written by Steve Underwood + * and David Rowe + * + * Copyright (C) 2001 Steve Underwood and 2007-2008 David Rowe + * + * All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2, as + * published by the Free Software Foundation. + * + * This program 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 General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + * + */ + +#ifndef __OSLEC_H +#define __OSLEC_H + +/* Mask bits for the adaption mode */ +#define ECHO_CAN_USE_ADAPTION 0x01 +#define ECHO_CAN_USE_NLP 0x02 +#define ECHO_CAN_USE_CNG 0x04 +#define ECHO_CAN_USE_CLIP 0x08 +#define ECHO_CAN_USE_TX_HPF 0x10 +#define ECHO_CAN_USE_RX_HPF 0x20 +#define ECHO_CAN_DISABLE 0x40 + +/** + * oslec_state: G.168 echo canceller descriptor. + * + * This defines the working state for a line echo canceller. + */ +struct oslec_state; + +/** + * oslec_create - Create a voice echo canceller context. + * @len: The length of the canceller, in samples. + * @return: The new canceller context, or NULL if the canceller could not be + * created. + */ +struct oslec_state *oslec_create(int len, int adaption_mode); + +/** + * oslec_free - Free a voice echo canceller context. + * @ec: The echo canceller context. + */ +void oslec_free(struct oslec_state *ec); + +/** + * oslec_flush - Flush (reinitialise) a voice echo canceller context. + * @ec: The echo canceller context. + */ +void oslec_flush(struct oslec_state *ec); + +/** + * oslec_adaption_mode - set the adaption mode of a voice echo canceller context. + * @ec The echo canceller context. + * @adaption_mode: The mode. + */ +void oslec_adaption_mode(struct oslec_state *ec, int adaption_mode); + +void oslec_snapshot(struct oslec_state *ec); + +/** + * oslec_update: Process a sample through a voice echo canceller. + * @ec: The echo canceller context. + * @tx: The transmitted audio sample. + * @rx: The received audio sample. + * + * The return value is the clean (echo cancelled) received sample. + */ +int16_t oslec_update(struct oslec_state *ec, int16_t tx, int16_t rx); + +/** + * oslec_hpf_tx: Process to high pass filter the tx signal. + * @ec: The echo canceller context. + * @tx: The transmitted auio sample. + * + * The return value is the HP filtered transmit sample, send this to your D/A. + */ +int16_t oslec_hpf_tx(struct oslec_state *ec, int16_t tx); + +#endif /* __OSLEC_H */ diff --git a/libs/dahdi-linux/patches/003-fix-oslec-build.patch b/libs/dahdi-linux/patches/003-fix-oslec-build.patch new file mode 100644 index 000000000..4b2b2a0e9 --- /dev/null +++ b/libs/dahdi-linux/patches/003-fix-oslec-build.patch @@ -0,0 +1,13 @@ +--- a/drivers/dahdi/Kbuild ++++ b/drivers/dahdi/Kbuild +@@ -64,9 +64,8 @@ obj-m += $(DAHDI_MODULES_EXTRA) + # If you want to build OSLEC, include the code in the standard location: + # drivers/staging/echo . The DAHDI OSLEC echo canceller will be built as + # well: +-ifneq (,$(wildcard $(src)/../staging/echo/echo.c)) ++ifneq (,$(wildcard $(src)/../staging/echo/oslec.h)) + obj-m += dahdi_echocan_oslec.o +-obj-m += ../staging/echo/echo.o + endif + + CFLAGS_MODULE += -I$(DAHDI_INCLUDE) -I$(src) -Wno-format-truncation diff --git a/libs/dahdi-linux/patches/050-re-enable-ztdummy.patch b/libs/dahdi-linux/patches/050-re-enable-ztdummy.patch new file mode 100644 index 000000000..5db2dfe49 --- /dev/null +++ b/libs/dahdi-linux/patches/050-re-enable-ztdummy.patch @@ -0,0 +1,9 @@ +--- a/drivers/dahdi/Kbuild ++++ b/drivers/dahdi/Kbuild +@@ -1,5 +1,5 @@ + obj-$(DAHDI_BUILD_ALL)$(CONFIG_DAHDI) += dahdi.o +-#obj-$(DAHDI_BUILD_ALL)$(CONFIG_DAHDI_DUMMY) += dahdi_dummy.o ++obj-$(DAHDI_BUILD_ALL)$(CONFIG_DAHDI_DUMMY) += dahdi_dummy.o + obj-$(DAHDI_BUILD_ALL)$(CONFIG_DAHDI_DYNAMIC) += dahdi_dynamic.o + obj-$(DAHDI_BUILD_ALL)$(CONFIG_DAHDI_DYNAMIC_LOC) += dahdi_dynamic_loc.o + obj-$(DAHDI_BUILD_ALL)$(CONFIG_DAHDI_DYNAMIC_ETH) += dahdi_dynamic_eth.o diff --git a/libs/dahdi-linux/patches/070-no-firmware-blob-download.patch b/libs/dahdi-linux/patches/070-no-firmware-blob-download.patch new file mode 100644 index 000000000..90e454704 --- /dev/null +++ b/libs/dahdi-linux/patches/070-no-firmware-blob-download.patch @@ -0,0 +1,17 @@ +--- a/Makefile ++++ b/Makefile +@@ -80,12 +80,12 @@ include/dahdi/version.h: FORCE + fi + @rm -f $@.tmp + +-prereq: include/dahdi/version.h firmware-loaders ++prereq: include/dahdi/version.h + + stackcheck: $(CHECKSTACK) modules + objdump -d drivers/dahdi/*.ko drivers/dahdi/*/*.ko | $(CHECKSTACK) + +-install: all install-modules install-include install-firmware install-xpp-firm ++install: all install-modules install-include + @echo "###################################################" + @echo "###" + @echo "### DAHDI installed successfully." diff --git a/libs/dahdi-linux/patches/100-add-support-for-hfc-s-pci.patch b/libs/dahdi-linux/patches/100-add-support-for-hfc-s-pci.patch new file mode 100644 index 000000000..7a8d94584 --- /dev/null +++ b/libs/dahdi-linux/patches/100-add-support-for-hfc-s-pci.patch @@ -0,0 +1,2732 @@ +--- a/drivers/dahdi/Kbuild ++++ b/drivers/dahdi/Kbuild +@@ -12,6 +12,7 @@ obj-$(DAHDI_BUILD_ALL)$(CONFIG_DAHDI_WCT + obj-$(DAHDI_BUILD_ALL)$(CONFIG_DAHDI_WCTC4XXP) += wctc4xxp/ + obj-$(DAHDI_BUILD_ALL)$(CONFIG_DAHDI_WCTDM24XXP) += wctdm24xxp/ + obj-$(DAHDI_BUILD_ALL)$(CONFIG_DAHDI_WCTE13XP) += wcte13xp.o ++obj-$(DAHDI_BUILD_ALL)$(CONFIG_DAHDI_HFCS) += hfcs/ + + ifndef HOTPLUG_FIRMWARE + ifneq (,$(filter y m,$(CONFIG_FW_LOADER))) +--- a/drivers/dahdi/Kconfig ++++ b/drivers/dahdi/Kconfig +@@ -235,4 +235,14 @@ config DAHDI_DYNAMIC_LOC + If unsure, say Y. + + ++config DAHDI_HFCS ++ tristate "Support for various HFC-S PCI BRI adapters" ++ depends on DAHDI && PCI ++ default DAHDI ++ ---help--- ++ To compile this driver as a module, choose M here: the ++ module will be called dahdi_hfcs. ++ ++ If unsure, say Y. ++ + source "drivers/dahdi/xpp/Kconfig" +--- /dev/null ++++ b/drivers/dahdi/hfcs/base.c +@@ -0,0 +1,1742 @@ ++/* ++ * dahdi_hfcs.c - Dahdi driver for HFC-S PCI A based ISDN BRI cards ++ * ++ * Dahdi rewrite in hardhdlc mode ++ * Jose A. Deniz ++ * ++ * Copyright (C) 2011, Raoul Bönisch ++ * Copyright (C) 2009, Jose A. Deniz ++ * Copyright (C) 2006, headissue GmbH; Jens Wilke ++ * Copyright (C) 2004 Daniele Orlandi ++ * Copyright (C) 2002, 2003, 2004, Junghanns.NET GmbH ++ * ++ * Jens Wilke ++ * ++ * Original author of this code is ++ * Daniele "Vihai" Orlandi ++ * ++ * Major rewrite of the driver made by ++ * Klaus-Peter Junghanns ++ * ++ * This program is free software and may be modified and ++ * distributed under the terms of the GNU Public License. ++ * ++ * Please read the README file for important infos. ++ */ ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 32)) ++#include ++#endif ++#include ++#include ++ ++#include ++ ++#include "dahdi_hfcs.h" ++#include "fifo.h" ++ ++#if CONFIG_PCI ++ ++#define DAHDI_B1 0 ++#define DAHDI_B2 1 ++#define DAHDI_D 2 ++ ++#define D 0 ++#define B1 1 ++#define B2 2 ++ ++/* ++ * Mode Te for all ++ */ ++static int modes; ++static int nt_modes[hfc_MAX_BOARDS]; ++static int nt_modes_count; ++static int force_l1_up; ++static struct proc_dir_entry *hfc_proc_dahdi_hfcs_dir; ++ ++#define DEBUG ++#ifdef DEBUG ++int debug_level; ++#endif ++ ++#ifndef FALSE ++#define FALSE 0 ++#endif ++#ifndef TRUE ++#define TRUE (!FALSE) ++#endif ++ ++#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,30) ++#define SET_PROC_DIRENTRY_OWNER(p) do { (p)->owner = THIS_MODULE; } while(0); ++#else ++#define SET_PROC_DIRENTRY_OWNER(p) do { } while(0); ++#endif ++ ++static DEFINE_PCI_DEVICE_TABLE(hfc_pci_ids) = { ++ {PCI_VENDOR_ID_CCD, PCI_DEVICE_ID_CCD_2BD0, ++ PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, ++ {PCI_VENDOR_ID_CCD, PCI_DEVICE_ID_CCD_B000, ++ PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, ++ {PCI_VENDOR_ID_CCD, PCI_DEVICE_ID_CCD_B006, ++ PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, ++ {PCI_VENDOR_ID_CCD, PCI_DEVICE_ID_CCD_B007, ++ PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, ++ {PCI_VENDOR_ID_CCD, PCI_DEVICE_ID_CCD_B008, ++ PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, ++ {PCI_VENDOR_ID_CCD, PCI_DEVICE_ID_CCD_B009, ++ PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, ++ {PCI_VENDOR_ID_CCD, PCI_DEVICE_ID_CCD_B00A, ++ PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, ++ {PCI_VENDOR_ID_CCD, PCI_DEVICE_ID_CCD_B00B, ++ PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, ++ {PCI_VENDOR_ID_CCD, PCI_DEVICE_ID_CCD_B00C, ++ PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, ++ {PCI_VENDOR_ID_CCD, PCI_DEVICE_ID_CCD_B100, ++ PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, ++ {PCI_VENDOR_ID_ABOCOM, PCI_DEVICE_ID_ABOCOM_2BD1, ++ PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, ++ {PCI_VENDOR_ID_ASUSTEK, PCI_DEVICE_ID_ASUSTEK_0675, ++ PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, ++ {PCI_VENDOR_ID_BERKOM, PCI_DEVICE_ID_BERKOM_T_CONCEPT, ++ PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, ++ {PCI_VENDOR_ID_BERKOM, PCI_DEVICE_ID_BERKOM_A1T, ++ PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, ++ {PCI_VENDOR_ID_ANIGMA, PCI_DEVICE_ID_ANIGMA_MC145575, ++ PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, ++ {PCI_VENDOR_ID_ZOLTRIX, PCI_DEVICE_ID_ZOLTRIX_2BD0, ++ PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, ++ {PCI_VENDOR_ID_DIGI, PCI_DEVICE_ID_DIGI_DF_M_IOM2_E, ++ PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, ++ {PCI_VENDOR_ID_DIGI, PCI_DEVICE_ID_DIGI_DF_M_E, ++ PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, ++ {PCI_VENDOR_ID_DIGI, PCI_DEVICE_ID_DIGI_DF_M_IOM2_A, ++ PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, ++ {PCI_VENDOR_ID_DIGI, PCI_DEVICE_ID_DIGI_DF_M_A, ++ PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, ++ {PCI_VENDOR_ID_SITECOM, PCI_DEVICE_ID_SITECOM_3069, ++ PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, ++ {0,} ++}; ++ ++MODULE_DEVICE_TABLE(pci, hfc_pci_ids); ++ ++static int __devinit hfc_probe(struct pci_dev *dev ++ , const struct pci_device_id *ent); ++static void __devexit hfc_remove(struct pci_dev *dev); ++ ++static struct pci_driver hfc_driver = { ++ .name = hfc_DRIVER_NAME, ++ .id_table = hfc_pci_ids, ++ .probe = hfc_probe, ++ .remove = __devexit_p(hfc_remove), ++}; ++ ++/****************************************** ++ * HW routines ++ ******************************************/ ++ ++static void hfc_softreset(struct hfc_card *card) ++{ ++ printk(KERN_INFO hfc_DRIVER_PREFIX ++ "card %d: " ++ "resetting\n", ++ card->cardnum); ++ ++/* ++ * Softreset procedure. Put it on, wait and off again ++ */ ++ hfc_outb(card, hfc_CIRM, hfc_CIRM_RESET); ++ udelay(6); ++ hfc_outb(card, hfc_CIRM, 0); ++ ++ set_current_state(TASK_UNINTERRUPTIBLE); ++ schedule_timeout((hfc_RESET_DELAY * HZ) / 1000); ++} ++ ++static void hfc_resetCard(struct hfc_card *card) ++{ ++ card->regs.m1 = 0; ++ hfc_outb(card, hfc_INT_M1, card->regs.m1); ++ ++ card->regs.m2 = 0; ++ hfc_outb(card, hfc_INT_M2, card->regs.m2); ++ ++ hfc_softreset(card); ++ ++ card->regs.trm = 0; ++ hfc_outb(card, hfc_TRM, card->regs.trm); ++ ++ /* ++ * Select the non-capacitive line mode for the S/T interface ++ */ ++ card->regs.sctrl = hfc_SCTRL_NONE_CAP; ++ ++ if (card->nt_mode) { ++ /* ++ * ST-Bit delay for NT-Mode ++ */ ++ hfc_outb(card, hfc_CLKDEL, hfc_CLKDEL_NT); ++ ++ card->regs.sctrl |= hfc_SCTRL_MODE_NT; ++ } else { ++ /* ++ * ST-Bit delay for TE-Mode ++ */ ++ hfc_outb(card, hfc_CLKDEL, hfc_CLKDEL_TE); ++ ++ card->regs.sctrl |= hfc_SCTRL_MODE_TE; ++ } ++ ++ hfc_outb(card, hfc_SCTRL, card->regs.sctrl); ++ ++ /* ++ * S/T Auto awake ++ */ ++ card->regs.sctrl_e = hfc_SCTRL_E_AUTO_AWAKE; ++ hfc_outb(card, hfc_SCTRL_E, card->regs.sctrl_e); ++ ++ /* ++ * No B-channel enabled at startup ++ */ ++ card->regs.sctrl_r = 0; ++ hfc_outb(card, hfc_SCTRL_R, card->regs.sctrl_r); ++ ++ /* ++ * HFC Master Mode ++ */ ++ hfc_outb(card, hfc_MST_MODE, hfc_MST_MODE_MASTER); ++ ++ /* ++ * Connect internal blocks ++ */ ++ card->regs.connect = ++ hfc_CONNECT_B1_HFC_from_ST | ++ hfc_CONNECT_B1_ST_from_HFC | ++ hfc_CONNECT_B1_GCI_from_HFC | ++ hfc_CONNECT_B2_HFC_from_ST | ++ hfc_CONNECT_B2_ST_from_HFC | ++ hfc_CONNECT_B2_GCI_from_HFC; ++ hfc_outb(card, hfc_CONNECT, card->regs.connect); ++ ++ /* ++ * All bchans are HDLC by default, not useful, actually ++ * since mode is set during open() ++ */ ++ hfc_outb(card, hfc_CTMT, 0); ++ ++ /* ++ * bit order ++ */ ++ hfc_outb(card, hfc_CIRM, 0); ++ ++ /* ++ * Enable D-rx FIFO. At least one FIFO must be enabled (by specs) ++ */ ++ card->regs.fifo_en = hfc_FIFOEN_DRX; ++ hfc_outb(card, hfc_FIFO_EN, card->regs.fifo_en); ++ ++ card->late_irqs = 0; ++ ++ /* ++ * Clear already pending ints ++ */ ++ hfc_inb(card, hfc_INT_S1); ++ hfc_inb(card, hfc_INT_S2); ++ ++ /* ++ * Enable IRQ output ++ */ ++ card->regs.m1 = hfc_INTS_DREC | hfc_INTS_L1STATE | hfc_INTS_TIMER; ++ hfc_outb(card, hfc_INT_M1, card->regs.m1); ++ ++ card->regs.m2 = hfc_M2_IRQ_ENABLE; ++ hfc_outb(card, hfc_INT_M2, card->regs.m2); ++ ++ /* ++ * Unlocks the states machine ++ */ ++ hfc_outb(card, hfc_STATES, 0); ++ ++ /* ++ * There's no need to explicitly activate L1 now. ++ * Activation is managed inside the interrupt routine. ++ */ ++} ++ ++static void hfc_update_fifo_state(struct hfc_card *card) ++{ ++ /* ++ * I'm not sure if irqsave is needed but there could be a race ++ * condition since hfc_update_fifo_state could be called from ++ * both the IRQ handler and the *_(open|close) functions ++ */ ++ ++ unsigned long flags; ++ spin_lock_irqsave(&card->chans[B1].lock, flags); ++ if (!card->fifo_suspended && ++ (card->chans[B1].status == open_framed || ++ card->chans[B1].status == open_voice)) { ++ ++ if (!(card->regs.fifo_en & hfc_FIFOEN_B1RX)) { ++ card->regs.fifo_en |= hfc_FIFOEN_B1RX; ++ hfc_clear_fifo_rx(&card->chans[B1].rx); ++ } ++ ++ if (!(card->regs.fifo_en & hfc_FIFOEN_B1TX)) { ++ card->regs.fifo_en |= hfc_FIFOEN_B1TX; ++ hfc_clear_fifo_tx(&card->chans[B1].tx); ++ } ++ } else { ++ if (card->regs.fifo_en & hfc_FIFOEN_B1RX) ++ card->regs.fifo_en &= ~hfc_FIFOEN_B1RX; ++ if (card->regs.fifo_en & hfc_FIFOEN_B1TX) ++ card->regs.fifo_en &= ~hfc_FIFOEN_B1TX; ++ } ++ spin_unlock_irqrestore(&card->chans[B1].lock, flags); ++ ++ spin_lock_irqsave(&card->chans[B2].lock, flags); ++ if (!card->fifo_suspended && ++ (card->chans[B2].status == open_framed || ++ card->chans[B2].status == open_voice || ++ card->chans[B2].status == sniff_aux)) { ++ ++ if (!(card->regs.fifo_en & hfc_FIFOEN_B2RX)) { ++ card->regs.fifo_en |= hfc_FIFOEN_B2RX; ++ hfc_clear_fifo_rx(&card->chans[B2].rx); ++ } ++ ++ if (!(card->regs.fifo_en & hfc_FIFOEN_B2TX)) { ++ card->regs.fifo_en |= hfc_FIFOEN_B2TX; ++ hfc_clear_fifo_tx(&card->chans[B2].tx); ++ } ++ } else { ++ if (card->regs.fifo_en & hfc_FIFOEN_B2RX) ++ card->regs.fifo_en &= ~hfc_FIFOEN_B2RX; ++ if (card->regs.fifo_en & hfc_FIFOEN_B2TX) ++ card->regs.fifo_en &= ~hfc_FIFOEN_B2TX; ++ } ++ spin_unlock_irqrestore(&card->chans[B2].lock, flags); ++ ++ spin_lock_irqsave(&card->chans[D].lock, flags); ++ if (!card->fifo_suspended && ++ card->chans[D].status == open_framed) { ++ ++ if (!(card->regs.fifo_en & hfc_FIFOEN_DTX)) { ++ card->regs.fifo_en |= hfc_FIFOEN_DTX; ++ ++ card->chans[D].tx.ugly_framebuf_size = 0; ++ card->chans[D].tx.ugly_framebuf_off = 0; ++ } ++ } else { ++ if (card->regs.fifo_en & hfc_FIFOEN_DTX) ++ card->regs.fifo_en &= ~hfc_FIFOEN_DTX; ++ } ++ spin_unlock_irqrestore(&card->chans[D].lock, flags); ++ ++ hfc_outb(card, hfc_FIFO_EN, card->regs.fifo_en); ++} ++ ++static inline void hfc_suspend_fifo(struct hfc_card *card) ++{ ++ card->fifo_suspended = TRUE; ++ ++ hfc_update_fifo_state(card); ++ ++ /* ++ * When L1 goes down D rx receives garbage; it is nice to ++ * clear it to avoid a CRC error on reactivation ++ * udelay is needed because the FIFO deactivation happens ++ * in 250us ++ */ ++ udelay(250); ++ hfc_clear_fifo_rx(&card->chans[D].rx); ++ ++#ifdef DEBUG ++ if (debug_level >= 3) { ++ printk(KERN_DEBUG hfc_DRIVER_PREFIX ++ "card %d: " ++ "FIFOs suspended\n", ++ card->cardnum); ++ } ++#endif ++} ++ ++static inline void hfc_resume_fifo(struct hfc_card *card) ++{ ++ card->fifo_suspended = FALSE; ++ ++ hfc_update_fifo_state(card); ++ ++#ifdef DEBUG ++ if (debug_level >= 3) { ++ printk(KERN_DEBUG hfc_DRIVER_PREFIX ++ "card %d: " ++ "FIFOs resumed\n", ++ card->cardnum); ++ } ++#endif ++} ++ ++static void hfc_check_l1_up(struct hfc_card *card) ++{ ++ if ((!card->nt_mode && card->l1_state != 7) ++ || (card->nt_mode && card->l1_state != 3)) { ++ ++ hfc_outb(card, hfc_STATES, hfc_STATES_DO_ACTION | ++ hfc_STATES_ACTIVATE| ++ hfc_STATES_NT_G2_G3); ++ ++ /* ++ * 0 because this is quite verbose when an inferface is unconnected, jaw ++ */ ++#if 0 ++ if (debug_level >= 1) { ++ printk(KERN_DEBUG hfc_DRIVER_PREFIX ++ "card %d: " ++ "L1 is down, bringing up L1.\n", ++ card->cardnum); ++ } ++#endif ++ } ++} ++ ++ ++/******************* ++ * Dahdi interface * ++ *******************/ ++ ++static int hfc_dahdi_open(struct dahdi_chan *dahdi_chan) ++{ ++ struct hfc_chan_duplex *chan = dahdi_chan->pvt; ++ struct hfc_card *card = chan->card; ++ ++ spin_lock(&chan->lock); ++ ++ switch (chan->number) { ++ case D: ++ if (chan->status != free && ++ chan->status != open_framed) { ++ spin_unlock(&chan->lock); ++ return -EBUSY; ++ } ++ chan->status = open_framed; ++ break; ++ ++ case B1: ++ case B2: ++ if (chan->status != free) { ++ spin_unlock(&chan->lock); ++ return -EBUSY; ++ } ++ chan->status = open_voice; ++ break; ++ } ++ ++ chan->open_by_dahdi = TRUE; ++ try_module_get(THIS_MODULE); ++ spin_unlock(&chan->lock); ++ ++ switch (chan->number) { ++ case D: ++ break; ++ ++ case B1: ++ card->regs.m2 |= hfc_M2_PROC_TRANS; ++ /* ++ * Enable transparent mode ++ */ ++ card->regs.ctmt |= hfc_CTMT_TRANSB1; ++ /* ++ * Reversed bit order ++ */ ++ card->regs.cirm |= hfc_CIRM_B1_REV; ++ /* ++ * Enable transmission ++ */ ++ card->regs.sctrl |= hfc_SCTRL_B1_ENA; ++ /* ++ * Enable reception ++ */ ++ card->regs.sctrl_r |= hfc_SCTRL_R_B1_ENA; ++ break; ++ ++ case B2: ++ card->regs.m2 |= hfc_M2_PROC_TRANS; ++ card->regs.ctmt |= hfc_CTMT_TRANSB2; ++ card->regs.cirm |= hfc_CIRM_B2_REV; ++ card->regs.sctrl |= hfc_SCTRL_B2_ENA; ++ card->regs.sctrl_r |= hfc_SCTRL_R_B2_ENA; ++ break; ++ ++ } ++ ++ /* ++ * If not already enabled, enable processing transition (8KHz) ++ * interrupt ++ */ ++ hfc_outb(card, hfc_INT_M2, card->regs.m2); ++ hfc_outb(card, hfc_CTMT, card->regs.ctmt); ++ hfc_outb(card, hfc_CIRM, card->regs.cirm); ++ hfc_outb(card, hfc_SCTRL, card->regs.sctrl); ++ hfc_outb(card, hfc_SCTRL_R, card->regs.sctrl_r); ++ ++ hfc_update_fifo_state(card); ++ ++ printk(KERN_INFO hfc_DRIVER_PREFIX ++ "card %d: " ++ "chan %s opened as %s.\n", ++ card->cardnum, ++ chan->name, ++ dahdi_chan->name); ++ ++ return 0; ++} ++ ++static int hfc_dahdi_close(struct dahdi_chan *dahdi_chan) ++{ ++ struct hfc_chan_duplex *chan = dahdi_chan->pvt; ++ struct hfc_card *card = chan->card; ++ ++ if (!card) { ++ printk(KERN_CRIT hfc_DRIVER_PREFIX ++ "hfc_dahdi_close called with NULL card\n"); ++ return -1; ++ } ++ ++ spin_lock(&chan->lock); ++ ++ if (chan->status == free) { ++ spin_unlock(&chan->lock); ++ return -EINVAL; ++ } ++ ++ chan->status = free; ++ chan->open_by_dahdi = FALSE; ++ ++ spin_unlock(&chan->lock); ++ ++ switch (chan->number) { ++ case D: ++ break; ++ ++ case B1: ++ card->regs.ctmt &= ~hfc_CTMT_TRANSB1; ++ card->regs.cirm &= ~hfc_CIRM_B1_REV; ++ card->regs.sctrl &= ~hfc_SCTRL_B1_ENA; ++ card->regs.sctrl_r &= ~hfc_SCTRL_R_B1_ENA; ++ break; ++ ++ case B2: ++ card->regs.ctmt &= ~hfc_CTMT_TRANSB2; ++ card->regs.cirm &= ~hfc_CIRM_B2_REV; ++ card->regs.sctrl &= ~hfc_SCTRL_B2_ENA; ++ card->regs.sctrl_r &= ~hfc_SCTRL_R_B2_ENA; ++ break; ++ } ++ ++ if (card->chans[B1].status == free && ++ card->chans[B2].status == free) ++ card->regs.m2 &= ~hfc_M2_PROC_TRANS; ++ ++ hfc_outb(card, hfc_INT_M2, card->regs.m2); ++ hfc_outb(card, hfc_CTMT, card->regs.ctmt); ++ hfc_outb(card, hfc_CIRM, card->regs.cirm); ++ hfc_outb(card, hfc_SCTRL, card->regs.sctrl); ++ hfc_outb(card, hfc_SCTRL_R, card->regs.sctrl_r); ++ ++ hfc_update_fifo_state(card); ++ ++ module_put(THIS_MODULE); ++ ++ printk(KERN_INFO hfc_DRIVER_PREFIX ++ "card %d: " ++ "chan %s closed as %s.\n", ++ card->cardnum, ++ chan->name, ++ dahdi_chan->name); ++ ++ return 0; ++} ++ ++static int hfc_dahdi_rbsbits(struct dahdi_chan *chan, int bits) ++{ ++ return 0; ++} ++ ++static int hfc_dahdi_ioctl(struct dahdi_chan *chan, ++ unsigned int cmd, unsigned long data) ++{ ++ switch (cmd) { ++ ++ default: ++ return -ENOTTY; ++ } ++ ++ return 0; ++} ++ ++static void hfc_hdlc_hard_xmit(struct dahdi_chan *d_chan) ++{ ++ struct hfc_chan_duplex *chan = d_chan->pvt; ++ struct hfc_card *card = chan->card; ++ struct dahdi_hfc *hfccard = card->dahdi_dev; ++ ++ atomic_inc(&hfccard->hdlc_pending); ++ ++} ++ ++static int hfc_dahdi_startup(struct file *file, struct dahdi_span *span) ++{ ++ struct dahdi_hfc *dahdi_hfcs = dahdi_hfc_from_span(span); ++ struct hfc_card *hfctmp = dahdi_hfcs->card; ++ int alreadyrunning; ++ ++ if (!hfctmp) { ++ printk(KERN_INFO hfc_DRIVER_PREFIX ++ "card %d: " ++ "no card for span at startup!\n", ++ hfctmp->cardnum); ++ } ++ ++ alreadyrunning = span->flags & DAHDI_FLAG_RUNNING; ++ ++ if (!alreadyrunning) ++ span->flags |= DAHDI_FLAG_RUNNING; ++ ++ return 0; ++} ++ ++static int hfc_dahdi_shutdown(struct dahdi_span *span) ++{ ++ return 0; ++} ++ ++static int hfc_dahdi_maint(struct dahdi_span *span, int cmd) ++{ ++ return 0; ++} ++ ++static int hfc_dahdi_chanconfig(struct file *file, struct dahdi_chan *d_chan, int sigtype) ++{ ++ struct hfc_chan_duplex *chan = d_chan->pvt; ++ struct hfc_card *card = chan->card; ++ struct dahdi_hfc *hfccard = card->dahdi_dev; ++ ++ if ((sigtype == DAHDI_SIG_HARDHDLC) && (hfccard->sigchan == d_chan)) { ++ hfccard->sigactive = 0; ++ atomic_set(&hfccard->hdlc_pending, 0); ++ } ++ ++ return 0; ++} ++ ++static int hfc_dahdi_spanconfig(struct file *file, struct dahdi_span *span, ++ struct dahdi_lineconfig *lc) ++{ ++ span->lineconfig = lc->lineconfig; ++ ++ return 0; ++} ++ ++static const struct dahdi_span_ops hfc_dahdi_span_ops = { ++ .owner = THIS_MODULE, ++ .chanconfig = hfc_dahdi_chanconfig, ++ .spanconfig = hfc_dahdi_spanconfig, ++ .startup = hfc_dahdi_startup, ++ .shutdown = hfc_dahdi_shutdown, ++ .maint = hfc_dahdi_maint, ++ .rbsbits = hfc_dahdi_rbsbits, ++ .open = hfc_dahdi_open, ++ .close = hfc_dahdi_close, ++ .ioctl = hfc_dahdi_ioctl, ++ .hdlc_hard_xmit = hfc_hdlc_hard_xmit ++}; ++ ++static int hfc_dahdi_initialize(struct dahdi_hfc *hfccard) ++{ ++ struct hfc_card *hfctmp = hfccard->card; ++ int i; ++ ++ hfccard->ddev = dahdi_create_device(); ++ if (!hfccard->ddev) ++ return -ENOMEM; ++ ++ memset(&hfccard->span, 0x0, sizeof(struct dahdi_span)); ++ ++ /* ++ * ZTHFC ++ * ++ * Cards' and channels' names shall contain "ZTHFC" ++ * as the dahdi-tools look for this string to guess framing. ++ * We don't want to modify dahdi-tools only in order to change this. ++ * ++ * So we choose for a span name: DAHDI HFC-S formerly known as ZTHFC. :-) ++ */ ++ ++ sprintf(hfccard->span.name, "DAHDI_HFCS_FKA_ZTHFC%d", hfctmp->cardnum + 1); ++ sprintf(hfccard->span.desc, ++ "HFC-S PCI A ISDN card %d [%s] ", ++ hfctmp->cardnum, ++ hfctmp->nt_mode ? "NT" : "TE"); ++ hfccard->span.spantype = hfctmp->nt_mode ? SPANTYPE_DIGITAL_BRI_NT : ++ SPANTYPE_DIGITAL_BRI_TE; ++ hfccard->ddev->manufacturer = "Cologne Chips"; ++ hfccard->span.flags = 0; ++ hfccard->span.ops = &hfc_dahdi_span_ops; ++ hfccard->ddev->devicetype = kasprintf(GFP_KERNEL, "HFC-S PCI-A ISDN"); ++ hfccard->ddev->location = kasprintf(GFP_KERNEL, "PCI Bus %02d Slot %02d", ++ hfctmp->pcidev->bus->number, ++ PCI_SLOT(hfctmp->pcidev->devfn) + 1); ++ hfccard->span.chans = hfccard->_chans; ++ hfccard->span.channels = 3; ++ for (i = 0; i < hfccard->span.channels; i++) ++ hfccard->_chans[i] = &hfccard->chans[i]; ++ hfccard->span.deflaw = DAHDI_LAW_ALAW; ++ hfccard->span.linecompat = DAHDI_CONFIG_AMI | DAHDI_CONFIG_CCS; ++ hfccard->span.offset = 0; ++ ++ for (i = 0; i < hfccard->span.channels; i++) { ++ memset(&hfccard->chans[i], 0x0, sizeof(struct dahdi_chan)); ++ ++ sprintf(hfccard->chans[i].name, ++ "DAHDI_HFCS_FKA_ZTHFC%d/%d/%d", ++ hfctmp->cardnum + 1, 0, i + 1); ++ ++ printk(KERN_INFO hfc_DRIVER_PREFIX ++ "card %d: " ++ "registered %s\n", ++ hfctmp->cardnum, ++ hfccard->chans[i].name); ++ ++ if (i == hfccard->span.channels - 1) { ++ hfccard->chans[i].sigcap = DAHDI_SIG_HARDHDLC; ++ hfccard->sigchan = &hfccard->chans[DAHDI_D]; ++ hfccard->sigactive = 0; ++ atomic_set(&hfccard->hdlc_pending, 0); ++ } else { ++ hfccard->chans[i].sigcap = ++ DAHDI_SIG_CLEAR | DAHDI_SIG_DACS; ++ } ++ ++ hfccard->chans[i].chanpos = i + 1; ++ } ++ ++ hfccard->chans[DAHDI_D].readchunk = ++ hfctmp->chans[D].rx.dahdi_buffer; ++ ++ hfccard->chans[DAHDI_D].writechunk = ++ hfctmp->chans[D].tx.dahdi_buffer; ++ ++ hfccard->chans[DAHDI_D].pvt = &hfctmp->chans[D]; ++ ++ hfccard->chans[DAHDI_B1].readchunk = ++ hfctmp->chans[B1].rx.dahdi_buffer; ++ ++ hfccard->chans[DAHDI_B1].writechunk = ++ hfctmp->chans[B1].tx.dahdi_buffer; ++ ++ hfccard->chans[DAHDI_B1].pvt = &hfctmp->chans[B1]; ++ ++ hfccard->chans[DAHDI_B2].readchunk = ++ hfctmp->chans[B2].rx.dahdi_buffer; ++ ++ hfccard->chans[DAHDI_B2].writechunk = ++ hfctmp->chans[B2].tx.dahdi_buffer; ++ ++ hfccard->chans[DAHDI_B2].pvt = &hfctmp->chans[B2]; ++ ++ list_add_tail(&hfccard->span.device_node, &hfccard->ddev->spans); ++ if (dahdi_register_device(hfccard->ddev, &hfccard->card->pcidev->dev)) { ++ printk(KERN_NOTICE "Unable to register device with DAHDI\n"); ++ return -1; ++ } ++ ++ return 0; ++} ++ ++static void hfc_dahdi_transmit(struct hfc_chan_simplex *chan) ++{ ++ hfc_fifo_put(chan, chan->dahdi_buffer, DAHDI_CHUNKSIZE); ++} ++ ++static void hfc_dahdi_receive(struct hfc_chan_simplex *chan) ++{ ++ hfc_fifo_get(chan, chan->dahdi_buffer, DAHDI_CHUNKSIZE); ++} ++ ++/****************************************** ++ * Interrupt Handler ++ ******************************************/ ++ ++static void hfc_handle_timer_interrupt(struct hfc_card *card); ++static void hfc_handle_state_interrupt(struct hfc_card *card); ++static void hfc_handle_processing_interrupt(struct hfc_card *card); ++static void hfc_frame_arrived(struct hfc_chan_duplex *chan); ++static void hfc_handle_voice(struct hfc_card *card); ++ ++#if (KERNEL_VERSION(2, 6, 24) < LINUX_VERSION_CODE) ++static irqreturn_t hfc_interrupt(int irq, void *dev_id) ++#else ++static irqreturn_t hfc_interrupt(int irq, void *dev_id, struct pt_regs *regs) ++#endif ++{ ++ struct hfc_card *card = dev_id; ++ unsigned long flags; ++ u8 status, s1, s2; ++ ++ if (!card) { ++ printk(KERN_CRIT hfc_DRIVER_PREFIX ++ "spurious interrupt (IRQ %d)\n", ++ irq); ++ return IRQ_NONE; ++ } ++ ++ spin_lock_irqsave(&card->lock, flags); ++ status = hfc_inb(card, hfc_STATUS); ++ if (!(status & hfc_STATUS_ANYINT)) { ++ /* ++ * maybe we are sharing the irq ++ */ ++ spin_unlock_irqrestore(&card->lock, flags); ++ return IRQ_NONE; ++ } ++ ++ /* We used to ingore the IRQ when the card was in processing ++ * state but apparently there is no restriction to access the ++ * card in such state: ++ * ++ * Joerg Ciesielski wrote: ++ * > There is no restriction for the IRQ handler to access ++ * > HFC-S PCI during processing phase. A IRQ latency of 375 us ++ * > is also no problem since there are no interrupt sources in ++ * > HFC-S PCI which must be handled very fast. ++ * > Due to its deep fifos the IRQ latency can be several ms with ++ * > out the risk of loosing data. Even the S/T state interrupts ++ * > must not be handled with a latency less than <5ms. ++ * > ++ * > The processing phase only indicates that HFC-S PCI is ++ * > processing the Fifos as PCI master so that data is read and ++ * > written in the 32k memory window. But there is no restriction ++ * > to access data in the memory window during this time. ++ * ++ * // if (status & hfc_STATUS_PCI_PROC) { ++ * // return IRQ_HANDLED; ++ * // } ++ */ ++ ++ s1 = hfc_inb(card, hfc_INT_S1); ++ s2 = hfc_inb(card, hfc_INT_S2); ++ ++ if (s1 != 0) { ++ if (s1 & hfc_INTS_TIMER) { ++ /* ++ * timer (bit 7) ++ */ ++ hfc_handle_timer_interrupt(card); ++ } ++ ++ if (s1 & hfc_INTS_L1STATE) { ++ /* ++ * state machine (bit 6) ++ */ ++ hfc_handle_state_interrupt(card); ++ } ++ ++ if (s1 & hfc_INTS_DREC) { ++ /* ++ * D chan RX (bit 5) ++ */ ++ hfc_frame_arrived(&card->chans[D]); ++ } ++ ++ if (s1 & hfc_INTS_B1REC) { ++ /* ++ * B1 chan RX (bit 3) ++ */ ++ hfc_frame_arrived(&card->chans[B1]); ++ } ++ ++ if (s1 & hfc_INTS_B2REC) { ++ /* ++ * B2 chan RX (bit 4) ++ */ ++ hfc_frame_arrived(&card->chans[B2]); ++ } ++ ++ if (s1 & hfc_INTS_DTRANS) { ++ /* ++ * D chan TX (bit 2) ++ */ ++ } ++ ++ if (s1 & hfc_INTS_B1TRANS) { ++ /* ++ * B1 chan TX (bit 0) ++ */ ++ } ++ ++ if (s1 & hfc_INTS_B2TRANS) { ++ /* ++ * B2 chan TX (bit 1) ++ */ ++ } ++ ++ } ++ ++ if (s2 != 0) { ++ if (s2 & hfc_M2_PMESEL) { ++ /* ++ * kaboom irq (bit 7) ++ * ++ * CologneChip says: ++ * ++ * the meaning of this fatal error bit is that HFC-S ++ * PCI as PCI master could not access the PCI bus ++ * within 125us to finish its data processing. If this ++ * happens only very seldom it does not cause big ++ * problems but of course some B-channel or D-channel ++ * data will be corrupted due to this event. ++ * ++ * Unfortunately this bit is only set once after the ++ * problem occurs and can only be reseted by a ++ * software reset. That means it is not easily ++ * possible to check how often this fatal error ++ * happens. ++ * ++ */ ++ ++ if (!card->sync_loss_reported) { ++ printk(KERN_CRIT hfc_DRIVER_PREFIX ++ "card %d: " ++ "sync lost, pci performance too low!\n", ++ card->cardnum); ++ ++ card->sync_loss_reported = TRUE; ++ } ++ } ++ ++ if (s2 & hfc_M2_GCI_MON_REC) { ++ /* ++ * RxR monitor channel (bit 2) ++ */ ++ } ++ ++ if (s2 & hfc_M2_GCI_I_CHG) { ++ /* ++ * GCI I-change (bit 1) ++ */ ++ } ++ ++ if (s2 & hfc_M2_PROC_TRANS) { ++ /* ++ * processing/non-processing transition (bit 0) ++ */ ++ hfc_handle_processing_interrupt(card); ++ } ++ ++ } ++ ++ spin_unlock_irqrestore(&card->lock, flags); ++ ++ return IRQ_HANDLED; ++} ++ ++static void hfc_handle_timer_interrupt(struct hfc_card *card) ++{ ++ if (card->ignore_first_timer_interrupt) { ++ card->ignore_first_timer_interrupt = FALSE; ++ return; ++ } ++ ++ if ((card->nt_mode && card->l1_state == 3) || ++ (!card->nt_mode && card->l1_state == 7)) { ++ ++ card->regs.ctmt &= ~hfc_CTMT_TIMER_MASK; ++ hfc_outb(card, hfc_CTMT, card->regs.ctmt); ++ ++ hfc_resume_fifo(card); ++ } ++} ++ ++static void hfc_handle_state_interrupt(struct hfc_card *card) ++{ ++ u8 new_state = hfc_inb(card, hfc_STATES) & hfc_STATES_STATE_MASK; ++ ++#ifdef DEBUG ++ if (debug_level >= 1) { ++ printk(KERN_DEBUG hfc_DRIVER_PREFIX ++ "card %d: " ++ "layer 1 state = %c%d\n", ++ card->cardnum, ++ card->nt_mode ? 'G' : 'F', ++ new_state); ++ } ++#endif ++ ++ if (card->nt_mode) { ++ /* ++ * NT mode ++ */ ++ ++ if (new_state == 3) { ++ /* ++ * fix to G3 state (see specs) ++ */ ++ hfc_outb(card, hfc_STATES, hfc_STATES_LOAD_STATE | 3); ++ } ++ ++ if (new_state == 3 && card->l1_state != 3) ++ hfc_resume_fifo(card); ++ ++ if (new_state != 3 && card->l1_state == 3) ++ hfc_suspend_fifo(card); ++ ++ } else { ++ if (new_state == 3) { ++ /* ++ * Keep L1 up... zaptel & libpri expects ++ * a always up L1... ++ * Enable only when using an unpatched libpri ++ * ++ * Are we still using unpatched libpri? Is this tested at runtime??? ++ * Does it only affect zaptel or DAHDI, too? ++ */ ++ ++ if (force_l1_up) { ++ hfc_outb(card, hfc_STATES, ++ hfc_STATES_DO_ACTION | ++ hfc_STATES_ACTIVATE| ++ hfc_STATES_NT_G2_G3); ++ } ++ } ++ ++ if (new_state == 7 && card->l1_state != 7) { ++ /* ++ * TE is now active, schedule FIFO activation after ++ * some time, otherwise the first frames are lost ++ */ ++ ++ card->regs.ctmt |= hfc_CTMT_TIMER_50 | ++ hfc_CTMT_TIMER_CLEAR; ++ hfc_outb(card, hfc_CTMT, card->regs.ctmt); ++ ++ /* ++ * Activating the timer firest an ++ * interrupt immediately, we ++ * obviously need to ignore it ++ */ ++ card->ignore_first_timer_interrupt = TRUE; ++ } ++ ++ if (new_state != 7 && card->l1_state == 7) { ++ /* ++ * TE has become inactive, disable FIFO ++ */ ++ hfc_suspend_fifo(card); ++ } ++ } ++ ++ card->l1_state = new_state; ++} ++ ++static void hfc_handle_processing_interrupt(struct hfc_card *card) ++{ ++ int available_bytes = 0; ++ ++ /* ++ * Synchronize with the first enabled channel ++ */ ++ if (card->regs.fifo_en & hfc_FIFOEN_B1RX) ++ available_bytes = hfc_fifo_used_rx(&card->chans[B1].rx); ++ if (card->regs.fifo_en & hfc_FIFOEN_B2RX) ++ available_bytes = hfc_fifo_used_rx(&card->chans[B2].rx); ++ else ++ available_bytes = -1; ++ ++ if ((available_bytes == -1 && card->ticks == 8) || ++ available_bytes >= DAHDI_CHUNKSIZE + hfc_RX_FIFO_PRELOAD) { ++ card->ticks = 0; ++ ++ if (available_bytes > DAHDI_CHUNKSIZE*2 + hfc_RX_FIFO_PRELOAD) { ++ card->late_irqs++; ++ /* ++ * we are out of sync, clear fifos, jaw ++ */ ++ hfc_clear_fifo_rx(&card->chans[B1].rx); ++ hfc_clear_fifo_tx(&card->chans[B1].tx); ++ hfc_clear_fifo_rx(&card->chans[B2].rx); ++ hfc_clear_fifo_tx(&card->chans[B2].tx); ++ ++#ifdef DEBUG ++ if (debug_level >= 4) { ++ printk(KERN_DEBUG hfc_DRIVER_PREFIX ++ "card %d: " ++ "late IRQ, %d bytes late\n", ++ card->cardnum, ++ available_bytes - ++ (DAHDI_CHUNKSIZE + ++ hfc_RX_FIFO_PRELOAD)); ++ } ++#endif ++ } else { ++ hfc_handle_voice(card); ++ } ++ } ++ ++ card->ticks++; ++} ++ ++ ++static void hfc_handle_voice(struct hfc_card *card) ++{ ++ struct dahdi_hfc *hfccard = card->dahdi_dev; ++ int frame_left, res; ++ unsigned char buf[hfc_HDLC_BUF_LEN]; ++ unsigned int size = sizeof(buf) / sizeof(buf[0]); ++ ++ ++ if (card->chans[B1].status != open_voice && ++ card->chans[B2].status != open_voice) ++ return; ++ ++ dahdi_transmit(&hfccard->span); ++ ++ if (card->regs.fifo_en & hfc_FIFOEN_B1TX) ++ hfc_dahdi_transmit(&card->chans[B1].tx); ++ if (card->regs.fifo_en & hfc_FIFOEN_B2TX) ++ hfc_dahdi_transmit(&card->chans[B2].tx); ++ ++ /* ++ * dahdi hdlc frame tx ++ */ ++ ++ if (atomic_read(&hfccard->hdlc_pending)) { ++ hfc_check_l1_up(card); ++ res = dahdi_hdlc_getbuf(hfccard->sigchan, buf, &size); ++ if (size > 0) { ++ hfccard->sigactive = 1; ++ memcpy(card->chans[D].tx.ugly_framebuf + ++ card->chans[D].tx.ugly_framebuf_size, ++ buf, size); ++ card->chans[D].tx.ugly_framebuf_size += size; ++ if (res != 0) { ++ hfc_fifo_put_frame(&card->chans[D].tx, ++ card->chans[D].tx.ugly_framebuf, ++ card->chans[D].tx.ugly_framebuf_size); ++ ++hfccard->frames_out; ++ hfccard->sigactive = 0; ++ card->chans[D].tx.ugly_framebuf_size ++ = 0; ++ atomic_dec(&hfccard->hdlc_pending); ++ } ++ } ++ } ++ /* ++ * dahdi hdlc frame tx done ++ */ ++ ++ if (card->regs.fifo_en & hfc_FIFOEN_B1RX) ++ hfc_dahdi_receive(&card->chans[B1].rx); ++ else ++ memset(&card->chans[B1].rx.dahdi_buffer, 0x7f, ++ sizeof(card->chans[B1].rx.dahdi_buffer)); ++ ++ if (card->regs.fifo_en & hfc_FIFOEN_B2RX) ++ hfc_dahdi_receive(&card->chans[B2].rx); ++ else ++ memset(&card->chans[B2].rx.dahdi_buffer, 0x7f, ++ sizeof(card->chans[B1].rx.dahdi_buffer)); ++ ++ /* ++ * Echo cancellation ++ */ ++ dahdi_ec_chunk(&hfccard->chans[DAHDI_B1], ++ card->chans[B1].rx.dahdi_buffer, ++ card->chans[B1].tx.dahdi_buffer); ++ dahdi_ec_chunk(&hfccard->chans[DAHDI_B2], ++ card->chans[B2].rx.dahdi_buffer, ++ card->chans[B2].tx.dahdi_buffer); ++ ++ /* ++ * dahdi hdlc frame rx ++ */ ++ if (hfc_fifo_has_frames(&card->chans[D].rx)) ++ hfc_frame_arrived(&card->chans[D]); ++ ++ if (card->chans[D].rx.ugly_framebuf_size) { ++ frame_left = card->chans[D].rx.ugly_framebuf_size - ++ card->chans[D].rx.ugly_framebuf_off ; ++ if (frame_left > hfc_HDLC_BUF_LEN) { ++ dahdi_hdlc_putbuf(hfccard->sigchan, ++ card->chans[D].rx.ugly_framebuf + ++ card->chans[D].rx.ugly_framebuf_off, ++ hfc_HDLC_BUF_LEN); ++ card->chans[D].rx.ugly_framebuf_off += ++ hfc_HDLC_BUF_LEN; ++ } else { ++ dahdi_hdlc_putbuf(hfccard->sigchan, ++ card->chans[D].rx.ugly_framebuf + ++ card->chans[D].rx.ugly_framebuf_off, ++ frame_left); ++ dahdi_hdlc_finish(hfccard->sigchan); ++ card->chans[D].rx.ugly_framebuf_size = 0; ++ card->chans[D].rx.ugly_framebuf_off = 0; ++ } ++ } ++ /* ++ * dahdi hdlc frame rx done ++ */ ++ ++ if (hfccard->span.flags & DAHDI_FLAG_RUNNING) ++ dahdi_receive(&hfccard->span); ++ ++} ++ ++static void hfc_frame_arrived(struct hfc_chan_duplex *chan) ++{ ++ struct hfc_card *card = chan->card; ++ int antiloop = 16; ++ struct sk_buff *skb; ++ ++ while (hfc_fifo_has_frames(&chan->rx) && --antiloop) { ++ int frame_size = hfc_fifo_get_frame_size(&chan->rx); ++ ++ if (frame_size < 3) { ++#ifdef DEBUG ++ if (debug_level >= 2) ++ printk(KERN_DEBUG hfc_DRIVER_PREFIX ++ "card %d: " ++ "chan %s: " ++ "invalid frame received, " ++ "just %d bytes\n", ++ card->cardnum, ++ chan->name, ++ frame_size); ++#endif ++ ++ hfc_fifo_drop_frame(&chan->rx); ++ ++ ++ continue; ++ } else if (frame_size == 3) { ++#ifdef DEBUG ++ if (debug_level >= 2) ++ printk(KERN_DEBUG hfc_DRIVER_PREFIX ++ "card %d: " ++ "chan %s: " ++ "empty frame received\n", ++ card->cardnum, ++ chan->name); ++#endif ++ ++ hfc_fifo_drop_frame(&chan->rx); ++ ++ ++ continue; ++ } ++ ++ if (chan->open_by_dahdi && ++ card->chans[D].rx.ugly_framebuf_size) { ++ ++ /* ++ * We have to wait for Dahdi to transmit the ++ * frame... wait for next time ++ */ ++ ++ break; ++ } ++ ++ skb = dev_alloc_skb(frame_size - 3); ++ ++ if (!skb) { ++ printk(KERN_ERR hfc_DRIVER_PREFIX ++ "card %d: " ++ "chan %s: " ++ "cannot allocate skb: frame dropped\n", ++ card->cardnum, ++ chan->name); ++ ++ hfc_fifo_drop_frame(&chan->rx); ++ ++ ++ continue; ++ } ++ ++ ++ /* ++ * HFC does the checksum ++ */ ++#ifndef CHECKSUM_HW ++ skb->ip_summed = CHECKSUM_COMPLETE; ++#else ++ skb->ip_summed = CHECKSUM_HW; ++#endif ++ ++ if (chan->open_by_dahdi) { ++ card->chans[D].rx.ugly_framebuf_size = frame_size - 1; ++ ++ if (hfc_fifo_get_frame(&card->chans[D].rx, ++ card->chans[D].rx.ugly_framebuf, ++ frame_size - 1) == -1) { ++ dev_kfree_skb(skb); ++ continue; ++ } ++ ++ memcpy(skb_put(skb, frame_size - 3), ++ card->chans[D].rx.ugly_framebuf, ++ frame_size - 3); ++ } else { ++ if (hfc_fifo_get_frame(&chan->rx, ++ skb_put(skb, frame_size - 3), ++ frame_size - 3) == -1) { ++ dev_kfree_skb(skb); ++ continue; ++ } ++ } ++ } ++ ++ if (!antiloop) ++ printk(KERN_CRIT hfc_DRIVER_PREFIX ++ "card %d: " ++ "Infinite loop detected\n", ++ card->cardnum); ++} ++ ++/****************************************** ++ * Module initialization and cleanup ++ ******************************************/ ++ ++static int __devinit hfc_probe(struct pci_dev *pci_dev, ++ const struct pci_device_id *ent) ++{ ++ static int cardnum; ++ int err; ++ int i; ++ ++ struct hfc_card *card = NULL; ++ struct dahdi_hfc *dahdi_hfcs = NULL; ++ card = kmalloc(sizeof(struct hfc_card), GFP_KERNEL); ++ if (!card) { ++ printk(KERN_CRIT hfc_DRIVER_PREFIX ++ "unable to kmalloc!\n"); ++ err = -ENOMEM; ++ goto err_alloc_hfccard; ++ } ++ ++ memset(card, 0x00, sizeof(struct hfc_card)); ++ card->cardnum = cardnum; ++ card->pcidev = pci_dev; ++ spin_lock_init(&card->lock); ++ ++ pci_set_drvdata(pci_dev, card); ++ ++ err = pci_enable_device(pci_dev); ++ if (err) ++ goto err_pci_enable_device; ++ ++ err = pci_set_dma_mask(pci_dev, PCI_DMA_32BIT); ++ if (err) { ++ printk(KERN_ERR hfc_DRIVER_PREFIX ++ "card %d: " ++ "No suitable DMA configuration available.\n", ++ card->cardnum); ++ goto err_pci_set_dma_mask; ++ } ++ ++ pci_write_config_word(pci_dev, PCI_COMMAND, PCI_COMMAND_MEMORY); ++ err = pci_request_regions(pci_dev, hfc_DRIVER_NAME); ++ if (err) { ++ printk(KERN_CRIT hfc_DRIVER_PREFIX ++ "card %d: " ++ "cannot request I/O memory region\n", ++ card->cardnum); ++ goto err_pci_request_regions; ++ } ++ ++ pci_set_master(pci_dev); ++ ++ if (!pci_dev->irq) { ++ printk(KERN_CRIT hfc_DRIVER_PREFIX ++ "card %d: " ++ "no irq!\n", ++ card->cardnum); ++ err = -ENODEV; ++ goto err_noirq; ++ } ++ ++ card->io_bus_mem = pci_resource_start(pci_dev, 1); ++ if (!card->io_bus_mem) { ++ printk(KERN_CRIT hfc_DRIVER_PREFIX ++ "card %d: " ++ "no iomem!\n", ++ card->cardnum); ++ err = -ENODEV; ++ goto err_noiobase; ++ } ++ ++ card->io_mem = ioremap(card->io_bus_mem, hfc_PCI_MEM_SIZE); ++ if (!(card->io_mem)) { ++ printk(KERN_CRIT hfc_DRIVER_PREFIX ++ "card %d: " ++ "cannot ioremap I/O memory\n", ++ card->cardnum); ++ err = -ENODEV; ++ goto err_ioremap; ++ } ++ ++ /* ++ * pci_alloc_consistent guarantees alignment ++ * (Documentation/DMA-mapping.txt) ++ */ ++ card->fifo_mem = pci_alloc_consistent(pci_dev, ++ hfc_FIFO_SIZE, &card->fifo_bus_mem); ++ if (!card->fifo_mem) { ++ printk(KERN_CRIT hfc_DRIVER_PREFIX ++ "card %d: " ++ "unable to allocate FIFO DMA memory!\n", ++ card->cardnum); ++ err = -ENOMEM; ++ goto err_alloc_fifo; ++ } ++ ++ memset(card->fifo_mem, 0x00, hfc_FIFO_SIZE); ++ ++ card->fifos = card->fifo_mem; ++ ++ pci_write_config_dword(card->pcidev, hfc_PCI_MWBA, card->fifo_bus_mem); ++ ++ err = request_irq(card->pcidev->irq, &hfc_interrupt, ++ ++#if (KERNEL_VERSION(2, 6, 23) < LINUX_VERSION_CODE) ++ IRQF_SHARED, hfc_DRIVER_NAME, card); ++#else ++ SA_SHIRQ, hfc_DRIVER_NAME, card); ++#endif ++ ++ if (err) { ++ printk(KERN_CRIT hfc_DRIVER_PREFIX ++ "card %d: " ++ "unable to register irq\n", ++ card->cardnum); ++ goto err_request_irq; ++ } ++ ++ card->nt_mode = FALSE; ++ ++ if (modes & (1 << card->cardnum)) ++ card->nt_mode = TRUE; ++ ++ for (i = 0; i < nt_modes_count; i++) { ++ if (nt_modes[i] == card->cardnum) ++ card->nt_mode = TRUE; ++ } ++ ++ /* ++ * D Channel ++ */ ++ card->chans[D].card = card; ++ card->chans[D].name = "D"; ++ card->chans[D].status = free; ++ card->chans[D].number = D; ++ spin_lock_init(&card->chans[D].lock); ++ ++ card->chans[D].rx.chan = &card->chans[D]; ++ card->chans[D].rx.fifo_base = card->fifos + 0x4000; ++ card->chans[D].rx.z_base = card->fifos + 0x4000; ++ card->chans[D].rx.z1_base = card->fifos + 0x6080; ++ card->chans[D].rx.z2_base = card->fifos + 0x6082; ++ card->chans[D].rx.z_min = 0x0000; ++ card->chans[D].rx.z_max = 0x01FF; ++ card->chans[D].rx.f_min = 0x10; ++ card->chans[D].rx.f_max = 0x1F; ++ card->chans[D].rx.f1 = card->fifos + 0x60a0; ++ card->chans[D].rx.f2 = card->fifos + 0x60a1; ++ card->chans[D].rx.fifo_size = card->chans[D].rx.z_max ++ - card->chans[D].rx.z_min + 1; ++ card->chans[D].rx.f_num = card->chans[D].rx.f_max ++ - card->chans[D].rx.f_min + 1; ++ ++ card->chans[D].tx.chan = &card->chans[D]; ++ card->chans[D].tx.fifo_base = card->fifos + 0x0000; ++ card->chans[D].tx.z_base = card->fifos + 0x0000; ++ card->chans[D].tx.z1_base = card->fifos + 0x2080; ++ card->chans[D].tx.z2_base = card->fifos + 0x2082; ++ card->chans[D].tx.z_min = 0x0000; ++ card->chans[D].tx.z_max = 0x01FF; ++ card->chans[D].tx.f_min = 0x10; ++ card->chans[D].tx.f_max = 0x1F; ++ card->chans[D].tx.f1 = card->fifos + 0x20a0; ++ card->chans[D].tx.f2 = card->fifos + 0x20a1; ++ card->chans[D].tx.fifo_size = card->chans[D].tx.z_max - ++ card->chans[D].tx.z_min + 1; ++ card->chans[D].tx.f_num = card->chans[D].tx.f_max - ++ card->chans[D].tx.f_min + 1; ++ ++ /* ++ * B1 Channel ++ */ ++ card->chans[B1].card = card; ++ card->chans[B1].name = "B1"; ++ card->chans[B1].status = free; ++ card->chans[B1].number = B1; ++ card->chans[B1].protocol = 0; ++ spin_lock_init(&card->chans[B1].lock); ++ ++ card->chans[B1].rx.chan = &card->chans[B1]; ++ card->chans[B1].rx.fifo_base = card->fifos + 0x4200; ++ card->chans[B1].rx.z_base = card->fifos + 0x4000; ++ card->chans[B1].rx.z1_base = card->fifos + 0x6000; ++ card->chans[B1].rx.z2_base = card->fifos + 0x6002; ++ card->chans[B1].rx.z_min = 0x0200; ++ card->chans[B1].rx.z_max = 0x1FFF; ++ card->chans[B1].rx.f_min = 0x00; ++ card->chans[B1].rx.f_max = 0x1F; ++ card->chans[B1].rx.f1 = card->fifos + 0x6080; ++ card->chans[B1].rx.f2 = card->fifos + 0x6081; ++ card->chans[B1].rx.fifo_size = card->chans[B1].rx.z_max - ++ card->chans[B1].rx.z_min + 1; ++ card->chans[B1].rx.f_num = card->chans[B1].rx.f_max - ++ card->chans[B1].rx.f_min + 1; ++ ++ card->chans[B1].tx.chan = &card->chans[B1]; ++ card->chans[B1].tx.fifo_base = card->fifos + 0x0200; ++ card->chans[B1].tx.z_base = card->fifos + 0x0000; ++ card->chans[B1].tx.z1_base = card->fifos + 0x2000; ++ card->chans[B1].tx.z2_base = card->fifos + 0x2002; ++ card->chans[B1].tx.z_min = 0x0200; ++ card->chans[B1].tx.z_max = 0x1FFF; ++ card->chans[B1].tx.f_min = 0x00; ++ card->chans[B1].tx.f_max = 0x1F; ++ card->chans[B1].tx.f1 = card->fifos + 0x2080; ++ card->chans[B1].tx.f2 = card->fifos + 0x2081; ++ card->chans[B1].tx.fifo_size = card->chans[B1].tx.z_max - ++ card->chans[B1].tx.z_min + 1; ++ card->chans[B1].tx.f_num = card->chans[B1].tx.f_max - ++ card->chans[B1].tx.f_min + 1; ++ ++ /* ++ * B2 Channel ++ */ ++ card->chans[B2].card = card; ++ card->chans[B2].name = "B2"; ++ card->chans[B2].status = free; ++ card->chans[B2].number = B2; ++ card->chans[B2].protocol = 0; ++ spin_lock_init(&card->chans[B2].lock); ++ ++ card->chans[B2].rx.chan = &card->chans[B2]; ++ card->chans[B2].rx.fifo_base = card->fifos + 0x6200, ++ card->chans[B2].rx.z_base = card->fifos + 0x6000; ++ card->chans[B2].rx.z1_base = card->fifos + 0x6100; ++ card->chans[B2].rx.z2_base = card->fifos + 0x6102; ++ card->chans[B2].rx.z_min = 0x0200; ++ card->chans[B2].rx.z_max = 0x1FFF; ++ card->chans[B2].rx.f_min = 0x00; ++ card->chans[B2].rx.f_max = 0x1F; ++ card->chans[B2].rx.f1 = card->fifos + 0x6180; ++ card->chans[B2].rx.f2 = card->fifos + 0x6181; ++ card->chans[B2].rx.fifo_size = card->chans[B2].rx.z_max - ++ card->chans[B2].rx.z_min + 1; ++ card->chans[B2].rx.f_num = card->chans[B2].rx.f_max - ++ card->chans[B2].rx.f_min + 1; ++ ++ card->chans[B2].tx.chan = &card->chans[B2]; ++ card->chans[B2].tx.fifo_base = card->fifos + 0x2200; ++ card->chans[B2].tx.z_base = card->fifos + 0x2000; ++ card->chans[B2].tx.z1_base = card->fifos + 0x2100; ++ card->chans[B2].tx.z2_base = card->fifos + 0x2102; ++ card->chans[B2].tx.z_min = 0x0200; ++ card->chans[B2].tx.z_max = 0x1FFF; ++ card->chans[B2].tx.f_min = 0x00; ++ card->chans[B2].tx.f_max = 0x1F; ++ card->chans[B2].tx.f1 = card->fifos + 0x2180; ++ card->chans[B2].tx.f2 = card->fifos + 0x2181; ++ card->chans[B2].tx.fifo_size = card->chans[B2].tx.z_max - ++ card->chans[B2].tx.z_min + 1; ++ card->chans[B2].tx.f_num = card->chans[B2].tx.f_max - ++ card->chans[B2].tx.f_min + 1; ++ ++ /* ++ * All done ++ */ ++ ++ dahdi_hfcs = kmalloc(sizeof(struct dahdi_hfc), GFP_KERNEL); ++ if (!dahdi_hfcs) { ++ printk(KERN_CRIT hfc_DRIVER_PREFIX ++ "unable to kmalloc!\n"); ++ goto err_request_irq; ++ } ++ memset(dahdi_hfcs, 0x0, sizeof(struct dahdi_hfc)); ++ ++ dahdi_hfcs->card = card; ++ hfc_dahdi_initialize(dahdi_hfcs); ++ card->dahdi_dev = dahdi_hfcs; ++ ++ snprintf(card->proc_dir_name, ++ sizeof(card->proc_dir_name), ++ "%d", card->cardnum); ++ card->proc_dir = proc_mkdir(card->proc_dir_name, hfc_proc_dahdi_hfcs_dir); ++ SET_PROC_DIRENTRY_OWNER(card->proc_dir); ++ ++ hfc_resetCard(card); ++ ++ printk(KERN_INFO hfc_DRIVER_PREFIX ++ "card %d configured for %s mode at mem %#lx (0x%p) IRQ %u\n", ++ card->cardnum, ++ card->nt_mode ? "NT" : "TE", ++ card->io_bus_mem, ++ card->io_mem, ++ card->pcidev->irq); ++ ++ cardnum++; ++ ++ return 0; ++ ++err_request_irq: ++ pci_free_consistent(pci_dev, hfc_FIFO_SIZE, ++ card->fifo_mem, card->fifo_bus_mem); ++err_alloc_fifo: ++ iounmap(card->io_mem); ++err_ioremap: ++err_noiobase: ++err_noirq: ++ pci_release_regions(pci_dev); ++err_pci_request_regions: ++err_pci_set_dma_mask: ++err_pci_enable_device: ++ kfree(card); ++err_alloc_hfccard: ++ return err; ++} ++ ++static void __devexit hfc_remove(struct pci_dev *pci_dev) ++{ ++ struct hfc_card *card = pci_get_drvdata(pci_dev); ++ ++ ++ printk(KERN_INFO hfc_DRIVER_PREFIX ++ "card %d: " ++ "shutting down card at %p.\n", ++ card->cardnum, ++ card->io_mem); ++ ++ if (!card) { ++ return; ++ } ++ ++ hfc_softreset(card); ++ ++ dahdi_unregister_device(card->dahdi_dev->ddev); ++ ++ ++ /* ++ * disable memio and bustmaster ++ */ ++ pci_write_config_word(pci_dev, PCI_COMMAND, 0); ++ ++/* ++BUG: these proc entries just cause Call traces, so removed. ++ remove_proc_entry("bufs", card->proc_dir); ++ remove_proc_entry("fifos", card->proc_dir); ++ remove_proc_entry("info", card->proc_dir); ++*/ ++ remove_proc_entry(card->proc_dir_name, hfc_proc_dahdi_hfcs_dir); ++ ++ free_irq(pci_dev->irq, card); ++ ++ pci_free_consistent(pci_dev, hfc_FIFO_SIZE, ++ card->fifo_mem, card->fifo_bus_mem); ++ ++ iounmap(card->io_mem); ++ ++ pci_release_regions(pci_dev); ++ ++ pci_disable_device(pci_dev); ++ ++ kfree(card); ++} ++ ++/****************************************** ++ * Module stuff ++ ******************************************/ ++ ++static int __init hfc_init_module(void) ++{ ++ int ret; ++ ++ printk(KERN_INFO hfc_DRIVER_PREFIX ++ hfc_DRIVER_STRING " loading\n"); ++#ifdef DEBUG ++printk(KERN_INFO hfc_DRIVER_PREFIX "Check /var/log/kern-debug.log for debugging output level %d.", debug_level); ++printk(KERN_DEBUG hfc_DRIVER_PREFIX "base.c is debugging."); ++#endif ++ ++#if (KERNEL_VERSION(2, 6, 26) <= LINUX_VERSION_CODE) ++ hfc_proc_dahdi_hfcs_dir = proc_mkdir(hfc_DRIVER_NAME, NULL); ++#else ++ hfc_proc_dahdi_hfcs_dir = proc_mkdir(hfc_DRIVER_NAME, proc_root_driver); ++#endif ++ ++ ret = pci_register_driver(&hfc_driver); ++ return ret; ++} ++ ++module_init(hfc_init_module); ++ ++static void __exit hfc_module_exit(void) ++{ ++ pci_unregister_driver(&hfc_driver); ++ ++#if (KERNEL_VERSION(2, 6, 26) <= LINUX_VERSION_CODE) ++ remove_proc_entry(hfc_DRIVER_NAME, NULL); ++#else ++ remove_proc_entry(hfc_DRIVER_NAME, proc_root_driver); ++#endif ++ ++ printk(KERN_INFO hfc_DRIVER_PREFIX ++ hfc_DRIVER_STRING " unloaded\n"); ++} ++ ++module_exit(hfc_module_exit); ++ ++#endif ++ ++MODULE_DESCRIPTION(hfc_DRIVER_DESCR); ++MODULE_AUTHOR("Jens Wilke , " ++ "Daniele (Vihai) Orlandi , " ++ "Jose A. Deniz "); ++MODULE_ALIAS("dahdi_hfcs"); ++#ifdef MODULE_LICENSE ++MODULE_LICENSE("GPL"); ++#endif ++ ++ ++module_param(modes, int, 0444); ++ ++#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 10) ++module_param_array(nt_modes, int, &nt_modes_count, 0444); ++#else ++module_param_array(nt_modes, int, nt_modes_count, 0444); ++#endif ++ ++module_param(force_l1_up, int, 0444); ++#ifdef DEBUG ++module_param(debug_level, int, 0444); ++#endif ++ ++MODULE_PARM_DESC(modes, "[Deprecated] bit-mask to configure NT mode"); ++MODULE_PARM_DESC(nt_modes, ++ "Comma-separated list of card IDs to configure in NT mode"); ++MODULE_PARM_DESC(force_l1_up, "Don't allow L1 to go down"); ++#ifdef DEBUG ++MODULE_PARM_DESC(debug_level, "Debug verbosity level"); ++#endif +--- /dev/null ++++ b/drivers/dahdi/hfcs/dahdi_hfcs.h +@@ -0,0 +1,419 @@ ++/* ++ * dahdi_hfcs.h - Dahdi driver for HFC-S PCI A based ISDN BRI cards ++ * ++ * Dahdi port by Jose A. Deniz ++ * ++ * Copyright (C) 2009 Jose A. Deniz ++ * Copyright (C) 2006 headissue GmbH; Jens Wilke ++ * Copyright (C) 2004 Daniele Orlandi ++ * Copyright (C) 2002, 2003, 2004, Junghanns.NET GmbH ++ * ++ * Jens Wilke ++ * ++ * Orginal author of this code is ++ * Daniele "Vihai" Orlandi ++ * ++ * Major rewrite of the driver made by ++ * Klaus-Peter Junghanns ++ * ++ * This program is free software and may be modified and ++ * distributed under the terms of the GNU Public License. ++ * ++ */ ++ ++#ifndef _HFC_ZAPHFC_H ++#define _HFC_ZAPHFC_H ++ ++#include ++ ++#define hfc_DRIVER_NAME "dahdi_hfcs" ++#define hfc_DRIVER_PREFIX hfc_DRIVER_NAME ": " ++#define hfc_DRIVER_DESCR "HFC-S PCI A ISDN" ++#define hfc_DRIVER_VERSION "1.42" ++#define hfc_DRIVER_STRING hfc_DRIVER_DESCR " (V" hfc_DRIVER_VERSION ")" ++ ++#define hfc_MAX_BOARDS 32 ++ ++#ifndef PCI_DMA_32BIT ++#define PCI_DMA_32BIT 0x00000000ffffffffULL ++#endif ++ ++#ifndef PCI_VENDOR_ID_SITECOM ++#define PCI_VENDOR_ID_SITECOM 0x182D ++#endif ++ ++#ifndef PCI_DEVICE_ID_SITECOM_3069 ++#define PCI_DEVICE_ID_SITECOM_3069 0x3069 ++#endif ++ ++#define hfc_RESET_DELAY 20 ++ ++#define hfc_CLKDEL_TE 0x0f /* CLKDEL in TE mode */ ++#define hfc_CLKDEL_NT 0x6c /* CLKDEL in NT mode */ ++ ++/* PCI memory mapped I/O */ ++ ++#define hfc_PCI_MEM_SIZE 0x0100 ++#define hfc_PCI_MWBA 0x80 ++ ++/* GCI/IOM bus monitor registers */ ++ ++#define hfc_C_I 0x08 ++#define hfc_TRxR 0x0C ++#define hfc_MON1_D 0x28 ++#define hfc_MON2_D 0x2C ++ ++ ++/* GCI/IOM bus timeslot registers */ ++ ++#define hfc_B1_SSL 0x80 ++#define hfc_B2_SSL 0x84 ++#define hfc_AUX1_SSL 0x88 ++#define hfc_AUX2_SSL 0x8C ++#define hfc_B1_RSL 0x90 ++#define hfc_B2_RSL 0x94 ++#define hfc_AUX1_RSL 0x98 ++#define hfc_AUX2_RSL 0x9C ++ ++/* GCI/IOM bus data registers */ ++ ++#define hfc_B1_D 0xA0 ++#define hfc_B2_D 0xA4 ++#define hfc_AUX1_D 0xA8 ++#define hfc_AUX2_D 0xAC ++ ++/* GCI/IOM bus configuration registers */ ++ ++#define hfc_MST_EMOD 0xB4 ++#define hfc_MST_MODE 0xB8 ++#define hfc_CONNECT 0xBC ++ ++ ++/* Interrupt and status registers */ ++ ++#define hfc_FIFO_EN 0x44 ++#define hfc_TRM 0x48 ++#define hfc_B_MODE 0x4C ++#define hfc_CHIP_ID 0x58 ++#define hfc_CIRM 0x60 ++#define hfc_CTMT 0x64 ++#define hfc_INT_M1 0x68 ++#define hfc_INT_M2 0x6C ++#define hfc_INT_S1 0x78 ++#define hfc_INT_S2 0x7C ++#define hfc_STATUS 0x70 ++ ++/* S/T section registers */ ++ ++#define hfc_STATES 0xC0 ++#define hfc_SCTRL 0xC4 ++#define hfc_SCTRL_E 0xC8 ++#define hfc_SCTRL_R 0xCC ++#define hfc_SQ 0xD0 ++#define hfc_CLKDEL 0xDC ++#define hfc_B1_REC 0xF0 ++#define hfc_B1_SEND 0xF0 ++#define hfc_B2_REC 0xF4 ++#define hfc_B2_SEND 0xF4 ++#define hfc_D_REC 0xF8 ++#define hfc_D_SEND 0xF8 ++#define hfc_E_REC 0xFC ++ ++/* Bits and values in various HFC PCI registers */ ++ ++/* bits in status register (READ) */ ++#define hfc_STATUS_PCI_PROC 0x02 ++#define hfc_STATUS_NBUSY 0x04 ++#define hfc_STATUS_TIMER_ELAP 0x10 ++#define hfc_STATUS_STATINT 0x20 ++#define hfc_STATUS_FRAMEINT 0x40 ++#define hfc_STATUS_ANYINT 0x80 ++ ++/* bits in CTMT (Write) */ ++#define hfc_CTMT_TRANSB1 0x01 ++#define hfc_CTMT_TRANSB2 0x02 ++#define hfc_CTMT_TIMER_CLEAR 0x80 ++#define hfc_CTMT_TIMER_MASK 0x1C ++#define hfc_CTMT_TIMER_3_125 (0x01 << 2) ++#define hfc_CTMT_TIMER_6_25 (0x02 << 2) ++#define hfc_CTMT_TIMER_12_5 (0x03 << 2) ++#define hfc_CTMT_TIMER_25 (0x04 << 2) ++#define hfc_CTMT_TIMER_50 (0x05 << 2) ++#define hfc_CTMT_TIMER_400 (0x06 << 2) ++#define hfc_CTMT_TIMER_800 (0x07 << 2) ++#define hfc_CTMT_AUTO_TIMER 0x20 ++ ++/* bits in CIRM (Write) */ ++#define hfc_CIRM_AUX_MSK 0x07 ++#define hfc_CIRM_RESET 0x08 ++#define hfc_CIRM_B1_REV 0x40 ++#define hfc_CIRM_B2_REV 0x80 ++ ++/* bits in INT_M1 and INT_S1 */ ++#define hfc_INTS_B1TRANS 0x01 ++#define hfc_INTS_B2TRANS 0x02 ++#define hfc_INTS_DTRANS 0x04 ++#define hfc_INTS_B1REC 0x08 ++#define hfc_INTS_B2REC 0x10 ++#define hfc_INTS_DREC 0x20 ++#define hfc_INTS_L1STATE 0x40 ++#define hfc_INTS_TIMER 0x80 ++ ++/* bits in INT_M2 */ ++#define hfc_M2_PROC_TRANS 0x01 ++#define hfc_M2_GCI_I_CHG 0x02 ++#define hfc_M2_GCI_MON_REC 0x04 ++#define hfc_M2_IRQ_ENABLE 0x08 ++#define hfc_M2_PMESEL 0x80 ++ ++/* bits in STATES */ ++#define hfc_STATES_STATE_MASK 0x0F ++#define hfc_STATES_LOAD_STATE 0x10 ++#define hfc_STATES_ACTIVATE 0x20 ++#define hfc_STATES_DO_ACTION 0x40 ++#define hfc_STATES_NT_G2_G3 0x80 ++ ++/* bits in HFCD_MST_MODE */ ++#define hfc_MST_MODE_MASTER 0x01 ++#define hfc_MST_MODE_SLAVE 0x00 ++/* remaining bits are for codecs control */ ++ ++/* bits in HFCD_SCTRL */ ++#define hfc_SCTRL_B1_ENA 0x01 ++#define hfc_SCTRL_B2_ENA 0x02 ++#define hfc_SCTRL_MODE_TE 0x00 ++#define hfc_SCTRL_MODE_NT 0x04 ++#define hfc_SCTRL_LOW_PRIO 0x08 ++#define hfc_SCTRL_SQ_ENA 0x10 ++#define hfc_SCTRL_TEST 0x20 ++#define hfc_SCTRL_NONE_CAP 0x40 ++#define hfc_SCTRL_PWR_DOWN 0x80 ++ ++/* bits in SCTRL_E */ ++#define hfc_SCTRL_E_AUTO_AWAKE 0x01 ++#define hfc_SCTRL_E_DBIT_1 0x04 ++#define hfc_SCTRL_E_IGNORE_COL 0x08 ++#define hfc_SCTRL_E_CHG_B1_B2 0x80 ++ ++/* bits in SCTRL_R */ ++#define hfc_SCTRL_R_B1_ENA 0x01 ++#define hfc_SCTRL_R_B2_ENA 0x02 ++ ++/* bits in FIFO_EN register */ ++#define hfc_FIFOEN_B1TX 0x01 ++#define hfc_FIFOEN_B1RX 0x02 ++#define hfc_FIFOEN_B2TX 0x04 ++#define hfc_FIFOEN_B2RX 0x08 ++#define hfc_FIFOEN_DTX 0x10 ++#define hfc_FIFOEN_DRX 0x20 ++ ++#define hfc_FIFOEN_B1 (hfc_FIFOEN_B1TX|hfc_FIFOEN_B1RX) ++#define hfc_FIFOEN_B2 (hfc_FIFOEN_B2TX|hfc_FIFOEN_B2RX) ++#define hfc_FIFOEN_D (hfc_FIFOEN_DTX|hfc_FIFOEN_DRX) ++ ++/* bits in the CONNECT register */ ++#define hfc_CONNECT_B1_HFC_from_ST 0x00 ++#define hfc_CONNECT_B1_HFC_from_GCI 0x01 ++#define hfc_CONNECT_B1_ST_from_HFC 0x00 ++#define hfc_CONNECT_B1_ST_from_GCI 0x02 ++#define hfc_CONNECT_B1_GCI_from_HFC 0x00 ++#define hfc_CONNECT_B1_GCI_from_ST 0x04 ++ ++#define hfc_CONNECT_B2_HFC_from_ST 0x00 ++#define hfc_CONNECT_B2_HFC_from_GCI 0x08 ++#define hfc_CONNECT_B2_ST_from_HFC 0x00 ++#define hfc_CONNECT_B2_ST_from_GCI 0x10 ++#define hfc_CONNECT_B2_GCI_from_HFC 0x00 ++#define hfc_CONNECT_B2_GCI_from_ST 0x20 ++ ++/* bits in the TRM register */ ++#define hfc_TRM_TRANS_INT_00 0x00 ++#define hfc_TRM_TRANS_INT_01 0x01 ++#define hfc_TRM_TRANS_INT_10 0x02 ++#define hfc_TRM_TRANS_INT_11 0x04 ++#define hfc_TRM_ECHO 0x20 ++#define hfc_TRM_B1_PLUS_B2 0x40 ++#define hfc_TRM_IOM_TEST_LOOP 0x80 ++ ++/* bits in the __SSL and __RSL registers */ ++#define hfc_SRSL_STIO 0x40 ++#define hfc_SRSL_ENABLE 0x80 ++#define hfc_SRCL_SLOT_MASK 0x1f ++ ++/* FIFO memory definitions */ ++ ++#define hfc_FIFO_SIZE 0x8000 ++ ++#define hfc_UGLY_FRAMEBUF 0x2000 ++ ++#define hfc_TX_FIFO_PRELOAD (DAHDI_CHUNKSIZE + 2) ++#define hfc_RX_FIFO_PRELOAD 4 ++ ++/* HDLC STUFF */ ++#define hfc_HDLC_BUF_LEN 32 ++/* arbitrary, just the max # of byts we will send to DAHDI per call */ ++ ++ ++/* NOTE: FIFO pointers are not declared volatile because accesses to the ++ * FIFOs are inherently safe. ++ */ ++ ++#ifdef DEBUG ++extern int debug_level; ++#endif ++ ++struct hfc_chan; ++ ++struct hfc_chan_simplex { ++ struct hfc_chan_duplex *chan; ++ ++ u8 dahdi_buffer[DAHDI_CHUNKSIZE]; ++ ++ u8 ugly_framebuf[hfc_UGLY_FRAMEBUF]; ++ int ugly_framebuf_size; ++ u16 ugly_framebuf_off; ++ ++ void *z1_base, *z2_base; ++ void *fifo_base; ++ void *z_base; ++ u16 z_min; ++ u16 z_max; ++ u16 fifo_size; ++ ++ u8 *f1, *f2; ++ u8 f_min; ++ u8 f_max; ++ u8 f_num; ++ ++ unsigned long long frames; ++ unsigned long long bytes; ++ unsigned long long fifo_full; ++ unsigned long long crc; ++ unsigned long long fifo_underrun; ++}; ++ ++enum hfc_chan_status { ++ free, ++ open_framed, ++ open_voice, ++ sniff_aux, ++ loopback, ++}; ++ ++struct hfc_chan_duplex { ++ struct hfc_card *card; ++ ++ char *name; ++ int number; ++ ++ enum hfc_chan_status status; ++ int open_by_netdev; ++ int open_by_dahdi; ++ ++ unsigned short protocol; ++ ++ spinlock_t lock; ++ ++ struct hfc_chan_simplex rx; ++ struct hfc_chan_simplex tx; ++ ++}; ++ ++typedef struct hfc_card { ++ int cardnum; ++ struct pci_dev *pcidev; ++ struct dahdi_hfc *dahdi_dev; ++ struct proc_dir_entry *proc_dir; ++ char proc_dir_name[32]; ++ ++ struct proc_dir_entry *proc_info; ++ struct proc_dir_entry *proc_fifos; ++ struct proc_dir_entry *proc_bufs; ++ ++ unsigned long io_bus_mem; ++ void __iomem *io_mem; ++ ++ dma_addr_t fifo_bus_mem; ++ void *fifo_mem; ++ void *fifos; ++ ++ int nt_mode; ++ int sync_loss_reported; ++ int late_irqs; ++ ++ u8 l1_state; ++ int fifo_suspended; ++ int ignore_first_timer_interrupt; ++ ++ struct { ++ u8 m1; ++ u8 m2; ++ u8 fifo_en; ++ u8 trm; ++ u8 connect; ++ u8 sctrl; ++ u8 sctrl_r; ++ u8 sctrl_e; ++ u8 ctmt; ++ u8 cirm; ++ } regs; ++ ++ struct hfc_chan_duplex chans[3]; ++ int echo_enabled; ++ ++ ++ ++ int debug_event; ++ ++ spinlock_t lock; ++ unsigned int irq; ++ unsigned int iomem; ++ int ticks; ++ int clicks; ++ unsigned char *pci_io; ++ void *fifomem; /* start of the shared mem */ ++ ++ unsigned int pcibus; ++ unsigned int pcidevfn; ++ ++ int drecinframe; ++ ++ unsigned char cardno; ++ struct hfc_card *next; ++ ++} hfc_card; ++ ++typedef struct dahdi_hfc { ++ unsigned int usecount; ++ struct dahdi_device *ddev; ++ struct dahdi_span span; ++ struct dahdi_chan chans[3]; ++ struct dahdi_chan *_chans[3]; ++ struct hfc_card *card; ++ ++ /* pointer to the signalling channel for this span */ ++ struct dahdi_chan *sigchan; ++ /* nonzero means we're in the middle of sending an HDLC frame */ ++ int sigactive; ++ /* hdlc_hard_xmit() increments, hdlc_tx_frame() decrements */ ++ atomic_t hdlc_pending; ++ int frames_out; ++ int frames_in; ++ ++} dahdi_hfc; ++ ++static inline struct dahdi_hfc* dahdi_hfc_from_span(struct dahdi_span *span) { ++ return container_of(span, struct dahdi_hfc, span); ++} ++ ++static inline u8 hfc_inb(struct hfc_card *card, int offset) ++{ ++ return readb(card->io_mem + offset); ++} ++ ++static inline void hfc_outb(struct hfc_card *card, int offset, u8 value) ++{ ++ writeb(value, card->io_mem + offset); ++} ++ ++#endif +--- /dev/null ++++ b/drivers/dahdi/hfcs/fifo.c +@@ -0,0 +1,380 @@ ++/* ++ * fifo.c - HFC FIFO management routines ++ * ++ * Copyright (C) 2006 headissue GmbH; Jens Wilke ++ * Copyright (C) 2004 Daniele Orlandi ++ * Copyright (C) 2002, 2003, 2004, Junghanns.NET GmbH ++ * ++ * Original author of this code is ++ * Daniele "Vihai" Orlandi ++ * ++ * This program is free software and may be modified and ++ * distributed under the terms of the GNU Public License. ++ * ++ */ ++ ++#define DEBUG ++#ifdef DEBUG ++extern int debug_level; ++#endif ++ ++#include ++ ++#include ++ ++#include "fifo.h" ++ ++static void hfc_fifo_mem_read(struct hfc_chan_simplex *chan, ++ int z_start, ++ void *data, int size) ++{ ++ int bytes_to_boundary = chan->z_max - z_start + 1; ++ if (bytes_to_boundary >= size) { ++ memcpy(data, ++ chan->z_base + z_start, ++ size); ++ } else { ++ /* ++ * Buffer wrap ++ */ ++ memcpy(data, ++ chan->z_base + z_start, ++ bytes_to_boundary); ++ ++ memcpy(data + bytes_to_boundary, ++ chan->fifo_base, ++ size - bytes_to_boundary); ++ } ++} ++ ++static void hfc_fifo_mem_write(struct hfc_chan_simplex *chan, ++ void *data, int size) ++{ ++ int bytes_to_boundary = chan->z_max - *Z1_F1(chan) + 1; ++ if (bytes_to_boundary >= size) { ++ memcpy(chan->z_base + *Z1_F1(chan), ++ data, ++ size); ++ } else { ++ /* ++ * FIFO wrap ++ */ ++ ++ memcpy(chan->z_base + *Z1_F1(chan), ++ data, ++ bytes_to_boundary); ++ ++ memcpy(chan->fifo_base, ++ data + bytes_to_boundary, ++ size - bytes_to_boundary); ++ } ++} ++ ++int hfc_fifo_get(struct hfc_chan_simplex *chan, ++ void *data, int size) ++{ ++ int available_bytes; ++ ++ /* ++ * Some useless statistic ++ */ ++ chan->bytes += size; ++ ++ available_bytes = hfc_fifo_used_rx(chan); ++ ++ if (available_bytes < size && !chan->fifo_underrun++) { ++ /* ++ * print the warning only once ++ */ ++ printk(KERN_WARNING hfc_DRIVER_PREFIX ++ "card %d: " ++ "chan %s: " ++ "RX FIFO not enough (%d) bytes to receive!\n", ++ chan->chan->card->cardnum, ++ chan->chan->name, ++ available_bytes); ++ return -1; ++ } ++ ++ hfc_fifo_mem_read(chan, *Z2_F2(chan), data, size); ++ *Z2_F2(chan) = Z_inc(chan, *Z2_F2(chan), size); ++ return available_bytes - size; ++} ++ ++void hfc_fifo_put(struct hfc_chan_simplex *chan, ++ void *data, int size) ++{ ++ struct hfc_card *card = chan->chan->card; ++ int used_bytes = hfc_fifo_used_tx(chan); ++ int free_bytes = hfc_fifo_free_tx(chan); ++ ++ if (!used_bytes && !chan->fifo_underrun++) { ++ /* ++ * print warning only once, to make timing not worse ++ */ ++ printk(KERN_WARNING hfc_DRIVER_PREFIX ++ "card %d: " ++ "chan %s: " ++ "TX FIFO has become empty\n", ++ card->cardnum, ++ chan->chan->name); ++ } ++ if (free_bytes < size) { ++ printk(KERN_CRIT hfc_DRIVER_PREFIX ++ "card %d: " ++ "chan %s: " ++ "TX FIFO full!\n", ++ chan->chan->card->cardnum, ++ chan->chan->name); ++ chan->fifo_full++; ++ hfc_clear_fifo_tx(chan); ++ } ++ ++ hfc_fifo_mem_write(chan, data, size); ++ chan->bytes += size; ++ *Z1_F1(chan) = Z_inc(chan, *Z1_F1(chan), size); ++} ++ ++int hfc_fifo_get_frame(struct hfc_chan_simplex *chan, void *data, int max_size) ++{ ++ int frame_size; ++ u16 newz2 ; ++ ++ if (*chan->f1 == *chan->f2) { ++ /* ++ * nothing received, strange uh? ++ */ ++ printk(KERN_WARNING hfc_DRIVER_PREFIX ++ "card %d: " ++ "chan %s: " ++ "get_frame called with no frame in FIFO.\n", ++ chan->chan->card->cardnum, ++ chan->chan->name); ++ ++ return -1; ++ } ++ ++ /* ++ * frame_size includes CRC+CRC+STAT ++ */ ++ frame_size = hfc_fifo_get_frame_size(chan); ++ ++#ifdef DEBUG ++ if (debug_level == 3) { ++ printk(KERN_DEBUG hfc_DRIVER_PREFIX ++ "card %d: " ++ "chan %s: " ++ "RX len %2d: ", ++ chan->chan->card->cardnum, ++ chan->chan->name, ++ frame_size); ++ } else if (debug_level >= 4) { ++ printk(KERN_DEBUG hfc_DRIVER_PREFIX ++ "card %d: " ++ "chan %s: " ++ "RX (f1=%02x, f2=%02x, z1=%04x, z2=%04x) len %2d: ", ++ chan->chan->card->cardnum, ++ chan->chan->name, ++ *chan->f1, *chan->f2, *Z1_F2(chan), *Z2_F2(chan), ++ frame_size); ++ } ++ ++ if (debug_level >= 3) { ++ int i; ++ for (i = 0; i < frame_size; i++) { ++ printk("%02x", hfc_fifo_u8(chan, ++ Z_inc(chan, *Z2_F2(chan), i))); ++ } ++ ++ printk("\n"); ++ } ++#endif ++ ++ if (frame_size <= 0) { ++#ifdef DEBUG ++ if (debug_level >= 2) { ++ printk(KERN_DEBUG hfc_DRIVER_PREFIX ++ "card %d: " ++ "chan %s: " ++ "invalid (empty) frame received.\n", ++ chan->chan->card->cardnum, ++ chan->chan->name); ++ } ++#endif ++ ++ hfc_fifo_drop_frame(chan); ++ return -1; ++ } ++ ++ /* ++ * STAT is not really received ++ */ ++ chan->bytes += frame_size - 1; ++ ++ /* ++ * Calculate beginning of the next frame ++ */ ++ newz2 = Z_inc(chan, *Z2_F2(chan), frame_size); ++ ++ /* ++ * We cannot use hfc_fifo_get because of different semantic of ++ * "available bytes" and to avoid useless increment of Z2 ++ */ ++ hfc_fifo_mem_read(chan, *Z2_F2(chan), data, ++ frame_size < max_size ? frame_size : max_size); ++ ++ if (hfc_fifo_u8(chan, Z_inc(chan, *Z2_F2(chan), ++ frame_size - 1)) != 0x00) { ++ /* ++ * CRC not ok, frame broken, skipping ++ */ ++#ifdef DEBUG ++ if (debug_level >= 2) { ++ printk(KERN_WARNING hfc_DRIVER_PREFIX ++ "card %d: " ++ "chan %s: " ++ "Received frame with wrong CRC\n", ++ chan->chan->card->cardnum, ++ chan->chan->name); ++ } ++#endif ++ ++ chan->crc++; ++ ++ hfc_fifo_drop_frame(chan); ++ return -1; ++ } ++ ++ chan->frames++; ++ ++ *chan->f2 = F_inc(chan, *chan->f2, 1); ++ ++ /* ++ * Set Z2 for the next frame we're going to receive ++ */ ++ *Z2_F2(chan) = newz2; ++ ++ return frame_size; ++} ++ ++void hfc_fifo_drop_frame(struct hfc_chan_simplex *chan) ++{ ++ int available_bytes; ++ u16 newz2; ++ ++ if (*chan->f1 == *chan->f2) { ++ /* ++ * nothing received, strange eh? ++ */ ++ printk(KERN_WARNING hfc_DRIVER_PREFIX ++ "card %d: " ++ "chan %s: " ++ "skip_frame called with no frame in FIFO.\n", ++ chan->chan->card->cardnum, ++ chan->chan->name); ++ ++ return; ++ } ++ ++ available_bytes = hfc_fifo_used_rx(chan) + 1; ++ ++ /* ++ * Calculate beginning of the next frame ++ */ ++ newz2 = Z_inc(chan, *Z2_F2(chan), available_bytes); ++ ++ *chan->f2 = F_inc(chan, *chan->f2, 1); ++ ++ /* ++ * Set Z2 for the next frame we're going to receive ++ */ ++ *Z2_F2(chan) = newz2; ++} ++ ++void hfc_fifo_put_frame(struct hfc_chan_simplex *chan, ++ void *data, int size) ++{ ++ u16 newz1; ++ int available_frames; ++ ++#ifdef DEBUG ++ if (debug_level == 3) { ++ printk(KERN_DEBUG hfc_DRIVER_PREFIX ++ "card %d: " ++ "chan %s: " ++ "TX len %2d: ", ++ chan->chan->card->cardnum, ++ chan->chan->name, ++ size); ++ } else if (debug_level >= 4) { ++ printk(KERN_DEBUG hfc_DRIVER_PREFIX ++ "card %d: " ++ "chan %s: " ++ "TX (f1=%02x, f2=%02x, z1=%04x, z2=%04x) len %2d: ", ++ chan->chan->card->cardnum, ++ chan->chan->name, ++ *chan->f1, *chan->f2, *Z1_F1(chan), *Z2_F1(chan), ++ size); ++ } ++ ++ if (debug_level >= 3) { ++ int i; ++ for (i = 0; i < size; i++) ++ printk("%02x", ((u8 *)data)[i]); ++ ++ printk("\n"); ++ } ++#endif ++ ++ available_frames = hfc_fifo_free_frames(chan); ++ ++ if (available_frames >= chan->f_num) { ++ printk(KERN_CRIT hfc_DRIVER_PREFIX ++ "card %d: " ++ "chan %s: " ++ "TX FIFO total number of frames exceeded!\n", ++ chan->chan->card->cardnum, ++ chan->chan->name); ++ ++ chan->fifo_full++; ++ ++ return; ++ } ++ ++ hfc_fifo_put(chan, data, size); ++ ++ newz1 = *Z1_F1(chan); ++ ++ *chan->f1 = F_inc(chan, *chan->f1, 1); ++ ++ *Z1_F1(chan) = newz1; ++ ++ chan->frames++; ++} ++ ++void hfc_clear_fifo_rx(struct hfc_chan_simplex *chan) ++{ ++ *chan->f2 = *chan->f1; ++ *Z2_F2(chan) = *Z1_F2(chan); ++} ++ ++void hfc_clear_fifo_tx(struct hfc_chan_simplex *chan) ++{ ++ *chan->f1 = *chan->f2; ++ *Z1_F1(chan) = *Z2_F1(chan); ++ ++ if (chan->chan->status == open_voice) { ++ /* ++ * Make sure that at least hfc_TX_FIFO_PRELOAD bytes are ++ * present in the TX FIFOs ++ * Create hfc_TX_FIFO_PRELOAD bytes of empty data ++ * (0x7f is mute audio) ++ */ ++ u8 empty_fifo[hfc_TX_FIFO_PRELOAD + ++ DAHDI_CHUNKSIZE + hfc_RX_FIFO_PRELOAD]; ++ memset(empty_fifo, 0x7f, sizeof(empty_fifo)); ++ ++ hfc_fifo_put(chan, empty_fifo, sizeof(empty_fifo)); ++ } ++} ++ +--- /dev/null ++++ b/drivers/dahdi/hfcs/fifo.h +@@ -0,0 +1,139 @@ ++/* ++ * fifo.h - Dahdi driver for HFC-S PCI A based ISDN BRI cards ++ * ++ * Copyright (C) 2004 Daniele Orlandi ++ * Copyright (C) 2002, 2003, 2004, Junghanns.NET GmbH ++ * ++ * Daniele "Vihai" Orlandi ++ * ++ * Major rewrite of the driver made by ++ * Klaus-Peter Junghanns ++ * ++ * This program is free software and may be modified and ++ * distributed under the terms of the GNU Public License. ++ * ++ */ ++ ++#ifndef _HFC_FIFO_H ++#define _HFC_FIFO_H ++ ++#include "dahdi_hfcs.h" ++ ++static inline u16 *Z1_F1(struct hfc_chan_simplex *chan) ++{ ++ return chan->z1_base + (*chan->f1 * 4); ++} ++ ++static inline u16 *Z2_F1(struct hfc_chan_simplex *chan) ++{ ++ return chan->z2_base + (*chan->f1 * 4); ++} ++ ++static inline u16 *Z1_F2(struct hfc_chan_simplex *chan) ++{ ++ return chan->z1_base + (*chan->f2 * 4); ++} ++ ++static inline u16 *Z2_F2(struct hfc_chan_simplex *chan) ++{ ++ return chan->z2_base + (*chan->f2 * 4); ++} ++ ++static inline u16 Z_inc(struct hfc_chan_simplex *chan, u16 z, u16 inc) ++{ ++ /* ++ * declared as u32 in order to manage overflows ++ */ ++ u32 newz = z + inc; ++ if (newz > chan->z_max) ++ newz -= chan->fifo_size; ++ ++ return newz; ++} ++ ++static inline u8 F_inc(struct hfc_chan_simplex *chan, u8 f, u8 inc) ++{ ++ /* ++ * declared as u16 in order to manage overflows ++ */ ++ u16 newf = f + inc; ++ if (newf > chan->f_max) ++ newf -= chan->f_num; ++ ++ return newf; ++} ++ ++static inline u16 hfc_fifo_used_rx(struct hfc_chan_simplex *chan) ++{ ++ return (*Z1_F2(chan) - *Z2_F2(chan) + ++ chan->fifo_size) % chan->fifo_size; ++} ++ ++static inline u16 hfc_fifo_get_frame_size(struct hfc_chan_simplex *chan) ++{ ++ /* ++ * This +1 is needed because in frame mode the available bytes are Z2-Z1+1 ++ * while in transparent mode I wouldn't consider the byte pointed by Z2 to ++ * be available, otherwise, the FIFO would always contain one byte, even ++ * when Z1==Z2 ++ */ ++ ++ return hfc_fifo_used_rx(chan) + 1; ++} ++ ++static inline u8 hfc_fifo_u8(struct hfc_chan_simplex *chan, u16 z) ++{ ++ return *((u8 *)(chan->z_base + z)); ++} ++ ++static inline u16 hfc_fifo_used_tx(struct hfc_chan_simplex *chan) ++{ ++ return (*Z1_F1(chan) - *Z2_F1(chan) + ++ chan->fifo_size) % chan->fifo_size; ++} ++ ++static inline u16 hfc_fifo_free_rx(struct hfc_chan_simplex *chan) ++{ ++ u16 free_bytes = *Z2_F1(chan) - *Z1_F1(chan); ++ ++ if (free_bytes > 0) ++ return free_bytes; ++ else ++ return free_bytes + chan->fifo_size; ++} ++ ++static inline u16 hfc_fifo_free_tx(struct hfc_chan_simplex *chan) ++{ ++ u16 free_bytes = *Z2_F1(chan) - *Z1_F1(chan); ++ ++ if (free_bytes > 0) ++ return free_bytes; ++ else ++ return free_bytes + chan->fifo_size; ++} ++ ++static inline int hfc_fifo_has_frames(struct hfc_chan_simplex *chan) ++{ ++ return *chan->f1 != *chan->f2; ++} ++ ++static inline u8 hfc_fifo_used_frames(struct hfc_chan_simplex *chan) ++{ ++ return (*chan->f1 - *chan->f2 + chan->f_num) % chan->f_num; ++} ++ ++static inline u8 hfc_fifo_free_frames(struct hfc_chan_simplex *chan) ++{ ++ return (*chan->f2 - *chan->f1 + chan->f_num) % chan->f_num; ++} ++ ++int hfc_fifo_get(struct hfc_chan_simplex *chan, void *data, int size); ++void hfc_fifo_put(struct hfc_chan_simplex *chan, void *data, int size); ++void hfc_fifo_drop(struct hfc_chan_simplex *chan, int size); ++int hfc_fifo_get_frame(struct hfc_chan_simplex *chan, void *data, int max_size); ++void hfc_fifo_drop_frame(struct hfc_chan_simplex *chan); ++void hfc_fifo_put_frame(struct hfc_chan_simplex *chan, void *data, int size); ++void hfc_clear_fifo_rx(struct hfc_chan_simplex *chan); ++void hfc_clear_fifo_tx(struct hfc_chan_simplex *chan); ++ ++#endif +--- /dev/null ++++ b/drivers/dahdi/hfcs/Kbuild +@@ -0,0 +1,10 @@ ++obj-m += dahdi_hfcs.o ++ ++EXTRA_CFLAGS := -I$(src)/.. -Wno-undef ++ ++dahdi_hfcs-objs := base.o fifo.o ++ ++$(obj)/base.o: $(src)/dahdi_hfcs.h ++$(obj)/fifo.o: $(src)/fifo.h ++ ++ diff --git a/libs/dahdi-linux/patches/110-fix-uaccess_h-include.patch b/libs/dahdi-linux/patches/110-fix-uaccess_h-include.patch new file mode 100644 index 000000000..5357fa7f2 --- /dev/null +++ b/libs/dahdi-linux/patches/110-fix-uaccess_h-include.patch @@ -0,0 +1,77 @@ +--- a/drivers/dahdi/datamods/syncppp.c ++++ b/drivers/dahdi/datamods/syncppp.c +@@ -39,6 +39,7 @@ + + #include + #include ++#include + #include + #include + #include +@@ -56,7 +57,11 @@ + #include + + #include ++#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,18) + #include ++#else ++#include ++#endif + + #define MAXALIVECNT 6 /* max. alive packets */ + +--- a/drivers/dahdi/wcb4xxp/base.c ++++ b/drivers/dahdi/wcb4xxp/base.c +@@ -22,6 +22,7 @@ + + #include + ++#include + #include /* printk() */ + #include /* error codes */ + #include +@@ -35,7 +36,11 @@ + #include + #include /* dev_err() */ + #include ++#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,18) + #include /* copy_*_user */ ++#else ++#include ++#endif + #include /* work_struct */ + #include /* timer_struct */ + #include +--- a/drivers/dahdi/xpp/mmapdrv.c ++++ b/drivers/dahdi/xpp/mmapdrv.c +@@ -1,3 +1,4 @@ ++#include + #include + #include + #include +@@ -10,7 +11,11 @@ + #include + #include + #include ++#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,18) + #include ++#else ++#include ++#endif + #include + #include "mmapbus.h" + #include "xbus-core.h" +--- a/drivers/dahdi/xpp/xpp_usb.c ++++ b/drivers/dahdi/xpp/xpp_usb.c +@@ -27,7 +27,11 @@ + #include + #include /* for udelay */ + #include ++#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,18) + #include ++#else ++#include ++#endif + #include + #include + #include diff --git a/libs/dahdi-linux/patches/130-DAHLIN-371-pld-linux-math64.patch b/libs/dahdi-linux/patches/130-DAHLIN-371-pld-linux-math64.patch new file mode 100644 index 000000000..87351c5b0 --- /dev/null +++ b/libs/dahdi-linux/patches/130-DAHLIN-371-pld-linux-math64.patch @@ -0,0 +1,138 @@ +--- a/drivers/dahdi/xpp/xbus-core.c ++++ b/drivers/dahdi/xpp/xbus-core.c +@@ -25,6 +25,7 @@ + #include + #include + #include ++#include + #include + #include + #include +@@ -1768,11 +1769,13 @@ out: + + static void xbus_fill_proc_queue(struct seq_file *sfile, struct xframe_queue *q) + { ++ s32 rem; ++ s64 lag_sec = div_s64_rem(q->worst_lag_usec, 1000, &rem); + seq_printf(sfile, +- "%-15s: counts %3d, %3d, %3d worst %3d, overflows %3d worst_lag %02lld.%lld ms\n", ++ "%-15s: counts %3d, %3d, %3d worst %3d, overflows %3d worst_lag %02lld.%ld ms\n", + q->name, q->steady_state_count, q->count, q->max_count, +- q->worst_count, q->overflows, q->worst_lag_usec / 1000, +- q->worst_lag_usec % 1000); ++ q->worst_count, q->overflows, lag_sec, ++ rem); + xframe_queue_clearstats(q); + } + +--- a/drivers/dahdi/xpp/xbus-pcm.c ++++ b/drivers/dahdi/xpp/xbus-pcm.c +@@ -22,6 +22,7 @@ + #include + #include + #include ++#include + #include "xbus-pcm.h" + #include "xbus-core.h" + #include "xpp_dahdi.h" +@@ -129,7 +130,7 @@ static int xpp_ticker_step(struct xpp_ti + usec = ktime_us_delta(ticker->last_sample, + ticker->first_sample); + ticker->first_sample = ticker->last_sample; +- ticker->tick_period = usec / ticker->cycle; ++ ticker->tick_period = div_s64(usec, ticker->cycle); + cycled = 1; + } + ticker->count++; +@@ -497,7 +498,7 @@ static void send_drift(xbus_t *xbus, int + XBUS_DBG(SYNC, xbus, + "%sDRIFT adjust %s (%d) (last update %lld seconds ago)\n", + (disable_pll_sync) ? "Fake " : "", msg, drift, +- msec_delta / MSEC_PER_SEC); ++ div_s64(msec_delta, MSEC_PER_SEC)); + if (!disable_pll_sync) + CALL_PROTO(GLOBAL, SYNC_SOURCE, xbus, NULL, SYNC_MODE_PLL, + drift); +--- a/drivers/dahdi/xpp/xbus-sysfs.c ++++ b/drivers/dahdi/xpp/xbus-sysfs.c +@@ -23,6 +23,7 @@ + #include + #include + #include ++#include + #include + #ifdef PROTOCOL_DEBUG + #include +@@ -249,11 +250,9 @@ static DEVICE_ATTR_READER(driftinfo_show + /* + * Calculate lost ticks time + */ +- seconds = ktime_ms_delta(now, di->last_lost_tick) / 1000; +- minutes = seconds / 60; +- seconds = seconds % 60; +- hours = minutes / 60; +- minutes = minutes % 60; ++ seconds = div_s64(ktime_ms_delta(now, di->last_lost_tick), 1000); ++ minutes = div_s64_rem(seconds, 60, &seconds); ++ hours = div_s64_rem(minutes, 60, &minutes); + len += snprintf(buf + len, PAGE_SIZE - len, + "%-15s: %8d (was %d:%02d:%02d ago)\n", "lost_ticks", + di->lost_ticks, hours, minutes, seconds); +--- a/drivers/dahdi/xpp/xframe_queue.c ++++ b/drivers/dahdi/xpp/xframe_queue.c +@@ -1,3 +1,4 @@ ++#include + #include "xframe_queue.h" + #include "xbus-core.h" + #include "dahdi_debug.h" +@@ -40,10 +41,11 @@ static void __xframe_dump_queue(struct x + THIS_MODULE->name, q->name); + list_for_each_entry_reverse(xframe, &q->head, frame_list) { + xpacket_t *pack = (xpacket_t *)&xframe->packets[0]; +- s64 usec = ktime_us_delta(now, xframe->kt_queued); ++ s32 rem; ++ s64 sec = div_s64_rem(ktime_us_delta(now, xframe->kt_queued), 1000, &rem); + +- snprintf(prefix, ARRAY_SIZE(prefix), " %3d> %5lld.%03lld msec", +- i++, usec / 1000, usec % 1000); ++ snprintf(prefix, ARRAY_SIZE(prefix), " %3d> %5lld.%03ld msec", ++ i++, sec, rem); + dump_packet(prefix, pack, 1); + } + } +@@ -60,11 +62,13 @@ static bool __xframe_enqueue(struct xfra + if (q->count >= q->max_count) { + q->overflows++; + if ((overflow_cnt++ % 1000) < 5) { +- NOTICE("Overflow of %-15s: counts %3d, %3d, %3d worst %3d, overflows %3d worst_lag %02lld.%lld ms\n", ++ s32 rem; ++ s64 lag_sec = div_s64_rem(q->worst_lag_usec, 1000, &rem); ++ NOTICE("Overflow of %-15s: counts %3d, %3d, %3d worst %3d, overflows %3d worst_lag %02lld.%ld ms\n", + q->name, q->steady_state_count, q->count, + q->max_count, q->worst_count, q->overflows, +- q->worst_lag_usec / 1000, +- q->worst_lag_usec % 1000); ++ lag_sec, ++ rem); + __xframe_dump_queue(q); + } + ret = 0; +--- a/drivers/dahdi/xpp/xpp_usb.c ++++ b/drivers/dahdi/xpp/xpp_usb.c +@@ -27,6 +27,7 @@ + #include + #include /* for udelay */ + #include ++#include + #if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,18) + #include + #else +@@ -891,7 +892,7 @@ static void xpp_send_callback(struct urb + usec = 0; /* System clock jumped */ + if (usec > xusb->max_tx_delay) + xusb->max_tx_delay = usec; +- i = usec / USEC_BUCKET; ++ i = div_s64(usec, USEC_BUCKET); + if (i >= NUM_BUCKETS) + i = NUM_BUCKETS - 1; + xusb->usb_tx_delay[i]++; diff --git a/libs/dahdi-linux/patches/200-dahdi-use-fallthrough-where-needed.patch b/libs/dahdi-linux/patches/200-dahdi-use-fallthrough-where-needed.patch new file mode 100644 index 000000000..5e613b79b --- /dev/null +++ b/libs/dahdi-linux/patches/200-dahdi-use-fallthrough-where-needed.patch @@ -0,0 +1,131 @@ +From f9bc391e1cd830c830b3b4fb5fd46a59b41de373 Mon Sep 17 00:00:00 2001 +From: Christian Marangi +Date: Fri, 12 May 2023 20:18:13 +0200 +Subject: [PATCH 1/6] dahdi: use fallthrough where needed + +Use fallthrough instead of comment to fix compilation warning. + +Signed-off-by: Christian Marangi +--- + drivers/dahdi/dahdi-base.c | 14 +++++++------- + drivers/dahdi/wcaxx-base.c | 2 ++ + drivers/dahdi/wctdm24xxp/base.c | 2 ++ + drivers/dahdi/xpp/card_global.c | 2 +- + 4 files changed, 12 insertions(+), 8 deletions(-) + +--- a/drivers/dahdi/dahdi-base.c ++++ b/drivers/dahdi/dahdi-base.c +@@ -7930,7 +7930,7 @@ static inline void __dahdi_process_getau + memset(getlin, 0, DAHDI_CHUNKSIZE * sizeof(short)); + txb[0] = DAHDI_LIN2X(0, ms); + memset(txb + 1, txb[0], DAHDI_CHUNKSIZE - 1); +- /* fallthrough */ ++ fallthrough; + case DAHDI_CONF_CONF: /* Normal conference mode */ + if (is_pseudo_chan(ms)) /* if pseudo-channel */ + { +@@ -7954,7 +7954,7 @@ static inline void __dahdi_process_getau + memset(txb + 1, txb[0], DAHDI_CHUNKSIZE - 1); + break; + } +- /* fall through */ ++ fallthrough; + case DAHDI_CONF_CONFMON: /* Conference monitor mode */ + if (ms->confmode & DAHDI_CONF_LISTENER) { + /* Subtract out last sample written to conf */ +@@ -8493,7 +8493,7 @@ static void __dahdi_hooksig_pvt(struct d + break; + } + #endif +- /* fallthrough */ ++ fallthrough; + case DAHDI_SIG_FXSGS: /* FXS Groundstart */ + if (rxsig == DAHDI_RXSIG_ONHOOK) { + chan->ringdebtimer = RING_DEBOUNCE_TIME; +@@ -8512,7 +8512,7 @@ static void __dahdi_hooksig_pvt(struct d + chan->gotgs = 1; + } + } +- /* fallthrough */ ++ fallthrough; + case DAHDI_SIG_FXOLS: /* FXO Loopstart */ + case DAHDI_SIG_FXOKS: /* FXO Kewlstart */ + switch(rxsig) { +@@ -8612,7 +8612,7 @@ void dahdi_rbsbits(struct dahdi_chan *ch + __dahdi_hooksig_pvt(chan, DAHDI_RXSIG_START); + break; + } +- /* Fall through */ ++ fallthrough; + case DAHDI_SIG_EM_E1: + case DAHDI_SIG_FXOLS: /* FXO Loopstart */ + case DAHDI_SIG_FXOKS: /* FXO Kewlstart */ +@@ -8630,7 +8630,7 @@ void dahdi_rbsbits(struct dahdi_chan *ch + break; + case DAHDI_SIG_FXSKS: /* FXS Kewlstart */ + case DAHDI_SIG_FXSGS: /* FXS Groundstart */ +- /* Fall through */ ++ fallthrough; + case DAHDI_SIG_FXSLS: + if (!(cursig & DAHDI_BBIT)) { + /* Check for ringing first */ +@@ -9059,7 +9059,7 @@ static inline void __dahdi_process_putau + memcpy(ss->putlin, putlin, DAHDI_CHUNKSIZE * sizeof(short)); + break; + } +- /* fall through */ ++ fallthrough; + case DAHDI_CONF_CONFANN: /* Conference with announce */ + if (ms->confmode & DAHDI_CONF_TALKER) { + /* Store temp value */ +--- a/drivers/dahdi/wcaxx-base.c ++++ b/drivers/dahdi/wcaxx-base.c +@@ -1456,7 +1456,7 @@ wcaxx_check_battery_lost(struct wcaxx *w + break; + case BATTERY_UNKNOWN: + mod_hooksig(wc, mod, DAHDI_RXSIG_ONHOOK); +- /* fallthrough */ ++ fallthrough; + case BATTERY_PRESENT: + fxo->battery_state = BATTERY_DEBOUNCING_LOST; + fxo->battdebounce_timer = wc->framecount + battdebounce; +@@ -1567,7 +1567,7 @@ wcaxx_check_battery_present(struct wcaxx + break; + case BATTERY_UNKNOWN: + mod_hooksig(wc, mod, DAHDI_RXSIG_OFFHOOK); +- /* fallthrough */ ++ fallthrough; + case BATTERY_LOST: + fxo->battery_state = BATTERY_DEBOUNCING_PRESENT; + fxo->battdebounce_timer = wc->framecount + battdebounce; +--- a/drivers/dahdi/wctdm24xxp/base.c ++++ b/drivers/dahdi/wctdm24xxp/base.c +@@ -1964,7 +1964,7 @@ wctdm_check_battery_lost(struct wctdm *w + break; + case BATTERY_UNKNOWN: + mod_hooksig(wc, mod, DAHDI_RXSIG_ONHOOK); +- /* fallthrough */ ++ fallthrough; + case BATTERY_PRESENT: + fxo->battery_state = BATTERY_DEBOUNCING_LOST; + fxo->battdebounce_timer = wc->framecount + battdebounce; +@@ -2074,7 +2074,7 @@ wctdm_check_battery_present(struct wctdm + break; + case BATTERY_UNKNOWN: + mod_hooksig(wc, mod, DAHDI_RXSIG_OFFHOOK); +- /* fallthrough */ ++ fallthrough; + case BATTERY_LOST: + fxo->battery_state = BATTERY_DEBOUNCING_PRESENT; + fxo->battdebounce_timer = wc->framecount + battdebounce; +--- a/drivers/dahdi/xpp/card_global.c ++++ b/drivers/dahdi/xpp/card_global.c +@@ -148,7 +148,7 @@ static int execute_chip_command(xpd_t *x + XPD_NOTICE(xpd, + "'I' is deprecated in register commands. " + "Use 'S' instead.\n"); +- /* fall through */ ++ fallthrough; + case 'S': + do_subreg = 1; + num_args += 2; /* register + subreg */ diff --git a/libs/dahdi-linux/patches/201-dahdi-fix-always-true-compilation-warning.patch b/libs/dahdi-linux/patches/201-dahdi-fix-always-true-compilation-warning.patch new file mode 100644 index 000000000..353e9c2ac --- /dev/null +++ b/libs/dahdi-linux/patches/201-dahdi-fix-always-true-compilation-warning.patch @@ -0,0 +1,60 @@ +From eea6daaa4cae1ddcd8e32c8b9e4273ba3244838c Mon Sep 17 00:00:00 2001 +From: Christian Marangi +Date: Fri, 12 May 2023 20:19:04 +0200 +Subject: [PATCH 2/6] dahdi: fix always true compilation warning + +Fix always true compilation warning on statically allocated array. Check +content of the array instead. + +Signed-off-by: Christian Marangi +--- + drivers/dahdi/dahdi-base.c | 6 +++--- + drivers/dahdi/dahdi_dynamic_ethmf.c | 2 +- + drivers/dahdi/xpp/xbus-core.c | 2 +- + 3 files changed, 5 insertions(+), 5 deletions(-) + +--- a/drivers/dahdi/dahdi-base.c ++++ b/drivers/dahdi/dahdi-base.c +@@ -928,9 +928,9 @@ static int dahdi_seq_show(struct seq_fil + if (!s) + return -ENODEV; + +- if (s->name) ++ if (*(s->name)) + seq_printf(sfile, "Span %d: %s ", s->spanno, s->name); +- if (s->desc) ++ if (*(s->desc)) + seq_printf(sfile, "\"%s\"", s->desc); + else + seq_printf(sfile, "\"\""); +@@ -969,7 +969,7 @@ static int dahdi_seq_show(struct seq_fil + for (x = 0; x < s->channels; x++) { + struct dahdi_chan *chan = s->chans[x]; + +- if (chan->name) ++ if (*(chan->name)) + seq_printf(sfile, "\t%4d %s ", chan->channo, + chan->name); + +--- a/drivers/dahdi/dahdi_dynamic_ethmf.c ++++ b/drivers/dahdi/dahdi_dynamic_ethmf.c +@@ -535,7 +535,7 @@ static void ztdethmf_destroy(struct dahd + kfree(z->msgbuf); + kfree(z); + } else { +- if (z && z->span && z->span->name) { ++ if (z && z->span && *(z->span->name)) { + printk(KERN_ERR "Cannot find interface for %s\n", + z->span->name); + } +--- a/drivers/dahdi/xpp/xbus-core.c ++++ b/drivers/dahdi/xpp/xbus-core.c +@@ -120,7 +120,7 @@ int xbus_check_unique(xbus_t *xbus) + { + if (!xbus) + return -ENOENT; +- if (xbus->label && *(xbus->label)) { ++ if (*(xbus->label)) { + xbus_t *xbus_old; + + XBUS_DBG(DEVICES, xbus, "Checking LABEL='%s'\n", xbus->label); diff --git a/libs/dahdi-linux/patches/202-dahdi-sysfs-chan-fix-bug-if-clause-does-not-guard.patch b/libs/dahdi-linux/patches/202-dahdi-sysfs-chan-fix-bug-if-clause-does-not-guard.patch new file mode 100644 index 000000000..b88709415 --- /dev/null +++ b/libs/dahdi-linux/patches/202-dahdi-sysfs-chan-fix-bug-if-clause-does-not-guard.patch @@ -0,0 +1,28 @@ +From d0699f781e96df6c1fd10551c92fa27695b297da Mon Sep 17 00:00:00 2001 +From: Christian Marangi +Date: Fri, 12 May 2023 20:19:45 +0200 +Subject: [PATCH 3/6] dahdi-sysfs-chan: fix bug if clause does not guard + +Fix bug if clause does not guard by a typo by missing the if clause and +not correctly removing the device. + +Signed-off-by: Christian Marangi +--- + drivers/dahdi/dahdi-sysfs-chan.c | 3 ++- + 1 file changed, 2 insertions(+), 1 deletion(-) + +--- a/drivers/dahdi/dahdi-sysfs-chan.c ++++ b/drivers/dahdi/dahdi-sysfs-chan.c +@@ -381,10 +381,11 @@ static void fixed_devfiles_remove(void) + return; + for (i = 0; i < ARRAY_SIZE(fixed_minors); i++) { + void *d = fixed_minors[i].dev; +- if (d && !IS_ERR(d)) ++ if (d && !IS_ERR(d)) { + dahdi_dbg(DEVICES, "Removing fixed device file %s\n", + fixed_minors[i].name); + DEL_DAHDI_DEV(fixed_minors[i].minor); ++ } + } + } + diff --git a/libs/dahdi-linux/patches/204-dahdi-skip-checking-on-releasing.patch b/libs/dahdi-linux/patches/204-dahdi-skip-checking-on-releasing.patch new file mode 100644 index 000000000..24bbf81fa --- /dev/null +++ b/libs/dahdi-linux/patches/204-dahdi-skip-checking-on-releasing.patch @@ -0,0 +1,38 @@ +From 88cfe20bcd0be443fc7613fd287147d1c54b5f7f Mon Sep 17 00:00:00 2001 +From: Christian Marangi +Date: Fri, 12 May 2023 20:21:39 +0200 +Subject: [PATCH 5/6] dahdi: skip checking on releasing + +Skip checking on releasing since xb is statically allocated and always +present. + +Signed-off-by: Christian Marangi +--- + drivers/dahdi/wcte13xp-base.c | 3 +-- + drivers/dahdi/wcte43x-base.c | 3 +-- + 2 files changed, 2 insertions(+), 4 deletions(-) + +--- a/drivers/dahdi/wcte13xp-base.c ++++ b/drivers/dahdi/wcte13xp-base.c +@@ -2707,8 +2707,7 @@ static int __devinit te13xp_init_one(str + return 0; + + fail_exit: +- if (&wc->xb) +- wcxb_release(&wc->xb); ++ wcxb_release(&wc->xb); + + free_wc(wc); + return res; +--- a/drivers/dahdi/wcte43x-base.c ++++ b/drivers/dahdi/wcte43x-base.c +@@ -3521,8 +3521,7 @@ static int __devinit t43x_init_one(struc + return 0; + + fail_exit: +- if (&wc->xb) +- wcxb_release(&wc->xb); ++ wcxb_release(&wc->xb); + + if (debug) + dev_info(&wc->xb.pdev->dev, "***At fail_exit in init_one***\n"); diff --git a/libs/dahdi-linux/patches/205-dahdi-xpp-fix-wrong-printf-to-d.patch b/libs/dahdi-linux/patches/205-dahdi-xpp-fix-wrong-printf-to-d.patch new file mode 100644 index 000000000..52b903674 --- /dev/null +++ b/libs/dahdi-linux/patches/205-dahdi-xpp-fix-wrong-printf-to-d.patch @@ -0,0 +1,44 @@ +From 14a9e676d635b1c2be1bab4114cc76c1793892d0 Mon Sep 17 00:00:00 2001 +From: Christian Marangi +Date: Fri, 12 May 2023 20:22:31 +0200 +Subject: [PATCH 6/6] dahdi: xpp: fix wrong printf to %d + +Fix wrong printf that should be %d with int variables. + +Signed-off-by: Christian Marangi +--- + drivers/dahdi/xpp/xbus-core.c | 2 +- + drivers/dahdi/xpp/xframe_queue.c | 4 ++-- + 2 files changed, 3 insertions(+), 3 deletions(-) + +--- a/drivers/dahdi/xpp/xbus-core.c ++++ b/drivers/dahdi/xpp/xbus-core.c +@@ -1772,7 +1772,7 @@ static void xbus_fill_proc_queue(struct + s32 rem; + s64 lag_sec = div_s64_rem(q->worst_lag_usec, 1000, &rem); + seq_printf(sfile, +- "%-15s: counts %3d, %3d, %3d worst %3d, overflows %3d worst_lag %02lld.%ld ms\n", ++ "%-15s: counts %3d, %3d, %3d worst %3d, overflows %3d worst_lag %02lld.%d ms\n", + q->name, q->steady_state_count, q->count, q->max_count, + q->worst_count, q->overflows, lag_sec, + rem); +--- a/drivers/dahdi/xpp/xframe_queue.c ++++ b/drivers/dahdi/xpp/xframe_queue.c +@@ -44,7 +44,7 @@ static void __xframe_dump_queue(struct x + s32 rem; + s64 sec = div_s64_rem(ktime_us_delta(now, xframe->kt_queued), 1000, &rem); + +- snprintf(prefix, ARRAY_SIZE(prefix), " %3d> %5lld.%03ld msec", ++ snprintf(prefix, ARRAY_SIZE(prefix), " %3d> %5lld.%03d msec", + i++, sec, rem); + dump_packet(prefix, pack, 1); + } +@@ -64,7 +64,7 @@ static bool __xframe_enqueue(struct xfra + if ((overflow_cnt++ % 1000) < 5) { + s32 rem; + s64 lag_sec = div_s64_rem(q->worst_lag_usec, 1000, &rem); +- NOTICE("Overflow of %-15s: counts %3d, %3d, %3d worst %3d, overflows %3d worst_lag %02lld.%ld ms\n", ++ NOTICE("Overflow of %-15s: counts %3d, %3d, %3d worst %3d, overflows %3d worst_lag %02lld.%d ms\n", + q->name, q->steady_state_count, q->count, + q->max_count, q->worst_count, q->overflows, + lag_sec, diff --git a/libs/dahdi-linux/patches/206-dahdi_echocan_mg2-rename-ABS-define-to-PARA_ABS.patch b/libs/dahdi-linux/patches/206-dahdi_echocan_mg2-rename-ABS-define-to-PARA_ABS.patch new file mode 100644 index 000000000..18e8735f9 --- /dev/null +++ b/libs/dahdi-linux/patches/206-dahdi_echocan_mg2-rename-ABS-define-to-PARA_ABS.patch @@ -0,0 +1,42 @@ +From d2563faf053da31e1329e7313339669f31c989da Mon Sep 17 00:00:00 2001 +From: Christian Marangi +Date: Wed, 20 Mar 2024 19:48:33 +0100 +Subject: [PATCH] dahdi_echocan_mg2: rename ABS define to PARA_ABS + +Rename ABS define to PARA_ABS to fix compilation error with mips 24kc +arch. + +This target define in his ASM header a similar define ABS that cause +conflicts and redefinition error for this driver. + +Rename ABS to PARA_ABS to better suite the usage as it's abs usage with +value decremented by one if it's the max negative int. + +Signed-off-by: Christian Marangi +--- + drivers/dahdi/dahdi_echocan_mg2.c | 6 +++--- + 1 file changed, 3 insertions(+), 3 deletions(-) + +--- a/drivers/dahdi/dahdi_echocan_mg2.c ++++ b/drivers/dahdi/dahdi_echocan_mg2.c +@@ -44,7 +44,7 @@ + static int debug; + static int aggressive; + +-#define ABS(a) abs(a!=-32768?a:-32767) ++#define PARA_ABS(a) abs(a!=-32768?a:-32767) + + #define RESTORE_COEFFS {\ + int x;\ +@@ -464,9 +464,9 @@ static inline short sample_update(struct + RESTORE_COEFFS; + } + +- sign_error = ABS(rs) - ABS(isig); ++ sign_error = PARA_ABS(rs) - PARA_ABS(isig); + +- if (ABS(sign_error) > MAX_SIGN_ERROR) ++ if (PARA_ABS(sign_error) > MAX_SIGN_ERROR) + { + rs = 0; + RESTORE_COEFFS; diff --git a/libs/dahdi-tools/Makefile b/libs/dahdi-tools/Makefile new file mode 100644 index 000000000..e37f6472a --- /dev/null +++ b/libs/dahdi-tools/Makefile @@ -0,0 +1,97 @@ +# +# Copyright (C) 2014 OpenWrt.org +# +# This is free software, licensed under the GNU General Public License v2. +# See /LICENSE for more information. +# + +include $(TOPDIR)/rules.mk + +PKG_NAME:=dahdi-tools +PKG_VERSION:=3.1.0 +PKG_RELEASE:=3 + +PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.gz +PKG_SOURCE_URL:=https://downloads.asterisk.org/pub/telephony/dahdi-tools/releases +PKG_HASH:=ea852ebd274ee1cc90ff5e4ac84261b0b787b1a74e8b76ad659bc9ec4f77e67e + +PKG_LICENSE:=GPL-2.0 +PKG_LICENSE_FILES:=LICENSE +PKG_MAINTAINER:=Vittorio Gambaletta + +PKG_BUILD_PARALLEL:=1 + +PKG_FIXUP:=autoreconf + +PKG_INSTALL:=1 + +include $(INCLUDE_DIR)/package.mk + +define Package/dahdi-cfg/Default + SECTION:=utils + CATEGORY:=Utilities + SUBMENU:=Telephony + DEPENDS=+kmod-dahdi +endef + +define Package/dahdi-cfg + $(call Package/dahdi-cfg/Default) + DEPENDS+=+libpthread +dahdi-tools-libtonezone + TITLE:=DAHDI tools dahdi_cfg, dahdi_scan and fxotune +endef + +define Package/dahdi-monitor + $(call Package/dahdi-cfg/Default) + TITLE:=DAHDI tools dahdi_monitor, dahdi_speed and dahdi_test +endef + +define Package/dahdi-tools-libtonezone + $(call Package/dahdi-cfg/Default) + SECTION:=libs + CATEGORY:=Libraries + TITLE:=DAHDI tonezone library +endef + +CONFIGURE_ARGS += \ + --disable-silent-rules \ + --with-perllib="" \ + --without-libusb \ + --without-libusbx \ + --without-newt \ + --without-pcap \ + --without-ppp \ + --without-selinux \ + --without-usb + +# https://issues.asterisk.org/jira/browse/DAHTOOL-85 +TARGET_CFLAGS+=-fcommon + +define Build/InstallDev + $(INSTALL_DIR) $(1)/usr/lib + $(CP) $(PKG_INSTALL_DIR)/usr/lib/libtonezone.{a,so*} \ + $(1)/usr/lib/ + $(INSTALL_DIR) $(1)/usr/include/dahdi + $(INSTALL_DATA) $(PKG_INSTALL_DIR)/usr/include/dahdi/tonezone.h \ + $(1)/usr/include/dahdi/ +endef + +define Package/dahdi-cfg/install + $(INSTALL_DIR) $(1)/usr/sbin + $(INSTALL_BIN) $(PKG_INSTALL_DIR)/usr/sbin/{dahdi_cfg,dahdi_scan,fxotune} \ + $(1)/usr/sbin/ +endef + +define Package/dahdi-monitor/install + $(INSTALL_DIR) $(1)/usr/sbin + $(INSTALL_BIN) $(PKG_INSTALL_DIR)/usr/sbin/{dahdi_monitor,dahdi_speed,dahdi_test} \ + $(1)/usr/sbin/ +endef + +define Package/dahdi-tools-libtonezone/install + $(INSTALL_DIR) $(1)/usr/lib + $(CP) $(PKG_INSTALL_DIR)/usr/lib/libtonezone.so* $(1)/usr/lib/ +endef + +$(eval $(call BuildPackage,dahdi-cfg)) +$(eval $(call BuildPackage,dahdi-monitor)) +$(eval $(call BuildPackage,dahdi-tools-libtonezone)) diff --git a/libs/dahdi-tools/patches/020-fix-undefined-reference-to-get_ver.patch b/libs/dahdi-tools/patches/020-fix-undefined-reference-to-get_ver.patch new file mode 100644 index 000000000..f09fcad73 --- /dev/null +++ b/libs/dahdi-tools/patches/020-fix-undefined-reference-to-get_ver.patch @@ -0,0 +1,11 @@ +--- a/xpp/echo_loader.c ++++ b/xpp/echo_loader.c +@@ -564,7 +564,7 @@ UINT32 Oct6100UserDriverReadBurstApi(tPO + return cOCT6100_ERR_OK; + } + +-inline int get_ver(struct astribank *astribank) ++static inline int get_ver(struct astribank *astribank) + { + return spi_send(astribank, 0, 0, 1, 1); + } diff --git a/libs/dahdi-tools/patches/030-cdefs.patch b/libs/dahdi-tools/patches/030-cdefs.patch new file mode 100644 index 000000000..477832592 --- /dev/null +++ b/libs/dahdi-tools/patches/030-cdefs.patch @@ -0,0 +1,10 @@ +--- a/xpp/hexfile.h ++++ b/xpp/hexfile.h +@@ -26,6 +26,7 @@ + #include + #include + #include ++#include + #include + #include + #define PACKED __attribute__((packed)) diff --git a/libs/freetdm/Config.in b/libs/freetdm/Config.in new file mode 100644 index 000000000..725f88823 --- /dev/null +++ b/libs/freetdm/Config.in @@ -0,0 +1,12 @@ +menu "Configuration" + depends on PACKAGE_freetdm + +config FREETDM_WITH_DEBUG + bool "Compile with debug information" + default n + help + Enable extra debug codepaths, like asserts and extra output. If you + want to get meaningful backtraces see + https://wiki.openwrt.org/doc/devel/debugging for starting points. + +endmenu diff --git a/libs/freetdm/Makefile b/libs/freetdm/Makefile new file mode 100644 index 000000000..428a47645 --- /dev/null +++ b/libs/freetdm/Makefile @@ -0,0 +1,154 @@ +# +# Copyright (C) 2021 Sebastian Kemper +# +# This is free software, licensed under the GNU General Public License v2. +# See /LICENSE for more information. +# + +include $(TOPDIR)/rules.mk + +PKG_NAME:=freetdm +PKG_RELEASE:=2 +PKG_MAINTAINER:=Sebastian Kemper + +PKG_SOURCE_PROTO:=git +PKG_SOURCE_URL:=https://github.com/freeswitch/freetdm.git +PKG_SOURCE_DATE:=2021-08-30 +PKG_SOURCE_VERSION:=8918ee1c3637cad0f9d41a402d26d3aa076fc202 +PKG_MIRROR_HASH:=fd7e658f27bcca67fceeacd72e61bdbb6bea784df2def3ca2659a28ce2079e7b + +PKG_FIXUP:=autoreconf + +PKG_BUILD_PARALLEL:=1 +PKG_INSTALL:=1 + +PKG_LICENSE:= \ + BSD-2-Clause \ + BSD-3-Clause \ + BSD-4-Clause \ + GPL-2.0+ \ + MIT/X11 (BSD like) \ + MPL-1.1 + +PKG_LICENSE_FILES:=LICENSE + +PKG_BUILD_DEPENDS:=freeswitch + +FS_EXAMPLES_DIR:=/usr/share/freeswitch/examples +FS_LIB_DIR:=/usr/lib +FS_MOD_DIR:=$(FS_LIB_DIR)/freeswitch/mod +FS_PKGCONFIG_DIR:=$(FS_LIB_DIR)/pkgconfig + +PKG_CONFIG_DEPENDS:= \ + CONFIG_FREETDM_WITH_DEBUG \ + CONFIG_LIBC \ + CONFIG_PACKAGE_libfreetdm-ftmod-libpri \ + CONFIG_PACKAGE_libfreetdm-ftmod-pritap \ + +include $(INCLUDE_DIR)/package.mk + +define Package/libfreetdm/install/ftmod + $(INSTALL_DIR) $(1)$(FS_MOD_DIR) + $(INSTALL_BIN) $(PKG_INSTALL_DIR)$(FS_MOD_DIR)/ftmod_$(2).so \ + $(1)$(FS_MOD_DIR) +endef + +define Package/freetdm/config + source "$(SOURCE)/Config.in" +endef + +define Package/libfreetdm/Default + SECTION:=libs + CATEGORY:=Libraries + SUBMENU:=Telephony + URL:=https://www.freeswitch.org +endef + +define Package/libfreetdm +$(call Package/libfreetdm/Default) + DEPENDS:= + TITLE:=TDM signaling and media API + MENU:=1 +endef + +define Package/libfreetdm/description +Provides a unified interface to hardware TDM cards and SS7 stacks. +endef + +define Package/libfreetdm/install + $(INSTALL_DIR) $(1)$(FS_LIB_DIR) + $(CP) $(PKG_INSTALL_DIR)$(FS_LIB_DIR)/libfreetdm.so.* \ + $(1)$(FS_LIB_DIR) +endef + +define Package/freeswitch-mod-freetdm +$(call Package/libfreetdm/Default) + SECTION:=net + CATEGORY:=Network + SUBMENU:=Telephony + DEPENDS:=freeswitch +libfreetdm + TITLE:=FreeTDM endpoint module +endef + +define Package/freeswitch-mod-freetdm/description +This module is the glue between FreeSWITCH and FreeTDM. +endef + +define Package/freeswitch-mod-freetdm/install + $(INSTALL_DIR) $(1)$(FS_MOD_DIR) + $(INSTALL_BIN) $(PKG_INSTALL_DIR)$(FS_MOD_DIR)/mod_freetdm.so \ + $(1)$(FS_MOD_DIR) +ifeq ($(CONFIG_FS_WITH_MODCONF),y) + $(INSTALL_DIR) \ + $(1)$(FS_EXAMPLES_DIR)/mod_freetdm/freeswitch/autoload_configs + $(INSTALL_DATA) $(PKG_INSTALL_DIR)/etc/*.conf \ + $(1)$(FS_EXAMPLES_DIR)/mod_freetdm + $(INSTALL_DATA) \ + $(PKG_INSTALL_DIR)/etc/freeswitch/autoload_configs/freetdm.conf.xml \ + $(1)$(FS_EXAMPLES_DIR)/mod_freetdm/freeswitch/autoload_configs +endif +endef + +define Package/libfreetdm/FTModule +define Package/libfreetdm-ftmod-$(subst _,-,$(1)) +$(call Package/libfreetdm/Default) + DEPENDS:=libfreetdm \ + $(patsubst +%,+PACKAGE_libfreetdm-ftmod-$(subst _,-,$(1)):%,$(4)) + TITLE:=$(2) FreeTDM module +endef +define Package/libfreetdm-ftmod-$(subst _,-,$(1))/description +$(subst \n,$(newline),$(3)) +endef +define Package/libfreetdm-ftmod-$(subst _,-,$(1))/install +$(call Package/libfreetdm/install/ftmod,$$(1),$(1)) +endef +$$(eval $$(call BuildPackage,libfreetdm-ftmod-$(subst _,-,$(1)))) +endef + +CONFIGURE_ARGS+= \ + --srcdir=$(PKG_BUILD_DIR) \ + --disable-dependency-tracking \ + --disable-static \ + --with-modinstdir=$(FS_MOD_DIR) \ + $(call autoconf_bool,CONFIG_FREETDM_WITH_DEBUG,debug) \ + $(if $(CONFIG_PACKAGE_libfreetdm-ftmod-libpri),--with-libpri="$(STAGING_DIR)/usr",--without-libpri) \ + $(if $(CONFIG_PACKAGE_libfreetdm-ftmod-pritap),--with-pritap,--without-pritap) + +$(eval $(call BuildPackage,libfreetdm)) +$(eval $(call BuildPackage,freeswitch-mod-freetdm)) + +################################ +# FreeTDM modules +# Params: +# 1 - Package subname +# 2 - Package title +# 3 - Module description +# 4 - Module dependencies +################################ + +$(eval $(call Package/libfreetdm/FTModule,analog,Analog,Offers generic FXO/FXS support for any type of card supported by FreeTDM.,)) +$(eval $(call Package/libfreetdm/FTModule,analog_em,Analog EM,Offers generic E&M signaling for any type of card supported by FreeTDM.,)) +$(eval $(call Package/libfreetdm/FTModule,libpri,LibPRI,Offers support for PRI lines using the open source libpri stack for any\ntype of card supported by FreeTDM. Supports both PRI and BRI signalling.,+libpri @!aarch64)) +$(eval $(call Package/libfreetdm/FTModule,pritap,PRI tapping,This module is used to tap PRI lines.,+libfreetdm-ftmod-libpri)) +$(eval $(call Package/libfreetdm/FTModule,skel,Skeleton,ftmod_skel is an example module.,)) +$(eval $(call Package/libfreetdm/FTModule,zt,DAHDI I/O,This module supports the DAHDI interface. The DAHDI interface is used by\nseveral hardware vendors.,)) diff --git a/libs/freetdm/patches/280-tone-down-freetdm-COMP_VENDOR_CFLAGS.patch b/libs/freetdm/patches/280-tone-down-freetdm-COMP_VENDOR_CFLAGS.patch new file mode 100644 index 000000000..e7d7bc0b7 --- /dev/null +++ b/libs/freetdm/patches/280-tone-down-freetdm-COMP_VENDOR_CFLAGS.patch @@ -0,0 +1,11 @@ +--- a/configure.ac ++++ b/configure.ac +@@ -88,7 +88,7 @@ AC_ARG_ENABLE([enable_64], + + case "${ax_cv_c_compiler_vendor}" in + gnu) +- COMP_VENDOR_CFLAGS="-ffast-math -Wall -Werror -Wunused-variable -Wwrite-strings -Wstrict-prototypes -Wmissing-prototypes -O0" ++ COMP_VENDOR_CFLAGS="-ffast-math -Wall -Wunused-variable -Wwrite-strings -Wstrict-prototypes -Wmissing-prototypes" + ;; + sun) + COMP_VENDOR_CFLAGS="-xc99=all -mt -xCC -xvpara" diff --git a/libs/freetdm/patches/290-fix-mod_freetdm-copts.patch b/libs/freetdm/patches/290-fix-mod_freetdm-copts.patch new file mode 100644 index 000000000..a278a1e32 --- /dev/null +++ b/libs/freetdm/patches/290-fix-mod_freetdm-copts.patch @@ -0,0 +1,8 @@ +--- a/mod_freetdm/Makefile.in ++++ b/mod_freetdm/Makefile.in +@@ -1,4 +1,4 @@ +-FT_CFLAGS=@CFLAGS@ @COMP_VENDOR_CFLAGS@ @DEFS@ ++FT_CFLAGS=@COMP_VENDOR_CFLAGS@ @DEFS@ + + BASE=../../.. + FT_DIR=.. diff --git a/libs/freetdm/patches/300-install-missing_dir.patch b/libs/freetdm/patches/300-install-missing_dir.patch new file mode 100644 index 000000000..ac1d31804 --- /dev/null +++ b/libs/freetdm/patches/300-install-missing_dir.patch @@ -0,0 +1,10 @@ +--- a/Makefile.am ++++ b/Makefile.am +@@ -284,6 +284,7 @@ dox doxygen: + install-data-local: + $(mkinstalldirs) $(DESTDIR)$(prefix) + $(mkinstalldirs) $(DESTDIR)@confdir@ ++ $(mkinstalldirs) $(DESTDIR)@fsconfdir@/autoload_configs + @[ -f "$(DESTDIR)@confdir@/freetdm.conf" ] || ( cp conf/*.conf $(DESTDIR)@confdir@) + @[ -f "$(DESTDIR)@fsconfdir@/autoload_configs/freetdm.conf.xml" ] || ( cp -f conf/freetdm.conf.xml $(DESTDIR)@fsconfdir@/autoload_configs) + @echo FreeTDM Installed diff --git a/libs/gsmlib/Makefile b/libs/gsmlib/Makefile new file mode 100644 index 000000000..9bc4324ce --- /dev/null +++ b/libs/gsmlib/Makefile @@ -0,0 +1,96 @@ +# +# Copyright (C) 2018 OpenWrt.org +# +# This is free software, licensed under the GNU General Public License v2. +# See /LICENSE for more information. +# + +include $(TOPDIR)/rules.mk + +PKG_NAME:=gsmlib +PKG_VERSION:=1.10-20140304 +PKG_RELEASE:=5 + +PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.xz +PKG_SOURCE_URL:=https://github.com/vbouchaud/gsmlib.git +PKG_SOURCE_PROTO:=git +PKG_SOURCE_SUBDIR:=$(PKG_NAME)-$(PKG_VERSION) +PKG_SOURCE_VERSION:=cd5442de07cfe052316ede58640ef81b20627276 +PKG_MIRROR_HASH:=bc24d7ddcb5f4b5f9160351d9f38cf6f35f3feef969f675f883b32d04c8c80fa + +PKG_BUILD_DIR:=$(BUILD_DIR)/$(PKG_NAME)-$(PKG_VERSION) + +# Need Makefile.in.in from gettext-full/host and po.m4 from gettext-full +PKG_BUILD_DEPENDS:=gettext-full/host gettext-full + +PKG_FIXUP:=autoreconf + +PKG_INSTALL:=1 + +PKG_LICENSE:=LGPL-2.1+ +PKG_LICENSE_FILES:=COPYING +PKG_MAINTAINER:=Sebastian Kemper + +include $(INCLUDE_DIR)/package.mk + +define Package/$(PKG_NAME)/Default + SUBMENU:=Telephony + URL:=https://github.com/vbouchaud/gsmlib +endef + +define Package/$(PKG_NAME) +$(call Package/$(PKG_NAME)/Default) + SECTION:=libs + CATEGORY:=Libraries + TITLE:=GSM mobile phone access lib + DEPENDS:=+libstdcpp +endef + +define Package/gsm-utils +$(call Package/$(PKG_NAME)/Default) + SECTION:=utils + CATEGORY:=Utilities + TITLE:=GSM mobile phone access apps + DEPENDS:=+$(PKG_NAME) +endef + +define Package/$(PKG_NAME)/description +A library to access GSM mobile phones via GSM modems. +endef + +define Package/gsm-utils/description +Some simple command line programs to access GSM mobile phones via GSM modems. +endef + +CONFIGURE_ARGS += --disable-nls + +TARGET_CXXFLAGS += -std=c++11 + +define Build/InstallDev + $(INSTALL_DIR) $(1)/usr/include/$(PKG_NAME) + $(INSTALL_DATA) \ + $(PKG_INSTALL_DIR)/usr/include/$(PKG_NAME)/*.h \ + $(1)/usr/include/$(PKG_NAME) + $(INSTALL_DIR) $(1)/usr/lib + $(CP) $(PKG_INSTALL_DIR)/usr/lib/libgsmme.so* $(1)/usr/lib +endef + +define Build/Prepare +$(call Build/Prepare/Default) + $(INSTALL_DATA) \ + $(STAGING_DIR_HOSTPKG)/share/gettext/po/Makefile.in.in \ + $(PKG_BUILD_DIR)/po +endef + +define Package/$(PKG_NAME)/install + $(INSTALL_DIR) $(1)/usr/lib + $(CP) $(PKG_INSTALL_DIR)/usr/lib/libgsmme.so* $(1)/usr/lib +endef + +define Package/gsm-utils/install + $(INSTALL_DIR) $(1)/usr/bin + $(INSTALL_BIN) $(PKG_INSTALL_DIR)/usr/bin/* $(1)/usr/bin +endef + +$(eval $(call BuildPackage,$(PKG_NAME))) +$(eval $(call BuildPackage,gsm-utils)) diff --git a/libs/gsmlib/patches/01-update-autotools.patch b/libs/gsmlib/patches/01-update-autotools.patch new file mode 100644 index 000000000..372a4e615 --- /dev/null +++ b/libs/gsmlib/patches/01-update-autotools.patch @@ -0,0 +1,57 @@ +Description: Update autotools-related stuff. + +--- a/configure.in ++++ b/configure.in +@@ -15,6 +15,7 @@ AC_INIT(gsmlib/gsm_error.h) + + dnl Other + AC_CONFIG_AUX_DIR(scripts) ++AC_CONFIG_MACRO_DIR([m4]) + AC_PROG_INSTALL + + dnl check for libintl +@@ -34,6 +35,8 @@ if test "$CXXFLAGS" = ""; then + CXXFLAGS="-O2" + fi + ++AC_USE_SYSTEM_EXTENSIONS ++ + dnl comment out this line to get extensive debugging output and asserts + dnl CXXFLAGS="-DNDEBUG $CXXFLAGS" + +@@ -108,7 +111,7 @@ AC_SUBST(GSM_VERSION) + dnl national language support (NLS) + LINGUAS="de" + ALL_LINGUAS=$LINGUAS +-AM_GNU_GETTEXT ++AM_GNU_GETTEXT([external]) + dnl AM_GLIB_GNU_GETTEXT + + dnl set locale dir (FIXME there must be a better way) +--- /dev/null ++++ b/po/Makevars +@@ -0,0 +1,5 @@ ++DOMAIN = $(PACKAGE) ++ ++subdir = po ++top_builddir = .. ++ +--- a/Makefile.am ++++ b/Makefile.am +@@ -11,14 +11,12 @@ + # * Created: 21.5.1999 + # ************************************************************************* + ++ACLOCAL_AMFLAGS = -I m4 ++ + SUBDIRS_ = po gsmlib apps tests doc scripts win32 ext + + EXTRA_DIST = gsmlib.spec + +-if COMPILE_INTL +-SUBDIRS = intl $(SUBDIRS_) # po - make automake happy +-else + SUBDIRS = $(SUBDIRS_) # po intl - make automake happy +-endif + + all: diff --git a/libs/gsmlib/patches/02-fix-cross-compile.patch b/libs/gsmlib/patches/02-fix-cross-compile.patch new file mode 100644 index 000000000..8beb07c55 --- /dev/null +++ b/libs/gsmlib/patches/02-fix-cross-compile.patch @@ -0,0 +1,21 @@ +--- a/configure.in ++++ b/configure.in +@@ -60,7 +60,7 @@ AC_PROG_CPP + AC_PROG_CXX + + dnl check for gcc 2.95.x +-AC_TRY_RUN([ ++AC_RUN_IFELSE([ + #include + main() + { +@@ -72,7 +72,8 @@ main() + } + ],, + [echo "need at least gcc 2.95 to compile correctly" +-exit 1]) ++exit 1], ++[echo "checking if at least gcc 2.95 is available... cross-compiling (assuming yes)"]) + + dnl check for alloca + AC_FUNC_ALLOCA diff --git a/libs/gsmlib/patches/03-disable-Siemens-specific-code.patch b/libs/gsmlib/patches/03-disable-Siemens-specific-code.patch new file mode 100644 index 000000000..33ca728c8 --- /dev/null +++ b/libs/gsmlib/patches/03-disable-Siemens-specific-code.patch @@ -0,0 +1,11 @@ +--- a/Makefile.am ++++ b/Makefile.am +@@ -13,7 +13,7 @@ + + ACLOCAL_AMFLAGS = -I m4 + +-SUBDIRS_ = po gsmlib apps tests doc scripts win32 ext ++SUBDIRS_ = po gsmlib apps tests doc scripts win32 + + EXTRA_DIST = gsmlib.spec + diff --git a/libs/iksemel/Makefile b/libs/iksemel/Makefile new file mode 100644 index 000000000..f981ee832 --- /dev/null +++ b/libs/iksemel/Makefile @@ -0,0 +1,60 @@ +# +# Copyright (C) 2014 - 2017 OpenWrt.org +# +# This is free software, licensed under the GNU General Public License v2. +# See /LICENSE for more information. +# + +include $(TOPDIR)/rules.mk + +PKG_NAME:=iksemel +PKG_VERSION:=1.4 +PKG_RELEASE:=2 + +PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.gz +PKG_SOURCE_URL:=https://storage.googleapis.com/google-code-archive-downloads/v2/code.google.com/iksemel +PKG_HASH:=458c1b8fb3349076a6cecf26c29db1d561315d84e16bfcfba419f327f502e244 + +PKG_FIXUP:=autoreconf + +PKG_INSTALL:=1 + +PKG_LICENSE:=LGPL-2.1 +PKG_LICENSE_FILES:=COPYING +PKG_MAINTAINER:=Jiri Slachta + +include $(INCLUDE_DIR)/package.mk + +define Package/libiksemel + SUBMENU:=Telephony + SECTION:=libs + CATEGORY:=Libraries + TITLE:=Iksemel Jabber Library + URL:=https://github.com/meduketto/iksemel + DEPENDS:=+libgnutls +endef + +define Package/libiksemel/description +Iksemel is an XML parser library mainly designed for Jabber applications. +It provides SAX, DOM, and special Jabber stream APIs. Library is coded +in ANSI C except the network code (which is POSIX compatible), thus +highly portable. +endef + +define Build/InstallDev + $(INSTALL_DIR) $(1)/usr/include/ + $(CP) $(PKG_INSTALL_DIR)/usr/include/iksemel.h $(1)/usr/include/ + + $(INSTALL_DIR) $(1)/usr/lib + $(CP) $(PKG_INSTALL_DIR)/usr/lib/libiksemel.{a,so*} $(1)/usr/lib/ + + $(INSTALL_DIR) $(1)/usr/lib/pkgconfig + $(CP) $(PKG_INSTALL_DIR)/usr/lib/pkgconfig/iksemel.pc $(1)/usr/lib/pkgconfig/ +endef + +define Package/libiksemel/install + $(INSTALL_DIR) $(1)/usr/lib + $(CP) $(PKG_INSTALL_DIR)/usr/lib/libiksemel.so* $(1)/usr/lib/ +endef + +$(eval $(call BuildPackage,libiksemel)) diff --git a/libs/iksemel/patches/001-pkgconfig-gnutls.patch b/libs/iksemel/patches/001-pkgconfig-gnutls.patch new file mode 100644 index 000000000..ebc870d95 --- /dev/null +++ b/libs/iksemel/patches/001-pkgconfig-gnutls.patch @@ -0,0 +1,28 @@ +Last-Update: 2013-07-29 +Forwarded: not-needed +Origin: upstream, commit:4652af9cf119145af3a90c632f8a6db215946784 +Bug-Iksemel: https://code.google.com/p/iksemel/issues/detail?id=20 +Author: Dmitry Smirnov +Description: use pkgconfig for checking gnutls + +--- a/configure.ac ++++ b/configure.ac +@@ -44,9 +44,17 @@ + AC_SEARCH_LIBS(recv,socket) + AC_CHECK_FUNCS(getopt_long) + AC_CHECK_FUNCS(getaddrinfo) + +-AM_PATH_LIBGNUTLS(,AC_DEFINE(HAVE_GNUTLS,,"Use libgnutls")) ++dnl Check GNU TLS ++PKG_CHECK_MODULES(GNUTLS, gnutls >= 2.0.0, have_gnutls=yes, have_gnutls=no) ++if test "x$have_gnutls" = "xyes"; then ++ LIBGNUTLS_CFLAGS="$GNUTLS_CFLAGS" ++ LIBGNUTLS_LIBS="$GNUTLS_LIBS" ++ AC_SUBST(LIBGNUTLS_CFLAGS) ++ AC_SUBST(LIBGNUTLS_LIBS) ++ AC_DEFINE(HAVE_GNUTLS, 1, [whether to use GnuTSL support.]) ++fi + + dnl Check -Wall flag of GCC + if test "x$GCC" = "xyes"; then + if test -z "`echo "$CFLAGS" | grep "\-Wall" 2> /dev/null`" ; then diff --git a/libs/iksemel/patches/002-secure_gnutls_options.patch b/libs/iksemel/patches/002-secure_gnutls_options.patch new file mode 100644 index 000000000..bf09e17a8 --- /dev/null +++ b/libs/iksemel/patches/002-secure_gnutls_options.patch @@ -0,0 +1,38 @@ +Last-Update: 2015-10-28 +Bug-Upstream: https://github.com/meduketto/iksemel/issues/48 +Bug-Debian: https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=803204 +From: Marc Dequènes (duck) +Description: fix security problem (and compatibility problem with servers rejecting low grade ciphers). + +--- a/src/stream.c ++++ b/src/stream.c +@@ -62,13 +62,9 @@ + + static int + handshake (struct stream_data *data) + { +- const int protocol_priority[] = { GNUTLS_TLS1, GNUTLS_SSL3, 0 }; +- const int kx_priority[] = { GNUTLS_KX_RSA, 0 }; +- const int cipher_priority[] = { GNUTLS_CIPHER_3DES_CBC, GNUTLS_CIPHER_ARCFOUR, 0}; +- const int comp_priority[] = { GNUTLS_COMP_ZLIB, GNUTLS_COMP_NULL, 0 }; +- const int mac_priority[] = { GNUTLS_MAC_SHA, GNUTLS_MAC_MD5, 0 }; ++ const char *priority_string = "SECURE256:+SECURE192:-VERS-TLS-ALL:+VERS-TLS1.2"; + int ret; + + if (gnutls_global_init () != 0) + return IKS_NOMEM; +@@ -79,13 +75,9 @@ + if (gnutls_init (&data->sess, GNUTLS_CLIENT) != 0) { + gnutls_certificate_free_credentials (data->cred); + return IKS_NOMEM; + } +- gnutls_protocol_set_priority (data->sess, protocol_priority); +- gnutls_cipher_set_priority(data->sess, cipher_priority); +- gnutls_compression_set_priority(data->sess, comp_priority); +- gnutls_kx_set_priority(data->sess, kx_priority); +- gnutls_mac_set_priority(data->sess, mac_priority); ++ gnutls_priority_set_direct(data->sess, priority_string, NULL); + gnutls_credentials_set (data->sess, GNUTLS_CRD_CERTIFICATE, data->cred); + + gnutls_transport_set_push_function (data->sess, (gnutls_push_func) tls_push); + gnutls_transport_set_pull_function (data->sess, (gnutls_pull_func) tls_pull); diff --git a/libs/libctb/Makefile b/libs/libctb/Makefile new file mode 100644 index 000000000..e1d6c1aaf --- /dev/null +++ b/libs/libctb/Makefile @@ -0,0 +1,68 @@ +# +# Copyright (C) 2018 OpenWrt.org +# +# This is free software, licensed under the GNU General Public License v2. +# See /LICENSE for more information. +# + +include $(TOPDIR)/rules.mk + +PKG_NAME:=libctb +PKG_VERSION:=0.16 +PKG_RELEASE:=3 + +PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.gz +PKG_SOURCE_URL:=https://iftools.com/download/ctb/$(PKG_VERSION) +PKG_HASH:=1cb0026a66cfbf8e26988f76cb861f1fbfd04f272f9b9adaf0d463d01282fc08 + +MAKE_PATH:=build + +PKG_INSTALL:=1 + +PKG_LICENSE:=LGPL +PKG_LICENSE_FILES:=build/COPYING +PKG_MAINTAINER:=Sebastian Kemper + +include $(INCLUDE_DIR)/package.mk + +define Package/$(PKG_NAME) + SUBMENU:=Telephony + SECTION:=libs + CATEGORY:=Libraries + TITLE:=Communications toolbox - ctb + URL:=https://iftools.com/opensource/ctb.en.php + DEPENDS:=+libstdcpp +endef + +define Package/$(PKG_NAME)/description +Multiplatform library for different interfaces. +endef + +MAKE_FLAGS += \ + DEBUG=0 \ + GPIB=0 \ + prefix=/usr + +define Build/InstallDev + $(INSTALL_DIR) $(1)/usr/include/ctb-$(PKG_VERSION)/linux + $(INSTALL_DATA) \ + $(PKG_INSTALL_DIR)/usr/include/ctb-$(PKG_VERSION)/*.h \ + $(PKG_BUILD_DIR)/include/ctb-$(PKG_VERSION)/kbhit.h \ + $(1)/usr/include/ctb-$(PKG_VERSION) + $(INSTALL_DATA) \ + $(PKG_INSTALL_DIR)/usr/include/ctb-$(PKG_VERSION)/linux/*.h \ + $(1)/usr/include/ctb-$(PKG_VERSION)/linux + $(INSTALL_DIR) $(1)/usr/lib + $(INSTALL_BIN) \ + $(PKG_INSTALL_DIR)/usr/lib/$(PKG_NAME)-$(PKG_VERSION).so \ + $(1)/usr/lib +endef + +define Package/$(PKG_NAME)/install + $(INSTALL_DIR) $(1)/usr/lib + $(INSTALL_BIN) \ + $(PKG_INSTALL_DIR)/usr/lib/$(PKG_NAME)-$(PKG_VERSION).so \ + $(1)/usr/lib +endef + +$(eval $(call BuildPackage,$(PKG_NAME))) diff --git a/libs/libks/Makefile b/libs/libks/Makefile new file mode 100644 index 000000000..cf6a6cff1 --- /dev/null +++ b/libs/libks/Makefile @@ -0,0 +1,66 @@ +# +# Copyright (C) 2019 Sebastian Kemper +# +# This is free software, licensed under the GNU General Public License v2. +# See /LICENSE for more information. +# + +include $(TOPDIR)/rules.mk + +PKG_NAME:=libks + +PKG_VERSION:=2.0.2 +PKG_RELEASE:=1 + +PKG_SOURCE:=libks-$(PKG_VERSION).tar.gz +PKG_SOURCE_URL:=https://codeload.github.com/signalwire/libks/tar.gz/v$(PKG_VERSION)? +PKG_HASH:=af94f9fcdb2022b8f09187309ac2d372a5a4cc639af77cd4375f2d5c88b4fd63 + +PKG_BUILD_PARALLEL:=1 +CMAKE_INSTALL:=1 + +PKG_LICENSE:= \ + BSD-1-Clause \ + BSD-3-Clause \ + ISC \ + MIT \ + PUBLICDOMAIN \ + twofish +PKG_LICENSE_FILES:=copyright + +PKG_MAINTAINER:=Sebastian Kemper + +include $(INCLUDE_DIR)/package.mk +include $(INCLUDE_DIR)/cmake.mk + +define Package/libks + SUBMENU:=Telephony + SECTION:=libs + CATEGORY:=Libraries + TITLE:=Foundational support for SignalWire C products + URL:=https://github.com/signalwire/libks + ABI_VERSION:=2 + DEPENDS:=+libatomic +libopenssl +libuuid +endef + +# Otherwise OpenWrt's CPPFLAGS are ignored +TARGET_CFLAGS += $(TARGET_CPPFLAGS) + +define Build/InstallDev + $(INSTALL_DIR) $(1)/usr/include/libks2/libks/cmake + $(INSTALL_DATA) $(PKG_INSTALL_DIR)/usr/include/libks2/libks/*.h \ + $(1)/usr/include/libks2/libks + $(INSTALL_DIR) $(1)/usr/lib/pkgconfig + $(INSTALL_DATA) $(PKG_INSTALL_DIR)/usr/include/libks2/libks/cmake/* \ + $(1)/usr/include/libks2/libks/cmake + $(CP) $(PKG_INSTALL_DIR)/usr/lib/libks2.so* $(1)/usr/lib + $(INSTALL_DATA) $(PKG_INSTALL_DIR)/usr/lib/pkgconfig/libks2.pc \ + $(1)/usr/lib/pkgconfig +endef + +define Package/libks/install + $(INSTALL_DIR) $(1)/usr/lib + $(CP) $(PKG_INSTALL_DIR)/usr/lib/libks2.so.$(ABI_VERSION)* $(1)/usr/lib +endef + +$(eval $(call BuildPackage,libks)) diff --git a/libs/libks/patches/01-find-libm.patch b/libs/libks/patches/01-find-libm.patch new file mode 100644 index 000000000..f1a021adf --- /dev/null +++ b/libs/libks/patches/01-find-libm.patch @@ -0,0 +1,15 @@ +--- a/cmake/FindLibM.cmake ++++ b/cmake/FindLibM.cmake +@@ -8,11 +8,7 @@ + # A user may set ``LIBM_ROOT`` to a math library installation root to tell this + # module where to look. + +-find_path(LIBM_INCLUDE_DIRS +- NAMES math.h +- PATHS /usr/include /usr/local/include /usr/local/bic/include +- NO_DEFAULT_PATH +-) ++find_path(LIBM_INCLUDE_DIRS math.h) + find_library(LIBM_LIBRARIES m) + include(FindPackageHandleStandardArgs) + find_package_handle_standard_args(LibM DEFAULT_MSG LIBM_LIBRARIES LIBM_INCLUDE_DIRS) diff --git a/libs/libks/patches/02-correct-signal_h-include.patch b/libs/libks/patches/02-correct-signal_h-include.patch new file mode 100644 index 000000000..c0739b406 --- /dev/null +++ b/libs/libks/patches/02-correct-signal_h-include.patch @@ -0,0 +1,11 @@ +--- a/src/include/libks/ks_platform.h ++++ b/src/include/libks/ks_platform.h +@@ -93,7 +93,7 @@ KS_BEGIN_EXTERN_C + #include + #include + #include +-#include ++#include + #include + #include + #include diff --git a/libs/libks/patches/03-fix-flags.patch b/libs/libks/patches/03-fix-flags.patch new file mode 100644 index 000000000..f936e9d53 --- /dev/null +++ b/libs/libks/patches/03-fix-flags.patch @@ -0,0 +1,24 @@ +--- a/CMakeLists.txt ++++ b/CMakeLists.txt +@@ -11,6 +11,10 @@ option(WITH_LIBBACKTRACE "Enables linkin + # Must include cotire before anything else for auto pch setup + #include(cmake/cotire.cmake) + ++# Declare our project, libks2 ++project(LibKS2 VERSION 2.0.2 LANGUAGES C CXX) ++message("LibKS2 Version ${PROJECT_VERSION_MAJOR}.${PROJECT_VERSION_MINOR}") ++ + # Load our common utility api and setup the platfomrm and build + include(cmake/ksutil.cmake) + ksutil_setup_platform() +@@ -39,10 +43,6 @@ if (KS_PLAT_WIN OR WITH_KS_TEST) + endif() + endif() + +-# Declare our project, libks2 +-project(LibKS2 VERSION 2.0.2 LANGUAGES C CXX) +-message("LibKS2 Version ${PROJECT_VERSION_MAJOR}.${PROJECT_VERSION_MINOR}") +- + # Set package version + set(CPACK_PACKAGE_VERSION_MAJOR ${PROJECT_VERSION_MAJOR}) + set(CPACK_PACKAGE_VERSION_MINOR ${PROJECT_VERSION_MINOR}) diff --git a/libs/libks/patches/04-don_t-override-optimization.patch b/libs/libks/patches/04-don_t-override-optimization.patch new file mode 100644 index 000000000..32c5512a8 --- /dev/null +++ b/libs/libks/patches/04-don_t-override-optimization.patch @@ -0,0 +1,10 @@ +--- a/cmake/ksutil.cmake ++++ b/cmake/ksutil.cmake +@@ -135,7 +135,6 @@ macro(ksutil_setup_platform) + set(KS_PLAT_LIN 1 CACHE INTERNAL "Platform definition" FORCE) + set(CMAKE_POSITION_INDEPENDENT_CODE YES) + +- add_compile_options("$<$:-O2>") + add_compile_options("$<$:-g>") + + add_compile_options("$<$:-O0>") diff --git a/libs/libosip2/Makefile b/libs/libosip2/Makefile new file mode 100644 index 000000000..1fadf0669 --- /dev/null +++ b/libs/libosip2/Makefile @@ -0,0 +1,74 @@ +# +# Copyright (C) 2014 - 2018 OpenWrt.org +# +# This is free software, licensed under the GNU General Public License v2. +# See /LICENSE for more information. +# + +include $(TOPDIR)/rules.mk + +PKG_NAME:=libosip2 +PKG_VERSION:=5.3.0 +PKG_RELEASE:=1 + +PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.gz +PKG_SOURCE_URL:=@GNU/osip +PKG_HASH:=f4725916c22cf514969efb15c3c207233d64739383f7d42956038b78f6cae8c8 + +PKG_FIXUP:=autoreconf +PKG_INSTALL:=1 +PKG_BUILD_PARALLEL:=1 + +PKG_LICENSE:=LGPL-2.1+ +PKG_LICENSE_FILES:=COPYING + +include $(INCLUDE_DIR)/package.mk + +define Package/libosip2 + SUBMENU:=Telephony + SECTION:=libs + CATEGORY:=Libraries + TITLE:=GNU oSIP library + URL:=http://www.gnu.org/software/osip/ + ABI_VERSION:=15 + DEPENDS:=+librt +endef + +define Package/libosip2/description + GNU oSIP library, a Session Initiation Protocol (SIP) implementation. +endef + +# toolchain __arc__ define conflicts with libosip2 source +TARGET_CFLAGS += $(if $(CONFIG_arc),-U__arc__) + +CONFIGURE_ARGS += \ + --enable-shared \ + --enable-static \ + --disable-silent-rules \ + --disable-trace \ + --disable-mpatrol \ + --disable-gprof \ + --disable-mt \ + --enable-pthread \ + --enable-semaphore \ + --disable-gperf \ + --disable-test \ + --disable-minisize + +define Build/InstallDev + $(INSTALL_DIR) $(1)/usr/include + $(CP) $(PKG_INSTALL_DIR)/usr/include/osip{,parser}2 $(1)/usr/include/ + + $(INSTALL_DIR) $(1)/usr/lib + $(CP) $(PKG_INSTALL_DIR)/usr/lib/libosip{,parser}2.{a,so*} $(1)/usr/lib/ + + $(INSTALL_DIR) $(1)/usr/lib/pkgconfig + $(CP) $(PKG_INSTALL_DIR)/usr/lib/pkgconfig/libosip2.pc $(1)/usr/lib/pkgconfig/ +endef + +define Package/libosip2/install + $(INSTALL_DIR) $(1)/usr/lib + $(CP) $(PKG_INSTALL_DIR)/usr/lib/libosip{,parser}2.so.$(ABI_VERSION)* $(1)/usr/lib/ +endef + +$(eval $(call BuildPackage,libosip2)) diff --git a/libs/libpri/Makefile b/libs/libpri/Makefile new file mode 100644 index 000000000..a52221ec9 --- /dev/null +++ b/libs/libpri/Makefile @@ -0,0 +1,58 @@ +# +# Copyright (C) 2015 - 2018 OpenWrt.org +# +# This is free software, licensed under the GNU General Public License v2. +# See /LICENSE for more information. +# + +include $(TOPDIR)/rules.mk + +PKG_NAME:=libpri +PKG_VERSION:=1.6.0 +PKG_RELEASE:=4 + +PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.gz +PKG_SOURCE_URL:=https://downloads.asterisk.org/pub/telephony/libpri/releases +PKG_HASH:=7225ea7ec334a115f9dc08e71f55589c38cb4e00b13964cd2f08cc4e6123e3f6 +PKG_MAINTAINER:=Daniel Golle + +PKG_INSTALL:=1 + +include $(INCLUDE_DIR)/package.mk + +define Package/libpri + SECTION:=libs + CATEGORY:=Libraries + TITLE:=libpri Primary Rate ISDN implementation + URL:=http://www.asterisk.org/ + DEPENDS:=+dahdi-tools-libtonezone +endef + +define Package/libpri/description + libpri is a C implementation of the Primary Rate ISDN specification. It was + based on the Bellcore specification SR-NWT-002343 for National ISDN. As of + May 12, 2001, it has been tested work with NI-2, Nortel DMS-100, and + Lucent 5E Custom protocols on switches from Nortel and Lucent. +endef + +MAKE_FLAGS += \ + OSARCH=Linux \ + LDCONFIG=ldconfig + +define Build/Configure +endef + +define Build/InstallDev + $(INSTALL_DIR) $(1)/usr/include + $(INSTALL_DATA) $(PKG_INSTALL_DIR)/usr/include/*.h $(1)/usr/include/ + $(INSTALL_DIR) $(1)/usr/lib + $(CP) $(PKG_INSTALL_DIR)/usr/lib/libpri*.a $(1)/usr/lib/ + $(CP) $(PKG_INSTALL_DIR)/usr/lib/libpri*.so* $(1)/usr/lib/ +endef + +define Package/libpri/install + $(INSTALL_DIR) $(1)/usr/lib + $(CP) $(PKG_INSTALL_DIR)/usr/lib/libpri*.so* $(1)/usr/lib/ +endef + +$(eval $(call BuildPackage,libpri)) diff --git a/libs/libpri/patches/001-fix-include-signal-h-warning.patch b/libs/libpri/patches/001-fix-include-signal-h-warning.patch new file mode 100644 index 000000000..9ce45f69a --- /dev/null +++ b/libs/libpri/patches/001-fix-include-signal-h-warning.patch @@ -0,0 +1,22 @@ +--- a/pritest.c ++++ b/pritest.c +@@ -41,7 +41,7 @@ + #include + #include + #include +-#include ++#include + #include + #include + #include +--- a/testprilib.c ++++ b/testprilib.c +@@ -41,7 +41,7 @@ + #include + #include + #include +-#include ++#include + #include + #include + #include diff --git a/libs/libpri/patches/010-no-werror.patch b/libs/libpri/patches/010-no-werror.patch new file mode 100644 index 000000000..e66f42866 --- /dev/null +++ b/libs/libpri/patches/010-no-werror.patch @@ -0,0 +1,11 @@ +--- a/Makefile ++++ b/Makefile +@@ -68,7 +68,7 @@ DYNAMIC_OBJS= \ + $(STATIC_OBJS) + CFLAGS ?= -g + CFLAGS += $(CPPFLAGS) +-CFLAGS += -Wall -Werror -Wstrict-prototypes -Wmissing-prototypes ++CFLAGS += -Wall -Wstrict-prototypes -Wmissing-prototypes + CFLAGS += -fPIC $(ALERTING) $(LIBPRI_OPT) $(COVERAGE_CFLAGS) + INSTALL_PREFIX=$(DESTDIR) + INSTALL_BASE=/usr diff --git a/libs/libpri/patches/100_add-an-ability-to-build-libpri-on-MacOS-for-Linux-ta.patch b/libs/libpri/patches/100_add-an-ability-to-build-libpri-on-MacOS-for-Linux-ta.patch new file mode 100644 index 000000000..dd6d843a4 --- /dev/null +++ b/libs/libpri/patches/100_add-an-ability-to-build-libpri-on-MacOS-for-Linux-ta.patch @@ -0,0 +1,39 @@ +Upstream issue: https://issues.asterisk.org/jira/browse/PRI-188 + +From ec1d6589c6e4eb6550cb92d5e0f214f7b31e8d5f Mon Sep 17 00:00:00 2001 +From: "Sergey V. Lobanov" +Date: Sun, 30 Jan 2022 13:25:17 +0300 +Subject: [PATCH] Add an ability to build libpri on MacOS for Linux target + +This patch allows to rededine ar and ranlib tool using AR and +RANLIB make flags. + +Fixes: PRI-188 + +Signed-off-by: Sergey V. Lobanov +--- + Makefile | 6 ++++-- + 1 file changed, 4 insertions(+), 2 deletions(-) + +--- a/Makefile ++++ b/Makefile +@@ -27,6 +27,8 @@ + CC=gcc + GREP=grep + AWK=awk ++AR=ar ++RANLIB=ranlib + + OSARCH=$(shell uname -s) + PROC?=$(shell uname -m) +@@ -193,8 +195,8 @@ MAKE_DEPS= -MD -MT $@ -MF .$(subst /,_,$ + $(CC) $(CFLAGS) $(MAKE_DEPS) -c -o $@ $< + + $(STATIC_LIBRARY): $(STATIC_OBJS) +- ar rcs $(STATIC_LIBRARY) $(STATIC_OBJS) +- ranlib $(STATIC_LIBRARY) ++ $(AR) rcs $(STATIC_LIBRARY) $(STATIC_OBJS) ++ $(RANLIB) $(STATIC_LIBRARY) + + $(DYNAMIC_LIBRARY): $(DYNAMIC_OBJS) + $(CC) $(SOFLAGS) -o $@ $(DYNAMIC_OBJS) diff --git a/libs/libsrtp/Makefile b/libs/libsrtp/Makefile new file mode 100644 index 000000000..337fc6b7f --- /dev/null +++ b/libs/libsrtp/Makefile @@ -0,0 +1,62 @@ +# +# Copyright (C) 2017 OpenWrt.org +# Copyright (C) 2017 Jiri Slachta +# +# This is free software, licensed under the GNU General Public License v2. +# See /LICENSE for more information. +# +include $(TOPDIR)/rules.mk + +PKG_NAME:=libsrtp +PKG_VERSION:=2.4.2 +PKG_RELEASE:=2 + +PKG_SOURCE:=libsrtp-$(PKG_VERSION).tar.gz +PKG_SOURCE_URL:=https://codeload.github.com/cisco/libsrtp/tar.gz/v$(PKG_VERSION)? +PKG_HASH:=3b1bcb14ebda572b04b9bdf07574a449c84cb924905414e4d94e62837d22b628 + +PKG_LICENSE:=BSD-3-Clause +PKG_LICENSE_FILES:=LICENSE +PKG_MAINTAINER:=Jiri Slachta + +include $(INCLUDE_DIR)/package.mk + +CONFIGURE_ARGS+=--enable-openssl + +define Package/libsrtp2 + SUBMENU:=Telephony + SECTION:=libs + CATEGORY:=Libraries + TITLE:=Secure RTP (SRTP) library, v$(PKG_VERSION) + URL:=https://github.com/cisco/libsrtp + DEPENDS:=+libopenssl + ABI_VERSION:=1 +endef + +define Package/libsrtp2/description +Open-source implementation of the Secure Real-time Transport +Protocol (SRTP) originally authored by Cisco Systems, Inc. +It is available under a BSD-style license. +endef + +define Build/Install + $(call Build/Install/Default,all shared_library install) +endef + +define Build/InstallDev + $(INSTALL_DIR) $(1)/usr/include + $(CP) $(PKG_INSTALL_DIR)/usr/include/srtp2 $(1)/usr/include/ + $(INSTALL_DIR) $(1)/usr/lib + $(CP) $(PKG_INSTALL_DIR)/usr/lib/libsrtp2.{a,so*} $(1)/usr/lib/ + $(INSTALL_DIR) $(1)/usr/lib/pkgconfig + $(CP) $(PKG_INSTALL_DIR)/usr/lib/pkgconfig/libsrtp2.pc $(1)/usr/lib/pkgconfig/ +endef + +define Package/libsrtp2/install + $(INSTALL_DIR) $(1)/usr/lib + $(CP) \ + $(PKG_INSTALL_DIR)/usr/lib/libsrtp2.so.$(ABI_VERSION)* \ + $(1)/usr/lib/ +endef + +$(eval $(call BuildPackage,libsrtp2)) diff --git a/libs/pjproject/Makefile b/libs/pjproject/Makefile new file mode 100644 index 000000000..326708c3d --- /dev/null +++ b/libs/pjproject/Makefile @@ -0,0 +1,127 @@ +# +# Copyright (C) 2006-2018 OpenWrt.org +# Copyright (C) 2016 Cesnet, z.s.p.o. +# Copyright (C) 2017 - 2018 Jiri Slachta +# +# This is free software, licensed under the GNU General Public License v2. +# See /LICENSE for more information. +# + +include $(TOPDIR)/rules.mk + +PKG_NAME:=pjproject +PKG_VERSION:=2.13.1 +PKG_RELEASE:=2 +PKG_CPE_ID:=cpe:/a:pjsip:pjsip + +# download "vX.Y.tar.gz" as "pjproject-vX.Y.tar.gz" +PKG_SOURCE_URL_FILE:=$(PKG_VERSION).tar.gz +PKG_SOURCE:=$(PKG_NAME)-$(PKG_SOURCE_URL_FILE) +PKG_SOURCE_URL:=https://github.com/pjsip/$(PKG_NAME)/archive/refs/tags +PKG_HASH:=32a5ab5bfbb9752cb6a46627e4c410e61939c8dbbd833ac858473cfbd9fb9d7d +PKG_INSTALL:=1 + +PKG_LICENSE:=GPL-2.0 +PKG_LICENSE_FILES:=COPYING +PKG_MAINTAINER:=Jiri Slachta + +PKG_BUILD_DIR:=$(BUILD_DIR)/$(PKG_NAME)-$(PKG_VERSION) + +PKG_CONFIG_DEPENDS:=CONFIG_SOFT_FLOAT + +include $(INCLUDE_DIR)/package.mk + +define Package/pjproject/Default + SECTION:=lib + CATEGORY:=Libraries + SUBMENU:=Telephony + URL:=https://www.pjsip.org + DEPENDS:=+libstdcpp +libopenssl +libuuid +libpthread +endef + +define Package/pjproject/install/lib + $(INSTALL_DIR) $(1)/usr/lib + $(CP) $(PKG_INSTALL_DIR)/usr/lib/$(2).so* $(1)/usr/lib +endef + +define PJSIPpackage + define Package/$(1) + $$(call Package/pjproject/Default) + TITLE:=$(1) library + DEPENDS+=$(3) + endef + + define Package/$(1)/install +$(call Package/pjproject/install/lib,$$(1),$2) + endef + + $$(eval $$(call BuildPackage,$(1))) +endef + +CONFIGURE_ARGS+= \ + $(if $(CONFIG_SOFT_FLOAT),--disable-floating-point) \ + --disable-android-mediacodec \ + --disable-bcg729 \ + --disable-darwin-ssl \ + --disable-ext-sound \ + --disable-ffmpeg \ + --disable-g711-codec \ + --disable-g722-codec \ + --disable-g7221-codec \ + --disable-gsm-codec \ + --disable-ilbc-codec \ + --disable-ipp \ + --disable-l16-codec \ + --disable-libsrtp \ + --disable-libwebrtc \ + --disable-libyuv \ + --disable-opencore-amr \ + --disable-openh264 \ + --disable-opus \ + --disable-resample \ + --disable-sdl \ + --disable-silk \ + --disable-sound \ + --disable-speex-aec \ + --disable-speex-codec \ + --disable-upnp \ + --disable-v4l2 \ + --disable-video \ + --enable-shared \ + --with-ssl="$(STAGING_DIR)/usr" \ + --without-external-gsm \ + --without-external-pa \ + --without-external-webrtc + +TARGET_CFLAGS+=$(TARGET_CPPFLAGS) + +define Build/Compile + $(MAKE) $(PKG_JOBS) -C $(PKG_BUILD_DIR) EXCLUDE_APP=1 dep + $(MAKE) $(PKG_JOBS) -C $(PKG_BUILD_DIR) EXCLUDE_APP=1 +endef + +PJPROJECT_LIBS:= \ + libpj libpjlib-util libpjmedia libpjnath libpjsip-simple \ + libpjsip-ua libpjsip libpjsua libpjsua2 + +define Build/InstallDev + $(INSTALL_DIR) $(1)/usr/{include,lib} + + $(CP) -R $(PKG_INSTALL_DIR)/usr/include/* $(1)/usr/include + + $(foreach m,$(PJPROJECT_LIBS),$(CP) $(PKG_INSTALL_DIR)/usr/lib/$(m)* $(1)/usr/lib;) + + $(INSTALL_DIR) $(1)/usr/lib/pkgconfig + $(INSTALL_DATA) $(PKG_INSTALL_DIR)/usr/lib/pkgconfig/libpjproject.pc \ + $(1)/usr/lib/pkgconfig +endef + +$(eval $(call PJSIPpackage,libpj,libpj,+librt)) +$(eval $(call PJSIPpackage,libpjlib-util,libpjlib-util,+libpj +librt)) +$(eval $(call PJSIPpackage,libpjmedia,libpjmedia*,+libpj +libpjlib-util +libpjnath +librt)) +$(eval $(call PJSIPpackage,libpjnath,libpjnath,+libpj +libpjlib-util +librt)) +$(eval $(call PJSIPpackage,libpjsip-simple,libpjsip-simple,+libpj +libpjlib-util +libpjsip +librt)) +$(eval $(call PJSIPpackage,libpjsip-ua,libpjsip-ua,+libpj +libpjlib-util +libpjmedia +libpjsip-simple +libpjsip +librt)) +$(eval $(call PJSIPpackage,libpjsip,libpjsip,+libpj +libpjlib-util +librt)) +$(eval $(call PJSIPpackage,libpjsua,libpjsua,+libpj +libpjlib-util +libpjmedia +libpjnath +libpjsip-simple +libpjsip-ua +libpjsip +librt)) +$(eval $(call PJSIPpackage,libpjsua2,libpjsua2,+libpj +libpjlib-util +libpjmedia +libpjnath +libpjsip-simple +libpjsip-ua +libpjsip +librt +libpjsua)) diff --git a/libs/pjproject/patches/0001-change_linker.patch b/libs/pjproject/patches/0001-change_linker.patch new file mode 100644 index 000000000..5fd150304 --- /dev/null +++ b/libs/pjproject/patches/0001-change_linker.patch @@ -0,0 +1,11 @@ +--- a/build/cc-auto.mak.in ++++ b/build/cc-auto.mak.in +@@ -2,7 +2,7 @@ export CC = @CC@ -c + export CXX = @CXX@ -c + export AR = @AR@ + export AR_FLAGS = @AR_FLAGS@ +-export LD = @LD@ ++export LD = @CXX@ + export LDOUT = -o + export RANLIB = @RANLIB@ + diff --git a/libs/pjproject/patches/0004-config_site.patch b/libs/pjproject/patches/0004-config_site.patch new file mode 100644 index 000000000..d9d67aecf --- /dev/null +++ b/libs/pjproject/patches/0004-config_site.patch @@ -0,0 +1,94 @@ +--- /dev/null ++++ b/pjlib/include/pj/config_site.h +@@ -0,0 +1,91 @@ ++/* ++ * Asterisk config_site.h ++ */ ++ ++#include ++ ++/* ++ * Defining PJMEDIA_HAS_SRTP to 0 does NOT disable Asterisk's ability to use srtp. ++ * It only disables the pjmedia srtp transport which Asterisk doesn't use. ++ * The reason for the disable is that while Asterisk works fine with older libsrtp ++ * versions, newer versions of pjproject won't compile with them. ++ */ ++#define PJMEDIA_HAS_SRTP 0 ++ ++#define PJ_HAS_IPV6 1 ++#define NDEBUG 1 ++ ++#define PJ_MAX_HOSTNAME (256) ++#define PJSIP_MAX_URL_SIZE (512) ++#ifdef PJ_HAS_LINUX_EPOLL ++#define PJ_IOQUEUE_MAX_HANDLES (5000) ++#else ++#define PJ_IOQUEUE_MAX_HANDLES (FD_SETSIZE) ++#endif ++#define PJ_IOQUEUE_HAS_SAFE_UNREG 1 ++#define PJ_IOQUEUE_MAX_EVENTS_IN_SINGLE_POLL (16) ++ ++#define PJ_SCANNER_USE_BITWISE 0 ++#define PJ_OS_HAS_CHECK_STACK 0 ++ ++#ifndef PJ_LOG_MAX_LEVEL ++#define PJ_LOG_MAX_LEVEL 6 ++#endif ++ ++#define PJ_ENABLE_EXTRA_CHECK 1 ++#define PJSIP_MAX_TSX_COUNT ((64*1024)-1) ++#define PJSIP_MAX_DIALOG_COUNT ((64*1024)-1) ++#define PJSIP_UDP_SO_SNDBUF_SIZE (512*1024) ++#define PJSIP_UDP_SO_RCVBUF_SIZE (512*1024) ++#define PJ_DEBUG 0 ++#define PJSIP_SAFE_MODULE 0 ++#define PJ_HAS_STRICMP_ALNUM 0 ++ ++/* ++ * Do not ever enable PJ_HASH_USE_OWN_TOLOWER because the algorithm is ++ * inconsistently used when calculating the hash value and doesn't ++ * convert the same characters as pj_tolower()/tolower(). Thus you ++ * can get different hash values if the string hashed has certain ++ * characters in it. (ASCII '@', '[', '\\', ']', '^', and '_') ++ */ ++#undef PJ_HASH_USE_OWN_TOLOWER ++ ++/* ++ It is imperative that PJSIP_UNESCAPE_IN_PLACE remain 0 or undefined. ++ Enabling it will result in SEGFAULTS when URIs containing escape sequences are encountered. ++*/ ++#undef PJSIP_UNESCAPE_IN_PLACE ++#define PJSIP_MAX_PKT_LEN 65535 ++ ++#undef PJ_TODO ++#define PJ_TODO(x) ++ ++/* Defaults too low for WebRTC */ ++#define PJ_ICE_MAX_CAND 64 ++#define PJ_ICE_MAX_CHECKS (PJ_ICE_MAX_CAND * PJ_ICE_MAX_CAND) ++ ++/* Increase limits to allow more formats */ ++#define PJMEDIA_MAX_SDP_FMT 64 ++#define PJMEDIA_MAX_SDP_BANDW 4 ++#define PJMEDIA_MAX_SDP_ATTR (PJMEDIA_MAX_SDP_FMT*3 + 4) ++#define PJMEDIA_MAX_SDP_MEDIA 16 ++ ++/* ++ * Turn off the periodic sending of CRLNCRLN. Default is on (90 seconds), ++ * which conflicts with the global section's keep_alive_interval option in ++ * pjsip.conf. ++ */ ++#define PJSIP_TCP_KEEP_ALIVE_INTERVAL 0 ++#define PJSIP_TLS_KEEP_ALIVE_INTERVAL 0 ++ ++#define PJSIP_TSX_UAS_CONTINUE_ON_TP_ERROR 0 ++#define PJ_SSL_SOCK_OSSL_USE_THREAD_CB 0 ++#define PJSIP_AUTH_ALLOW_MULTIPLE_AUTH_HEADER 1 ++ ++/* ++ * The default is 32 with 8 being used by pjproject itself. ++ * Since this value is used in invites, dialogs, transports ++ * and subscriptions as well as the global pjproject endpoint, ++ * we don't want to increase it too much. ++ */ ++#define PJSIP_MAX_MODULE 38 diff --git a/libs/pjproject/patches/0006-fix-pkg_config-file.patch b/libs/pjproject/patches/0006-fix-pkg_config-file.patch new file mode 100644 index 000000000..90f1d225c --- /dev/null +++ b/libs/pjproject/patches/0006-fix-pkg_config-file.patch @@ -0,0 +1,24 @@ +--- a/libpjproject.pc.in ++++ b/libpjproject.pc.in +@@ -2,8 +2,8 @@ + + prefix=@PREFIX@ + exec_prefix=${prefix} +-libdir=@LIBDIR@ +-includedir=@INCLUDEDIR@ ++libdir=${exec_prefix}/lib ++includedir=${prefix}/include + + Name: libpjproject + Description: Multimedia communication library +--- a/build.mak.in ++++ b/build.mak.in +@@ -352,6 +352,6 @@ export PJ_LIBXX_FILES := $(APP_LIBXX_FIL + export PJ_INSTALL_DIR := @prefix@ + export PJ_INSTALL_INC_DIR := @includedir@ + export PJ_INSTALL_LIB_DIR := @libdir@ +-export PJ_INSTALL_CFLAGS := -I$(PJ_INSTALL_INC_DIR) -DPJ_AUTOCONF=1 @ac_cflags@ ++export PJ_INSTALL_CFLAGS := -DPJ_AUTOCONF=1 @ac_cflags@ + export PJ_INSTALL_LDFLAGS_PRIVATE := $(APP_THIRD_PARTY_LIBS) $(APP_THIRD_PARTY_EXT) @LIBS@ +-export PJ_INSTALL_LDFLAGS := -L$(PJ_INSTALL_LIB_DIR) $(filter-out $(PJ_INSTALL_LDFLAGS_PRIVATE),$(APP_LDXXLIBS)) ++export PJ_INSTALL_LDFLAGS := $(filter-out $(PJ_INSTALL_LDFLAGS_PRIVATE),$(APP_LDXXLIBS)) diff --git a/libs/pjproject/patches/0010-Make-sure-that-NOTIFY-tdata-is-set-before-sending-it_new-129fb323a66dd1fd16880fe5ba5e6a57.patch b/libs/pjproject/patches/0010-Make-sure-that-NOTIFY-tdata-is-set-before-sending-it_new-129fb323a66dd1fd16880fe5ba5e6a57.patch new file mode 100644 index 000000000..36eacfcb0 --- /dev/null +++ b/libs/pjproject/patches/0010-Make-sure-that-NOTIFY-tdata-is-set-before-sending-it_new-129fb323a66dd1fd16880fe5ba5e6a57.patch @@ -0,0 +1,27 @@ +From ac685b30c17be461b2bf5b46a772ed9742b8e985 Mon Sep 17 00:00:00 2001 +From: Riza Sulistyo +Date: Thu, 9 Feb 2023 13:19:23 +0700 +Subject: [PATCH] Make sure that NOTIFY tdata is set before sending it. + +--- + pjsip/src/pjsip-simple/evsub.c | 9 ++++++--- + 1 file changed, 6 insertions(+), 3 deletions(-) + +--- a/pjsip/src/pjsip-simple/evsub.c ++++ b/pjsip/src/pjsip-simple/evsub.c +@@ -2224,9 +2224,12 @@ static void on_tsx_state_uas( pjsip_evsu + /* Send the pending NOTIFY sent by app from inside + * on_rx_refresh() callback. + */ +- pj_assert(sub->pending_notify); +- status = pjsip_evsub_send_request(sub, sub->pending_notify); +- sub->pending_notify = NULL; ++ //pj_assert(sub->pending_notify); ++ /* Make sure that pending_notify is set. */ ++ if (sub->pending_notify) { ++ status = pjsip_evsub_send_request(sub, sub->pending_notify); ++ sub->pending_notify = NULL; ++ } + + } else if (pjsip_method_cmp(&tsx->method, &pjsip_notify_method)==0) { + diff --git a/libs/pjproject/patches/0020-log-dropped-packet-in-debug.patch b/libs/pjproject/patches/0020-log-dropped-packet-in-debug.patch new file mode 100644 index 000000000..e625f2e18 --- /dev/null +++ b/libs/pjproject/patches/0020-log-dropped-packet-in-debug.patch @@ -0,0 +1,26 @@ +--- a/pjsip/src/pjsip/sip_transport.c ++++ b/pjsip/src/pjsip/sip_transport.c +@@ -2088,15 +2088,17 @@ PJ_DEF(pj_ssize_t) pjsip_tpmgr_receive_p + * which were sent to keep NAT bindings. + */ + if (tmp.slen) { +- PJ_LOG(1, (THIS_FILE, +- "Error processing %d bytes packet from %s %s:%d %.*s:\n" +- "%.*s\n" +- "-- end of packet.", ++ PJ_LOG(2, (THIS_FILE, ++ "Dropping %d bytes packet from %s %s:%d %.*s\n", + msg_fragment_size, + rdata->tp_info.transport->type_name, +- rdata->pkt_info.src_name, ++ rdata->pkt_info.src_name, + rdata->pkt_info.src_port, +- (int)tmp.slen, tmp.ptr, ++ (int)tmp.slen, tmp.ptr)); ++ PJ_LOG(4, (THIS_FILE, ++ "Dropped packet:" ++ "%.*s\n" ++ "-- end of packet.", + (int)msg_fragment_size, + rdata->msg_info.msg_buf)); + } diff --git a/libs/re/Makefile b/libs/re/Makefile new file mode 100644 index 000000000..cdf9c8850 --- /dev/null +++ b/libs/re/Makefile @@ -0,0 +1,80 @@ +# +# Copyright (C) 2010-2017 OpenWrt.org +# Copyright (C) 2010 Alfred E. Heggestad +# +# This is free software, licensed under the GNU General Public License v2. +# See /LICENSE for more information. +# + +include $(TOPDIR)/rules.mk + +PKG_NAME:=re +PKG_VERSION:=2.0.1 +PKG_RELEASE:=1 + +PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.gz +PKG_SOURCE_URL:=https://codeload.github.com/baresip/re/tar.gz/v$(PKG_VERSION)? +PKG_HASH:=43aa439b96aff75fe5768b9f9d49dea97042e42e7647df47b345465763e2f7ed + +PKG_LICENSE:=BSD-3-Clause +PKG_LICENSE_FILES:=docs/COPYING +PKG_MAINTAINER:=Jiri Slachta + +PKG_BUILD_PARALLEL:=1 +PKG_INSTALL:=1 + +include $(INCLUDE_DIR)/package.mk + +define Package/libre + SUBMENU:=Telephony + SECTION:=libs + CATEGORY:=Libraries + DEPENDS:=+libopenssl +zlib + TITLE:=Generic library for real-time communications with async IO support + URL:=https://github.com/baresip/re + ABI_VERSION:=1 +endef + +# re.mk is used for this and all related packages (rem, restund and baresip). +# It relies on SYSROOT and SYSROOT_ALT being set. SYSROOT is used for finding +# toolchain headers (like pthread.h). SYSROOT_ALT is used for finding headers +# from other packages, like openssl etc. +# +# CFLAGS are picked up from the environment, as well as CPPFLAGS (and LD etc.). +# But LDFLAGS aren't picked up, so they need to be handed over via +# EXTRA_LFLAGS. +# +# LD is changed to TARGET_CC to fix build failures on x86 32bit. Without this +# there's no linking to ssp, which results in undefined references. + +# used by 001-extend-ninit-nclose-check.patch +TARGET_CFLAGS+=-DOPENWRT + +ifneq ($(CONFIG_USE_GLIBC)$(CONFIG_USE_MUSL),) +TARGET_CFLAGS+=-D_GNU_SOURCE +endif + +MAKE_FLAGS+= \ + CROSS_COMPILE="$(TARGET_CROSS)" \ + EXTRA_LFLAGS="$(TARGET_LDFLAGS)" \ + LD="$(TARGET_CC)" \ + OS=linux \ + RELEASE=1 \ + SYSROOT="$(shell $(FIND) $(TOOLCHAIN_DIR) -path '*/include/pthread.h' | sed -ne '1s|/include/pthread.h||p')" \ + SYSROOT_ALT="$(STAGING_DIR)/usr" + +define Build/InstallDev + $(INSTALL_DIR) $(1)/usr/share/re + $(INSTALL_DATA) $(PKG_INSTALL_DIR)/usr/share/re/re.mk $(1)/usr/share/re + $(INSTALL_DIR) $(1)/usr/include + $(CP) $(PKG_INSTALL_DIR)/usr/include/re $(1)/usr/include + $(INSTALL_DIR) $(1)/usr/lib + $(CP) $(PKG_INSTALL_DIR)/usr/lib/libre.{a,so*} $(1)/usr/lib +endef + +define Package/libre/install + $(INSTALL_DIR) $(1)/usr/lib + $(CP) $(PKG_INSTALL_DIR)/usr/lib/libre.so.$(ABI_VERSION)* $(1)/usr/lib +endef + +$(eval $(call BuildPackage,libre)) diff --git a/libs/re/patches/001-extend-ninit-nclose-check.patch b/libs/re/patches/001-extend-ninit-nclose-check.patch new file mode 100644 index 000000000..9a227595a --- /dev/null +++ b/libs/re/patches/001-extend-ninit-nclose-check.patch @@ -0,0 +1,20 @@ +--- a/src/dns/res.c ++++ b/src/dns/res.c +@@ -26,7 +26,7 @@ int get_resolv_dns(char *domain, size_t + uint32_t i; + int ret, err; + +-#ifdef OPENBSD ++#if defined(OPENBSD) || defined(OPENWRT) + ret = res_init(); + state = _res; + #else +@@ -76,7 +76,7 @@ int get_resolv_dns(char *domain, size_t + *n = i; + + out: +-#ifdef OPENBSD ++#if defined(OPENBSD) || defined(OPENWRT) + #else + res_nclose(&state); + #endif diff --git a/libs/re/patches/002-fix-redefine-ssize_t.patch b/libs/re/patches/002-fix-redefine-ssize_t.patch new file mode 100644 index 000000000..5a9e35431 --- /dev/null +++ b/libs/re/patches/002-fix-redefine-ssize_t.patch @@ -0,0 +1,11 @@ +--- a/include/re_types.h ++++ b/include/re_types.h +@@ -47,7 +47,7 @@ typedef unsigned long long int uint64 + #endif /* __BIT_TYPES_DEFINED__ */ + + #endif /* __int8_t_defined */ +-#ifndef __ssize_t_defined ++#if !defined(__ssize_t_defined) && !defined(__DEFINED_ssize_t) + typedef long ssize_t; + #define __ssize_t_defined + #endif diff --git a/libs/re/patches/004-prevent-optimization-meddling.patch b/libs/re/patches/004-prevent-optimization-meddling.patch new file mode 100644 index 000000000..97caed3ec --- /dev/null +++ b/libs/re/patches/004-prevent-optimization-meddling.patch @@ -0,0 +1,10 @@ +--- a/mk/re.mk ++++ b/mk/re.mk +@@ -47,7 +47,6 @@ + + ifneq ($(RELEASE),) + CFLAGS += -DRELEASE +-OPT_SPEED=1 + endif + + ifneq ($(TRACE_ERR),) diff --git a/libs/re/patches/005-fix-builds-for-mipsel-targets.patch b/libs/re/patches/005-fix-builds-for-mipsel-targets.patch new file mode 100644 index 000000000..c50a463a5 --- /dev/null +++ b/libs/re/patches/005-fix-builds-for-mipsel-targets.patch @@ -0,0 +1,14 @@ +--- a/mk/re.mk ++++ b/mk/re.mk +@@ -412,11 +412,6 @@ endif + + CFLAGS += -DARCH=\"$(ARCH)\" + +-ifeq ($(ARCH),mipsel) +-CFLAGS += -march=mips32 +-endif +- +- + ############################################################################## + # + # External libraries section diff --git a/libs/rem/Makefile b/libs/rem/Makefile new file mode 100644 index 000000000..a87a4ce2b --- /dev/null +++ b/libs/rem/Makefile @@ -0,0 +1,61 @@ +# +# Copyright (C) 2010-2017 OpenWrt.org +# Copyright (C) 2010 Alfred E. Heggestad +# +# This is free software, licensed under the GNU General Public License v2. +# See /LICENSE for more information. +# + +include $(TOPDIR)/rules.mk + +PKG_NAME:=rem +PKG_VERSION:=1.0.0 +PKG_RELEASE:=1 + +PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.gz +PKG_SOURCE_URL:=https://codeload.github.com/baresip/rem/tar.gz/v$(PKG_VERSION)? +PKG_HASH:=bcc91bb521fae183357fb422b00a3981477a22e99d3afe165c4ec50a6bbed9da + +PKG_LICENSE:=BSD-3-Clause +PKG_LICENSE_FILES:=docs/COPYING +PKG_MAINTAINER:=Jiri Slachta + +PKG_BUILD_PARALLEL:=1 +PKG_INSTALL:=1 + +include $(INCLUDE_DIR)/package.mk + +define Package/librem + SUBMENU:=Telephony + SECTION:=libs + CATEGORY:=Libraries + DEPENDS:=+libre + TITLE:=Audio and video processing media library + URL:=https://github.com/baresip/rem +endef + +MAKE_FLAGS+= \ + CROSS_COMPILE="$(TARGET_CROSS)" \ + EXTRA_LFLAGS="$(TARGET_LDFLAGS)" \ + LD="$(TARGET_CC)" \ + LIBRE_MK="$(STAGING_DIR)/usr/share/re/re.mk" \ + LIBRE_INC="$(STAGING_DIR)/usr/include/re" \ + LIBRE_SO="$(STAGING_DIR)/usr/lib" \ + OS=linux \ + RELEASE=1 \ + SYSROOT="$(shell $(FIND) $(TOOLCHAIN_DIR) -path '*/include/pthread.h' | sed -ne '1s|/include/pthread.h||p')" \ + SYSROOT_ALT="$(STAGING_DIR)/usr" + +define Build/InstallDev + $(INSTALL_DIR) $(1)/usr/include + $(CP) $(PKG_INSTALL_DIR)/usr/include/rem $(1)/usr/include + $(INSTALL_DIR) $(1)/usr/lib + $(CP) $(PKG_INSTALL_DIR)/usr/lib/librem.{a,so} $(1)/usr/lib +endef + +define Package/librem/install + $(INSTALL_DIR) $(1)/usr/lib + $(CP) $(PKG_INSTALL_DIR)/usr/lib/librem.so $(1)/usr/lib +endef + +$(eval $(call BuildPackage,librem)) diff --git a/libs/signalwire-client-c/Makefile b/libs/signalwire-client-c/Makefile new file mode 100644 index 000000000..debb11939 --- /dev/null +++ b/libs/signalwire-client-c/Makefile @@ -0,0 +1,69 @@ +# +# Copyright (C) 2019 Sebastian Kemper +# +# This is free software, licensed under the GNU General Public License v2. +# See /LICENSE for more information. +# + +include $(TOPDIR)/rules.mk + +PKG_NAME:=signalwire-client-c + +PKG_VERSION:=2.0.0 +PKG_RELEASE:=1 + +PKG_SOURCE:=signalwire-c-$(PKG_VERSION).tar.gz +PKG_SOURCE_URL:=https://codeload.github.com/signalwire/signalwire-c/tar.gz/v$(PKG_VERSION)? +PKG_HASH:=7916ad76b2c2c75ff616d19bf044894771b3f8602b80a6f74d8ba26206faef79 + +PKG_BUILD_DIR:=$(BUILD_DIR)/signalwire-c-$(PKG_VERSION) + +PKG_BUILD_PARALLEL:=1 +CMAKE_INSTALL:=1 + +PKG_LICENSE:=MIT +PKG_LICENSE_FILES:=copyright + +PKG_MAINTAINER:=Sebastian Kemper + +include $(INCLUDE_DIR)/package.mk +include $(INCLUDE_DIR)/cmake.mk + +define Package/signalwire-client-c + SUBMENU:=Telephony + SECTION:=libs + CATEGORY:=Libraries + TITLE:=SignalWire C client library + URL:=https://github.com/signalwire/signalwire-c + ABI_VERSION:=2 + DEPENDS:=+libatomic +libks +libopenssl +endef + +# Otherwise OpenWrt's CPPFLAGS are ignored +TARGET_CFLAGS += $(TARGET_CPPFLAGS) + +define Package/signalwire-client-c/install/headers + $(INSTALL_DIR) $(1)/usr/include/signalwire-client-c2/signalwire-client-c/$(2) + $(INSTALL_DATA) \ + $(PKG_INSTALL_DIR)/usr/include/signalwire-client-c2/signalwire-client-c/$(2)/*.h \ + $(1)/usr/include/signalwire-client-c2/signalwire-client-c/$(2) +endef + +define Build/InstallDev + $(foreach s,./ JSON blade signalwire transport,$(call Package/signalwire-client-c/install/headers,$(1),$(s));) + $(INSTALL_DIR) $(1)/usr/lib/pkgconfig \ + $(1)/usr/include/signalwire-client-c2/signalwire-client-c/cmake + $(INSTALL_DATA) $(PKG_INSTALL_DIR)/usr/include/signalwire-client-c2/signalwire-client-c/cmake/* \ + $(1)/usr/include/signalwire-client-c2/signalwire-client-c/cmake + $(CP) $(PKG_INSTALL_DIR)/usr/lib/libsignalwire_client2.so* $(1)/usr/lib + $(INSTALL_DATA) $(PKG_INSTALL_DIR)/usr/lib/pkgconfig/signalwire_client2.pc \ + $(1)/usr/lib/pkgconfig +endef + +define Package/signalwire-client-c/install + $(INSTALL_DIR) $(1)/usr/lib + $(CP) $(PKG_INSTALL_DIR)/usr/lib/libsignalwire_client2.so.$(ABI_VERSION)* \ + $(1)/usr/lib +endef + +$(eval $(call BuildPackage,signalwire-client-c)) diff --git a/libs/sofia-sip/Makefile b/libs/sofia-sip/Makefile new file mode 100644 index 000000000..d9501317c --- /dev/null +++ b/libs/sofia-sip/Makefile @@ -0,0 +1,90 @@ +# +# Copyright (C) 2020 Sebastian Kemper +# +# This is free software, licensed under the GNU General Public License v2. +# See /LICENSE for more information. +# + +include $(TOPDIR)/rules.mk + +PKG_NAME:=sofia-sip + +PKG_VERSION:=1.13.17 +PKG_RELEASE:=1 + +PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.gz +PKG_SOURCE_URL:=https://codeload.github.com/freeswitch/$(PKG_NAME)/tar.gz/v${PKG_VERSION}? +PKG_HASH:=daca3d961b6aa2974ad5d3be69ed011726c3e4d511b2a0d4cb6d878821a2de7a + +# sofia-sip adds a version to include path +# need to update this when the version changes +VERSION_EQUIVALENT:=1.13 + +PKG_BUILD_PARALLEL:=1 + +PKG_FIXUP:=autoreconf + +PKG_INSTALL:=1 + +PKG_LICENSE:=LGPL-2.1+ +PKG_LICENSE_FILES:=COPYING +PKG_MAINTAINER:=Sebastian Kemper + +include $(INCLUDE_DIR)/package.mk +include $(INCLUDE_DIR)/nls.mk + +define Package/sofia-sip/Default + SUBMENU:=Telephony + URL:=http://sofia-sip.sourceforge.net/index.html +endef + +define Package/sofia-sip +$(call Package/sofia-sip/Default) + SECTION:=libs + CATEGORY:=Libraries + TITLE:=Sofia-SIP open-source SIP User-Agent library + ABI_VERSION:=0 + DEPENDS:= \ + +libopenssl \ + +zlib +endef + +define Package/sofia-sip/description +Sofia-SIP is an open-source SIP User-Agent library, compliant with the +IETF RFC3261 specification (see the feature table). It can be used as a +building block for SIP client software for uses such as VoIP, IM, and +many other real-time and person-to-person communication services. The +primary target platform for Sofia-SIP is GNU/Linux. Sofia-SIP is based +on a SIP stack developed at the Nokia Research Center. Sofia-SIP is +licensed under the LGPL. +endef + +CONFIGURE_ARGS+= \ + --disable-stun \ + --without-doxygen \ + --without-glib + +define Build/InstallDev + $(INSTALL_DIR) $(1)/usr/include/sofia-sip-$(VERSION_EQUIVALENT)/sofia-{sip,resolv} \ + $(1)/usr/share/sofia-sip + $(INSTALL_DATA) \ + $(PKG_INSTALL_DIR)/usr/include/sofia-sip-$(VERSION_EQUIVALENT)/sofia-sip/*.h{,.in} \ + $(1)/usr/include/sofia-sip-$(VERSION_EQUIVALENT)/sofia-sip + $(INSTALL_DATA) \ + $(PKG_INSTALL_DIR)/usr/include/sofia-sip-$(VERSION_EQUIVALENT)/sofia-resolv/*.h \ + $(1)/usr/include/sofia-sip-$(VERSION_EQUIVALENT)/sofia-resolv + $(INSTALL_DIR) $(1)/usr/lib/pkgconfig + $(CP) $(PKG_INSTALL_DIR)/usr/lib/libsofia-sip-ua.{a,so*} $(1)/usr/lib + $(INSTALL_DATA) $(PKG_INSTALL_DIR)/usr/lib/pkgconfig/sofia-sip-ua.pc \ + $(1)/usr/lib/pkgconfig + $(INSTALL_DATA) $(PKG_INSTALL_DIR)/usr/share/sofia-sip/{msg_parser,tag_dll}.awk \ + $(1)/usr/share/sofia-sip +endef + +define Package/sofia-sip/install + $(INSTALL_DIR) $(1)/usr/lib + $(CP) $(PKG_INSTALL_DIR)/usr/lib/libsofia-sip-ua.so.$(ABI_VERSION)* \ + $(1)/usr/lib +endef + +$(eval $(call BuildPackage,sofia-sip)) diff --git a/libs/sofia-sip/patches/01-disable-libcheck.patch b/libs/sofia-sip/patches/01-disable-libcheck.patch new file mode 100644 index 000000000..3d1c04bf5 --- /dev/null +++ b/libs/sofia-sip/patches/01-disable-libcheck.patch @@ -0,0 +1,11 @@ +--- a/configure.ac ++++ b/configure.ac +@@ -247,7 +247,7 @@ SAC_OPENSSL + SAC_TPORT + + dnl Check is used for testing +-PKG_CHECK_MODULES(CHECK, check >= 0.9.4, have_check="yes", have_check="no") ++PKG_CHECK_MODULES(CHECK, we_do_not_want_check >= 0.9.4, have_check="yes", have_check="no") + AM_CONDITIONAL(HAVE_CHECK, test x"$have_check" = "xyes") + if test x"$have_check" = "xyes"; then + AC_DEFINE([HAVE_CHECK], 1, [Define to 1 if check library is available]) diff --git a/libs/spandsp/Makefile b/libs/spandsp/Makefile new file mode 100644 index 000000000..5993ba612 --- /dev/null +++ b/libs/spandsp/Makefile @@ -0,0 +1,58 @@ +# +# Copyright (C) 2014 - 2018 OpenWrt.org +# +# This is free software, licensed under the GNU General Public License v2. +# See /LICENSE for more information. +# + +include $(TOPDIR)/rules.mk + +PKG_NAME:=spandsp +PKG_VERSION:=0.0.6 +PKG_RELEASE:=4 + +PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.gz +PKG_SOURCE_URL:=https://www.soft-switch.org/downloads/spandsp +PKG_HASH:=cc053ac67e8ac4bb992f258fd94f275a7872df959f6a87763965feabfdcc9465 + +PKG_INSTALL:=1 +PKG_BUILD_PARALLEL:=1 +PKG_FIXUP:=autoreconf + +PKG_LICENSE:=LGPL-2.1 GPL-2.0 +PKG_LICENSE_FILES:=COPYING +PKG_MAINTAINER:=Jiri Slachta + +include $(INCLUDE_DIR)/package.mk + +define Package/libspandsp + SUBMENU:=Telephony + SECTION:=libs + CATEGORY:=Libraries + TITLE:=spandsp library + DEPENDS:=+libtiff +endef + +define Build/InstallDev + $(INSTALL_DIR) $(1)/usr/lib + $(CP) $(PKG_INSTALL_DIR)/usr/lib/libspandsp* $(1)/usr/lib/ + + $(INSTALL_DIR) $(1)/usr/include + $(INSTALL_DATA) $(PKG_INSTALL_DIR)/usr/include/spandsp.h $(1)/usr/include/ + + $(INSTALL_DIR) $(1)/usr/include/spandsp + $(INSTALL_DATA) $(PKG_INSTALL_DIR)/usr/include/spandsp/*.h $(1)/usr/include/spandsp/ + + $(INSTALL_DIR) $(1)/usr/include/spandsp/private + $(INSTALL_DATA) $(PKG_INSTALL_DIR)/usr/include/spandsp/private/*.h $(1)/usr/include/spandsp/private/ + + $(INSTALL_DIR) $(1)/usr/lib/pkgconfig + $(INSTALL_DATA) $(PKG_INSTALL_DIR)/usr/lib/pkgconfig/spandsp.pc $(1)/usr/lib/pkgconfig/ +endef + +define Package/libspandsp/install + $(INSTALL_DIR) $(1)/usr/lib + $(CP) $(PKG_INSTALL_DIR)/usr/lib/libspandsp*so* $(1)/usr/lib/ +endef + +$(eval $(call BuildPackage,libspandsp)) diff --git a/libs/spandsp/patches/100-compile-fixes.patch b/libs/spandsp/patches/100-compile-fixes.patch new file mode 100644 index 000000000..59b85e66f --- /dev/null +++ b/libs/spandsp/patches/100-compile-fixes.patch @@ -0,0 +1,23 @@ +--- a/src/spandsp/fast_convert.h ++++ b/src/spandsp/fast_convert.h +@@ -195,7 +195,7 @@ extern "C" + { + return (long int) (x); + } +-#elif defined(__ppc__) || defined(__powerpc__) ++#elif defined(THISISNOTDEFINEDYADDAYADDA) + static __inline__ long int lfastrint(register double x) + { + int res[2]; +--- a/configure.ac ++++ b/configure.ac +@@ -152,9 +152,7 @@ AC_ARG_ENABLE(builtin_tiff, + + AC_FUNC_ERROR_AT_LINE + AC_FUNC_VPRINTF +-AC_FUNC_MALLOC + AC_FUNC_MEMCMP +-AC_FUNC_REALLOC + AC_FUNC_SELECT_ARGTYPES + + AX_C99_FUNC_LRINT diff --git a/libs/spandsp/patches/101-disable-fixed-point.patch b/libs/spandsp/patches/101-disable-fixed-point.patch new file mode 100755 index 000000000..1aa175cb8 --- /dev/null +++ b/libs/spandsp/patches/101-disable-fixed-point.patch @@ -0,0 +1,14 @@ +--- a/configure.ac ++++ b/configure.ac +@@ -435,10 +435,7 @@ if test "$enable_fixed_point" = "yes" ; then + AC_DEFINE([SPANDSP_USE_FIXED_POINT], [1], [Enable fixed point processing, where possible, instead of floating point]) + SPANDSP_USE_FIXED_POINT="#define SPANDSP_USE_FIXED_POINT 1" + else +- AX_FIXED_POINT_MACHINE([$host], +- [AC_DEFINE([SPANDSP_USE_FIXED_POINT], [1], [Enable fixed point processing, where possible, instead of floating point]) +- SPANDSP_USE_FIXED_POINT="#define SPANDSP_USE_FIXED_POINT 1"], +- [SPANDSP_USE_FIXED_POINT="#undef SPANDSP_USE_FIXED_POINT"]) ++ SPANDSP_USE_FIXED_POINT="#undef SPANDSP_USE_FIXED_POINT"] + fi + AX_MISALIGNED_ACCESS_FAILS([$host], + [AC_DEFINE([SPANDSP_MISALIGNED_ACCESS_FAILS], [1], [Do not expect a misaligned memory access to work correctly]) diff --git a/libs/spandsp3/Makefile b/libs/spandsp3/Makefile new file mode 100644 index 000000000..f497387cf --- /dev/null +++ b/libs/spandsp3/Makefile @@ -0,0 +1,74 @@ +# +# Copyright (C) 2020 Sebastian Kemper +# +# This is free software, licensed under the GNU General Public License v2. +# See /LICENSE for more information. +# + +include $(TOPDIR)/rules.mk + +PKG_NAME:=spandsp3 + +PKG_SOURCE_PROTO:=git +PKG_SOURCE_URL:=https://github.com/freeswitch/spandsp.git +PKG_SOURCE_DATE=2023-06-16 +PKG_SOURCE_VERSION:=0d2e6ac65e0e8f53d652665a743015a88bf048d4 +PKG_RELEASE:=1 +PKG_MIRROR_HASH:=4b380960934ca4feda6d615ae8e7bb3245d87276f04d86e12c2f5939aa36608e + +PKG_INSTALL:=1 +PKG_BUILD_PARALLEL:=1 +PKG_FIXUP:=autoreconf + +PKG_LICENSE:=LGPL-2.1-or-later GPL-2.0-or-later +PKG_LICENSE_FILES:=COPYING +PKG_MAINTAINER:= \ + Jiri Slachta \ + Sebastian Kemper + +include $(INCLUDE_DIR)/package.mk + +define Package/libspandsp3 + SUBMENU:=Telephony + SECTION:=libs + CATEGORY:=Libraries + TITLE:=spandsp3 library + DEPENDS:=+libjpeg-turbo +libtiff + URL:=https://github.com/freeswitch/spandsp + ABI_VERSION:=3 +endef + +# Use fixed point math when soft float support is enabled for target devices. +ifeq ($(CONFIG_SOFT_FLOAT),y) +CONFIGURE_ARGS+= \ + --enable-fixed-point +endif + +define Build/InstallDev + $(INSTALL_DIR) \ + $(1)/usr/lib/spandsp3/{include/spandsp/private,lib} + + $(CP) $(PKG_INSTALL_DIR)/usr/lib/libspandsp* \ + $(1)/usr/lib/spandsp3/lib + + $(INSTALL_DATA) $(PKG_INSTALL_DIR)/usr/include/spandsp.h \ + $(1)/usr/lib/spandsp3/include + + $(INSTALL_DATA) $(PKG_INSTALL_DIR)/usr/include/spandsp/*.h \ + $(1)/usr/lib/spandsp3/include/spandsp + + $(INSTALL_DATA) $(PKG_INSTALL_DIR)/usr/include/spandsp/private/*.h \ + $(1)/usr/lib/spandsp3/include/spandsp/private + + $(INSTALL_DIR) $(1)/usr/lib/pkgconfig + $(INSTALL_DATA) $(PKG_INSTALL_DIR)/usr/lib/pkgconfig/spandsp.pc \ + $(1)/usr/lib/pkgconfig/spandsp3.pc +endef + +define Package/libspandsp3/install + $(INSTALL_DIR) $(1)/usr/lib + $(CP) $(PKG_INSTALL_DIR)/usr/lib/libspandsp.so.$(ABI_VERSION)* \ + $(1)/usr/lib +endef + +$(eval $(call BuildPackage,libspandsp3)) diff --git a/libs/spandsp3/patches/01-spandsp3-pkg-config.patch b/libs/spandsp3/patches/01-spandsp3-pkg-config.patch new file mode 100644 index 000000000..c7ae5a3b0 --- /dev/null +++ b/libs/spandsp3/patches/01-spandsp3-pkg-config.patch @@ -0,0 +1,18 @@ +--- a/spandsp.pc.in ++++ b/spandsp.pc.in +@@ -1,12 +1,12 @@ + prefix=@prefix@ + exec_prefix=@exec_prefix@ +-libdir=@libdir@ +-includedir=@includedir@ ++libdir=${exec_prefix}/lib/spandsp3/lib ++includedir=${prefix}/lib/spandsp3/include + + Name: spandsp + Description: A DSP library for telephony. + Requires: + Version: @VERSION@ +-Libs: -L${libdir} -lspandsp ++Libs: -L${libdir} -l:libspandsp.so.3 + Libs.private: -ltiff -lm + Cflags: -I${includedir} diff --git a/libs/spandsp3/patches/02-do-not-check-for-libxml2.patch b/libs/spandsp3/patches/02-do-not-check-for-libxml2.patch new file mode 100644 index 000000000..25aefaef3 --- /dev/null +++ b/libs/spandsp3/patches/02-do-not-check-for-libxml2.patch @@ -0,0 +1,20 @@ +--- a/configure.ac ++++ b/configure.ac +@@ -231,6 +231,9 @@ then + AC_CHECK_HEADERS([X11/X.h]) + fi + ++# Note: the libxml2 checks below introduce host include paths into the ++# build, so we turn them off. ++if test -n "$enable_tests" ; then # OpenWrt doesn't build the tests + # Determine XML2 include path + AC_MSG_CHECKING(for libxml/xmlmemory.h) + +@@ -259,6 +262,7 @@ fi + AC_CHECK_HEADERS([libxml/xmlmemory.h]) + AC_CHECK_HEADERS([libxml/parser.h]) + AC_CHECK_HEADERS([libxml/xinclude.h]) ++fi # OpenWrt doesn't build the tests + + AC_LANG([C++]) + AC_CHECK_HEADERS([FL/Fl.H]) diff --git a/net/asterisk-chan-dongle/Makefile b/net/asterisk-chan-dongle/Makefile new file mode 100644 index 000000000..dee791b6b --- /dev/null +++ b/net/asterisk-chan-dongle/Makefile @@ -0,0 +1,97 @@ +# +# Copyright (C) 2017 - 2018 OpenWrt.org +# +# This is free software, licensed under the GNU General Public License v2. +# See /LICENSE for more information. +# + +include $(TOPDIR)/rules.mk + +PKG_NAME:=asterisk-chan-dongle + +PKG_SOURCE_PROTO:=git +PKG_SOURCE_URL:=https://github.com/wdoekes/asterisk-chan-dongle.git +PKG_SOURCE_VERSION:=503dba87d726854b74b49e70679e64e6e86d5812 +PKG_SOURCE_DATE=2022-11-04 +PKG_RELEASE:=1 +PKG_MIRROR_HASH:=3cd8ea6e641a7623ba06000832ec5079e08f6f5eb234a3270710856fa0a37609 + +PKG_FIXUP:=autoreconf + +PKG_LICENSE:=GPL-2.0 +PKG_LICENSE_FILES:=COPYRIGHT.txt LICENSE.txt +PKG_MAINTAINER:=Jiri Slachta + +MODULES_DIR:=/usr/lib/asterisk/modules + +include $(INCLUDE_DIR)/package.mk +# asterisk-chan-dongle needs iconv +include $(INCLUDE_DIR)/nls.mk + +define Package/asterisk-chan-dongle + SUBMENU:=Telephony + SECTION:=net + CATEGORY:=Network + URL:=https://github.com/wdoekes/asterisk-chan-dongle + DEPENDS:=asterisk $(ICONV_DEPENDS) +libsqlite3 + TITLE:=Huawei UMTS 3G dongle support +endef + +define Package/asterisk-chan-dongle/description + Asterisk channel driver for Huawei UMTS 3G dongle. +endef + +CONFIGURE_ARGS+= \ + --with-asterisk=$(STAGING_DIR)/usr/include \ + --with-astversion=18 + +ifeq ($(CONFIG_BUILD_NLS),y) +CONFIGURE_ARGS+=--with-iconv=$(ICONV_PREFIX)/include +else +CONFIGURE_ARGS+=--with-iconv=$(TOOLCHAIN_DIR)/include +endif + +MAKE_FLAGS+=LD="$(TARGET_CC)" + +CONFIGURE_VARS += \ + DESTDIR="$(MODULES_DIR)" \ + ac_cv_type_size_t=yes \ + ac_cv_type_ssize_t=yes + +define Package/asterisk-chan-dongle/conffiles +/etc/asterisk/dongle.conf +endef + +define Package/asterisk-chan-dongle/install + $(INSTALL_DIR) $(1)/etc/asterisk + $(INSTALL_DATA) $(PKG_BUILD_DIR)/etc/dongle.conf $(1)/etc/asterisk + $(INSTALL_DIR) $(1)$(MODULES_DIR) + $(INSTALL_BIN) $(PKG_BUILD_DIR)/chan_dongle.so $(1)$(MODULES_DIR) +endef + +define Package/asterisk-chan-dongle/postinst +#!/bin/sh +if [ -z "$${IPKG_INSTROOT}" ]; then + echo + echo "o-------------------------------------------------------------------o" + echo "| asterisk-chan-dongle note |" + echo "o-------------------------------------------------------------------o" + echo "| Adding the \"asterisk\" user to the \"dialout\" group might be |" + echo "| required for asterisk to be able to access the dongle. |" + echo "o-------------------------------------------------------------=^_^=-o" + echo +fi +exit 0 +endef + +define Build/Prepare + $(call Build/Prepare/Default) +ifeq ($(QUILT),) +ifeq ($(CONFIG_BUILD_NLS),y) + $(SED) 's/\[iconv\], \[c iconv\]/[libiconv], [iconv]/' \ + "$(PKG_BUILD_DIR)/configure.ac" +endif +endif +endef + +$(eval $(call BuildPackage,asterisk-chan-dongle)) diff --git a/net/asterisk-chan-dongle/patches/300-use-openwrt-flags.patch b/net/asterisk-chan-dongle/patches/300-use-openwrt-flags.patch new file mode 100644 index 000000000..981ab9904 --- /dev/null +++ b/net/asterisk-chan-dongle/patches/300-use-openwrt-flags.patch @@ -0,0 +1,11 @@ +--- a/configure.ac ++++ b/configure.ac +@@ -247,8 +247,6 @@ dnl Apply options to defines + if test "x$enable_debug" = "xyes" ; then + CFLAGS="$CFLAGS -O0 -g3" + AC_DEFINE([__DEBUG__], [1], [Build with debugging]) +-else +- CFLAGS="$CFLAGS -O6" + fi + + dnl Asterisk header files use lots of old style declarations, ignore those. diff --git a/net/asterisk-chan-dongle/patches/400-time_t.patch b/net/asterisk-chan-dongle/patches/400-time_t.patch new file mode 100644 index 000000000..0b76ad347 --- /dev/null +++ b/net/asterisk-chan-dongle/patches/400-time_t.patch @@ -0,0 +1,16 @@ +--- a/configure.ac ++++ b/configure.ac +@@ -165,11 +165,13 @@ dnl AC_CHECK_TYPE(uint64_t, unsigned lon + + AC_CHECK_SIZEOF(int) + AC_CHECK_SIZEOF(long int) ++AC_CHECK_SIZEOF(long long int) + AC_CHECK_SIZEOF(time_t) + case "$ac_cv_sizeof_time_t" in + ''|0) AC_MSG_ERROR([Could not find time_t type]);; + $ac_cv_sizeof_int) AC_DEFINE([PRI_time_t], ["d"], [printf format for time_t]);; + $ac_cv_sizeof_long_int) AC_DEFINE([PRI_time_t], ["ld"], [printf format for time_t]);; ++$ac_cv_sizeof_long_long_int) AC_DEFINE([PRI_time_t], ["lld"], [printf format for time_t]);; + *) AC_MSG_ERROR([Could not find match size of time_t to printf format]) + esac + diff --git a/net/asterisk-chan-lantiq/Makefile b/net/asterisk-chan-lantiq/Makefile new file mode 100644 index 000000000..b58ada225 --- /dev/null +++ b/net/asterisk-chan-lantiq/Makefile @@ -0,0 +1,69 @@ +# +# Copyright (C) 2018 OpenWrt.org +# +# This is free software, licensed under the GNU General Public License v2. +# See /LICENSE for more information. +# + +include $(TOPDIR)/rules.mk + +PKG_NAME:=asterisk-chan-lantiq +PKG_RELEASE:=1 + +PKG_SOURCE_URL:=https://github.com/kochstefan/asterisk_channel_lantiq.git +PKG_SOURCE_VERSION:=2f029ec8778420538c8151c6aceba0f7b44b07c9 +PKG_SOURCE_DATE:=2021-09-11 +PKG_MIRROR_HASH:=9691624fb3465fb6af4f5d391dc4c0fc99dbb095e29cbef0574cf5838fb27053 +PKG_SOURCE_PROTO:=git + +PKG_LICENSE:=GPL-2.0 + +PKG_MAINTAINER:=Jiri Slachta + +PKG_FLAGS:=nonshared + +include $(INCLUDE_DIR)/package.mk + +define Package/$(PKG_NAME) + SUBMENU:=Telephony Lantiq + SECTION:=net + CATEGORY:=Network + TITLE:=Lantiq channel driver + URL:=https://github.com/kochstefan/asterisk_channel_lantiq + DEPENDS:=+asterisk +kmod-ltq-vmmc + USERID:=asterisk=385::vmmc=386 +endef + +define Package/$(PKG_NAME)/description +An implementation of a Lantiq TAPI channel driver for Asterisk. +endef + +define Package/$(PKG_NAME)/conffiles +/etc/asterisk/lantiq.conf +endef + +define Build/Compile + cd $(PKG_BUILD_DIR)/src/channels && \ + $(TARGET_CC) -o chan_lantiq.o -c chan_lantiq.c -MD -MT chan_lantiq.o \ + -MF .chan_lantiq.o.d -MP -pthread \ + $(TARGET_CFLAGS) -DAST_MODULE_SELF_SYM=__internal_chan_lantiq_self \ + $(TARGET_CPPFLAGS) \ + -Wall -Wstrict-prototypes -Wmissing-prototypes \ + -Wmissing-declarations $(FPIC) -DAST_MODULE=\"chan_lantiq\" && \ + $(TARGET_CC) -o chan_lantiq.so -pthread $(TARGET_LDFLAGS) -shared \ + -Wl,--version-script,chan_lantiq.exports,--warn-common \ + chan_lantiq.o +endef + +define Package/$(PKG_NAME)/install + $(INSTALL_DIR) $(1)/etc/asterisk + $(INSTALL_DATA) \ + $(PKG_BUILD_DIR)/src/configs/samples/lantiq.conf.sample \ + $(1)/etc/asterisk/lantiq.conf + $(INSTALL_DIR) $(1)/usr/lib/asterisk/modules + $(INSTALL_BIN) \ + $(PKG_BUILD_DIR)/src/channels/chan_lantiq.so \ + $(1)/usr/lib/asterisk/modules +endef + +$(eval $(call BuildPackage,$(PKG_NAME))) diff --git a/net/asterisk-chan-sccp/Makefile b/net/asterisk-chan-sccp/Makefile new file mode 100644 index 000000000..8d2185178 --- /dev/null +++ b/net/asterisk-chan-sccp/Makefile @@ -0,0 +1,75 @@ +# +# Copyright (C) 2016 OpenWrt.org +# Copyright (C) 2016 Cesnet, z.s.p.o. +# +# This is free software, licensed under the GNU General Public License v2. +# See /LICENSE for more information. +# + +include $(TOPDIR)/rules.mk + +PKG_NAME:=asterisk-chan-sccp +PKG_RELEASE:=2 + +# Updated to v4.3.3 release +PKG_SOURCE_URL:=https://github.com/chan-sccp/chan-sccp.git +PKG_SOURCE_VERSION:=968caa458920965c5dd15c31bcd50d21a891ab20 +PKG_SOURCE_DATE:=2020-12-19 +PKG_MIRROR_HASH:=705cd1cd30fc5db3143f87077e2c6511aaa463e1e160ad161a23ccd978fde24e +PKG_SOURCE_PROTO:=git + +PKG_FIXUP:=autoreconf + +PKG_LICENSE:=GPL-1.0 +PKG_LICENSE_FILES:=COPYING LICENSE +PKG_MAINTAINER:=Jiri Slachta + +PKG_INSTALL:=1 + +# need iconv.m4, otherwise error during autoreconf +PKG_BUILD_DEPENDS:=gettext-full + +include $(INCLUDE_DIR)/package.mk +# chan-sccp needs iconv +include $(INCLUDE_DIR)/nls.mk + +define Package/asterisk-chan-sccp + SUBMENU:=Telephony + SECTION:=net + CATEGORY:=Network + TITLE:=SCCP channel support + URL:=https://github.com/chan-sccp/chan-sccp + DEPENDS:=asterisk $(ICONV_DEPENDS) +libltdl \ + +asterisk-bridge-holding \ + +asterisk-bridge-native-rtp \ + +asterisk-bridge-simple \ + +asterisk-bridge-softmix \ + +asterisk-res-stasis-device-state + CONFLICTS:=asterisk-chan-skinny +endef + +define Package/asterisk-chan-sccp/description +Replacement for the SCCP channel driver (chan_skinny) in Asterisk. +Extended features include shared lines, presence / BLF, customizable +feature buttons and custom device state. +endef + +CONFIGURE_ARGS += \ + --disable-debug \ + --enable-advanced-functions \ + --enable-conference \ + --enable-video \ + --with-asterisk=$(STAGING_DIR)/usr + +define Package/asterisk-chan-sccp/conffiles +/etc/asterisk/sccp.conf +endef + +define Package/asterisk-chan-sccp/install + $(INSTALL_DIR) $(1)/etc/asterisk + $(INSTALL_DATA) $(PKG_INSTALL_DIR)/etc/asterisk/sccp.conf $(1)/etc/asterisk + $(INSTALL_DIR) $(1)/usr/lib/asterisk/modules + $(INSTALL_BIN) $(PKG_INSTALL_DIR)/usr/lib/asterisk/modules/chan_sccp.so $(1)/usr/lib/asterisk/modules/ +endef + +$(eval $(call BuildPackage,asterisk-chan-sccp)) diff --git a/net/asterisk-chan-sccp/patches/01-prevent-extra-optimization.patch b/net/asterisk-chan-sccp/patches/01-prevent-extra-optimization.patch new file mode 100644 index 000000000..6d4b8efa6 --- /dev/null +++ b/net/asterisk-chan-sccp/patches/01-prevent-extra-optimization.patch @@ -0,0 +1,20 @@ +--- a/autoconf/extra.m4 ++++ b/autoconf/extra.m4 +@@ -516,17 +516,6 @@ AC_DEFUN([CS_ENABLE_OPTIMIZATION], [ + ], SUPPORTED_CFLAGS) + ]) + AC_SUBST([strip_binaries]) +- ], [ +- CFLAGS_saved="`echo ${CFLAGS_saved} |sed -e 's/\-O[0-9]\ \?//g' -e 's/[^|\ ]\-g[$|\ ]//g'`" +- optimize_flag="-O0" +- case "${CC}" in +- *gcc*) +- AX_CHECK_COMPILE_FLAG(-Og, [ +- optimize_flag="-Og" +- ]) +- ;; +- esac +- CFLAGS_saved="${CFLAGS_saved} ${optimize_flag} " + ]) + + AS_IF([test "X${enable_debug}" == "Xyes"], [ diff --git a/net/asterisk-chan-sccp/patches/02-autoconf-2.70.patch b/net/asterisk-chan-sccp/patches/02-autoconf-2.70.patch new file mode 100644 index 000000000..40ed199c8 --- /dev/null +++ b/net/asterisk-chan-sccp/patches/02-autoconf-2.70.patch @@ -0,0 +1,11 @@ +--- a/autoconf/acinclude.m4 ++++ b/autoconf/acinclude.m4 +@@ -497,7 +497,7 @@ AC_DEFUN([CS_GET_VERSION], [ + SCCP_REVISION="unknown" + + CURRENT=`pwd` +- BASE=`dirname $ac_dir` ++ BASE=`dirname $ac_aux_dir` + cd $BASE >/dev/null + . ./tools/versioncheck silent + cd $CURRENT >/dev/null diff --git a/net/asterisk-chan-sccp/patches/100-reproducible-builds.patch b/net/asterisk-chan-sccp/patches/100-reproducible-builds.patch new file mode 100644 index 000000000..db1cac94c --- /dev/null +++ b/net/asterisk-chan-sccp/patches/100-reproducible-builds.patch @@ -0,0 +1,11 @@ +--- a/src/chan_sccp.c ++++ b/src/chan_sccp.c +@@ -198,7 +198,7 @@ boolean_t sccp_postPBX_load(void) + #else + snprintf(SCCP_REVISIONSTR, sizeof(SCCP_REVISIONSTR), "%s", SCCP_REVISION); + #endif +- snprintf(SCCP_VERSIONSTR, sizeof(SCCP_VERSIONSTR), "Skinny Client Control Protocol (SCCP). Release: %s %s - %s (built by '%s' on '%s')\n", SCCP_VERSION, SCCP_BRANCH, SCCP_REVISIONSTR, BUILD_USER, BUILD_DATE); ++ snprintf(SCCP_VERSIONSTR, sizeof(SCCP_VERSIONSTR), "Skinny Client Control Protocol (SCCP). Release: %s %s - %s\n", SCCP_VERSION, SCCP_BRANCH, SCCP_REVISIONSTR); + + GLOB(module_running) = TRUE; + pbx_rwlock_unlock(&GLOB(lock)); diff --git a/net/asterisk-g72x/Makefile b/net/asterisk-g72x/Makefile new file mode 100644 index 000000000..e97917236 --- /dev/null +++ b/net/asterisk-g72x/Makefile @@ -0,0 +1,53 @@ +# +# Copyright (C) 2016 OpenWrt.org +# +# This is free software, licensed under the GNU General Public License v2. +# See /LICENSE for more information. +# + +include $(TOPDIR)/rules.mk + +PKG_NAME:=asterisk-g72x +PKG_VERSION:=1.4.3 +PKG_RELEASE:=1 + +PKG_SOURCE:=asterisk-g72x-$(PKG_VERSION).tar.bz2 +PKG_SOURCE_URL:=http://asterisk.hosting.lv/src/ +PKG_HASH:=ffea55374c2134415569b876a68d9a12ce376146a22fad3963c8edc281052adf + +PKG_FIXUP:=autoreconf +PKG_INSTALL:=1 + +PKG_LICENSE:=GPL-3.0 +PKG_LICENSE_FILES:=README.md +PKG_MAINTAINER:=Alex Samorukov + +PKG_BUILD_DIR:=$(BUILD_DIR)/$(PKG_NAME)-$(PKG_VERSION) + +include $(INCLUDE_DIR)/package.mk + +define Package/asterisk-codec-g729 + SUBMENU:=Telephony + SECTION:=net + CATEGORY:=Network + TITLE:=G.729 codec support + URL:=http://asterisk.hosting.lv + DEPENDS:=asterisk +bcg729 +endef + +define Package/asterisk-codec-g729/description + Asterisk G.729 codec based on bcg729 implementation. +endef + +CONFIGURE_ARGS+= \ + --with-bcg729 \ + --enable-shared \ + --with-asterisk-includes=$(STAGING_DIR)/usr/include + +define Package/asterisk-codec-g729/install + $(INSTALL_DIR) $(1)/usr/lib/asterisk/modules + $(INSTALL_BIN) $(PKG_INSTALL_DIR)/usr/lib/asterisk/modules/codec_g729.so \ + $(1)/usr/lib/asterisk/modules/ +endef + +$(eval $(call BuildPackage,asterisk-codec-g729)) diff --git a/net/asterisk-opus/Makefile b/net/asterisk-opus/Makefile new file mode 100644 index 000000000..fde843c24 --- /dev/null +++ b/net/asterisk-opus/Makefile @@ -0,0 +1,81 @@ +# +# Copyright (C) 2018 OpenWrt.org +# +# This is free software, licensed under the GNU General Public License v2. +# See /LICENSE for more information. +# + +include $(TOPDIR)/rules.mk + +PKG_NAME:=asterisk-opus +PKG_RELEASE:=2 + +PKG_SOURCE_URL:=https://github.com/traud/asterisk-opus.git +PKG_SOURCE_DATE:=2021-11-01 +PKG_SOURCE_VERSION:=20522fbcd3fdf6f0adb20602d096d14cd69055e8 +PKG_MIRROR_HASH:=b69ff63f18a21168d94da97da453ebac30aa1de05d1fbef72723b6231c902e2f +PKG_SOURCE_PROTO:=git + +PKG_LICENSE:=GPL-2.0 +PKG_LICENSE_FILES:=LICENSE +PKG_MAINTAINER:=Jiri Slachta + +include $(INCLUDE_DIR)/package.mk + +TARGET_CFLAGS += \ + $(FPIC) + +define Package/asterisk-opus/Default + SUBMENU:=Telephony + SECTION:=net + CATEGORY:=Network + URL:=https://github.com/traud/asterisk-opus + DEPENDS:=asterisk +libopus +endef + +define Package/asterisk-codec-opus +$(call Package/asterisk-opus/Default) + TITLE:=Opus codec support +endef + +define Package/asterisk-codec-opus/description + Opus is the default audio codec in WebRTC. WebRTC is available in + Asterisk via SIP over WebSockets (WSS). Nevertheless, Opus can be used + for other transports (UDP, TCP, TLS) as well. Opus supersedes previous + codecs like CELT and SiLK. Furthermore, in favor of Opus, other + open-source audio codecs are no longer developed, like Speex, iSAC, + iLBC, and Siren. If you use your Asterisk as a back-to-back user agent + (B2BUA) and you transcode between various audio codecs, one should + enable Opus for future compatibility. + + Opus is not only supported for pass-through but can be transcoded as + well. +endef + +define Package/asterisk-codec-opus/install + $(INSTALL_DIR) $(1)/usr/lib/asterisk/modules + $(INSTALL_BIN) $(PKG_BUILD_DIR)/codecs/codec_opus_open_source.so \ + $(1)/usr/lib/asterisk/modules +endef + +define Package/asterisk-format-ogg-opus +$(call Package/asterisk-opus/Default) + TITLE:=OGG/Opus audio support + DEPENDS+=+libopusfile +libopusenc +endef + +define Package/asterisk-format-ogg-opus/description + Reading and writing audio files in the OGG/Opus format. +endef + +define Package/asterisk-format-ogg-opus/install + $(INSTALL_DIR) $(1)/usr/lib/asterisk/modules + $(INSTALL_BIN) $(PKG_BUILD_DIR)/formats/format_ogg_opus_open_source.so \ + $(1)/usr/lib/asterisk/modules +endef + +define Build/Configure +endef + +$(eval $(call BuildPackage,asterisk-codec-opus)) +$(eval $(call BuildPackage,asterisk-format-ogg-opus)) diff --git a/net/asterisk-opus/patches/01-Makefile.patch b/net/asterisk-opus/patches/01-Makefile.patch new file mode 100644 index 000000000..e74f0a9b5 --- /dev/null +++ b/net/asterisk-opus/patches/01-Makefile.patch @@ -0,0 +1,35 @@ +--- a/Makefile ++++ b/Makefile +@@ -5,18 +5,18 @@ libdir=$(exec_prefix)/lib + # build with `make OPUSENC=0` to disable rewrite support using libopusenc + OPUSENC?=1 + +-CFLAGS=-pthread -D_FORTIFY_SOURCE=2 -fPIC +-DEBUG=-g3 +-OPTIMIZE=-O3 ++CFLAGS+=-Wall -pthread ++DEBUG= ++OPTIMIZE= + CPPFLAGS= + DEFS= + INSTALL=/usr/bin/install -c +-LDFLAGS=-pthread -Wl,--warn-common ++LDFLAGS+=-pthread -Wl,--warn-common + LIBS= + SHELL=/bin/sh + + ASTMODDIR=$(libdir)/asterisk/modules +-MODULES=codec_opus_open_source format_ogg_opus_open_source format_vp8 res_format_attr_opus ++MODULES=codec_opus_open_source format_ogg_opus_open_source + + .SUFFIXES: .c .so + +@@ -38,7 +38,7 @@ codec_opus_open_source: DEFS+=-DAST_MODU + -DAST_MODULE_SELF_SYM=__internal_codec_opus_open_source_self + codec_opus_open_source: codecs/codec_opus_open_source.so + +-format_ogg_opus_open_source: CPATH+=-I/usr/include/opus ++format_ogg_opus_open_source: CPATH+=-I$(STAGING_DIR)/usr/include/opus + format_ogg_opus_open_source: LIBS+=-lopus -lopusfile + format_ogg_opus_open_source: DEFS+=-DAST_MODULE=\"format_ogg_opus_open_source\" \ + -DAST_MODULE_SELF_SYM=__internal_format_ogg_opus_open_source_self diff --git a/net/asterisk/Makefile b/net/asterisk/Makefile new file mode 100644 index 000000000..e5075caaa --- /dev/null +++ b/net/asterisk/Makefile @@ -0,0 +1,1085 @@ +# +# Copyright (C) 2017 - 2018 Jiri Slachta +# +# This is free software, licensed under the GNU General Public License v2. +# See /LICENSE for more information. +# + +include $(TOPDIR)/rules.mk + +PKG_NAME:=asterisk +PKG_VERSION:=20.5.2 +PKG_RELEASE:=1 +PKG_CPE_ID:=cpe:/a:digium:asterisk + +PKG_SOURCE:=asterisk-$(PKG_VERSION).tar.gz +PKG_SOURCE_URL:=https://downloads.asterisk.org/pub/telephony/asterisk/releases +PKG_HASH:=8f68e1789dfb8aa04b0eba87ea1d599a62e088ddd20926afc997f36b455e1859 + +PKG_BUILD_DEPENDS:=libxml2/host + +PKG_LICENSE:=GPL-2.0 +PKG_LICENSE_FILES:=COPYING LICENSE +PKG_MAINTAINER:=Jiri Slachta + +MENUSELECT_CATEGORIES:= \ + MENUSELECT_ADDONS \ + MENUSELECT_APPS \ + MENUSELECT_BRIDGES \ + MENUSELECT_CDR \ + MENUSELECT_CEL \ + MENUSELECT_CHANNELS \ + MENUSELECT_CODECS \ + MENUSELECT_FORMATS \ + MENUSELECT_FUNCS \ + MENUSELECT_PBX \ + MENUSELECT_RES \ + MENUSELECT_UTILS \ + MENUSELECT_AGIS + +MODULES_AVAILABLE:= \ + app-adsiprog \ + app-agent-pool \ + app-alarmreceiver \ + app-amd \ + app-attended-transfer \ + app-audiosocket \ + app-authenticate \ + app-blind-transfer \ + app-bridgeaddchan \ + app-bridgewait \ + app-broadcast \ + app-celgenuserevent \ + app-chanisavail \ + app-channelredirect \ + app-chanspy \ + app-confbridge \ + app-controlplayback \ + app-dictate \ + app-directed-pickup \ + app-directory \ + app-disa \ + app-dtmfstore \ + app-dumpchan \ + app-exec \ + app-externalivr \ + app-festival \ + app-flash \ + app-followme \ + app-getcpeid \ + app-if \ + app-ivrdemo \ + app-mf \ + app-milliwatt \ + app-minivm \ + app-mixmonitor \ + app-morsecode \ + app-mp3 \ + app-originate \ + app-page \ + app-playtones \ + app-privacy \ + app-queue \ + app-read \ + app-readexten \ + app-record \ + app-reload \ + app-saycounted \ + app-sayunixtime \ + app-senddtmf \ + app-sendtext \ + app-sf \ + app-signal \ + app-skel \ + app-sms \ + app-softhangup \ + app-speech \ + app-stack \ + app-stasis \ + app-statsd \ + app-stream-echo \ + app-system \ + app-talkdetect \ + app-test \ + app-transfer \ + app-userevent \ + app-verbose \ + app-waitforcond \ + app-voicemail \ + app-voicemail-imap \ + app-voicemail-odbc \ + app-waitforring \ + app-waitforsilence \ + app-waituntil \ + app-while \ + app-zapateller \ + bridge-builtin-features \ + bridge-builtin-interval-features \ + bridge-holding \ + bridge-native-rtp \ + bridge-simple \ + bridge-softmix \ + cdr \ + cdr-csv \ + cdr-sqlite3 \ + cel-custom \ + cel-manager \ + cel-sqlite3-custom \ + chan-alsa \ + chan-audiosocket \ + chan-bridge-media \ + chan-console \ + chan-dahdi \ + chan-iax2 \ + chan-mgcp \ + chan-mobile \ + chan-motif \ + chan-ooh323 \ + chan-rtp \ + chan-sip \ + chan-skinny \ + chan-unistim \ + codec-a-mu \ + codec-adpcm \ + codec-alaw \ + codec-dahdi \ + codec-g722 \ + codec-g726 \ + codec-gsm \ + codec-ilbc \ + codec-lpc10 \ + codec-resample \ + codec-speex \ + codec-ulaw \ + curl \ + format-g719 \ + format-g723 \ + format-g726 \ + format-g729 \ + format-gsm \ + format-h263 \ + format-h264 \ + format-ilbc \ + format-mp3 \ + format-ogg-speex \ + format-ogg-vorbis \ + format-pcm \ + format-siren14 \ + format-siren7 \ + format-sln \ + format-vox \ + format-wav \ + format-wav-gsm \ + func-aes \ + func-base64 \ + func-blacklist \ + func-callcompletion \ + func-channel \ + func-config \ + func-cut \ + func-db \ + func-devstate \ + func-dialgroup \ + func-dialplan \ + func-enum \ + func-env \ + func-evalexten \ + func-export \ + func-extstate \ + func-frame-drop \ + func-frame-trace \ + func-global \ + func-groupcount \ + func-hangupcause \ + func-holdintercept \ + func-iconv \ + func-jitterbuffer \ + func-json \ + func-lock \ + func-math \ + func-md5 \ + func-module \ + func-periodic-hook \ + func-pitchshift \ + func-presencestate \ + func-rand \ + func-realtime \ + func-sayfiles \ + func-scramble \ + func-sha1 \ + func-shell \ + func-sorcery \ + func-speex \ + func-sprintf \ + func-srv \ + func-sysinfo \ + func-talkdetect \ + func-uri \ + func-version \ + func-vmcount \ + func-volume \ + odbc \ + pbx-ael \ + pbx-dundi \ + pbx-loopback \ + pbx-lua \ + pbx-realtime \ + pbx-spool \ + pgsql \ + pjsip \ + res-adsi \ + res-aeap \ + res-ael-share \ + res-agi \ + res-ari \ + res-ari-applications \ + res-ari-asterisk \ + res-ari-bridges \ + res-ari-channels \ + res-ari-device-states \ + res-ari-endpoints \ + res-ari-events \ + res-ari-mailboxes \ + res-ari-model \ + res-ari-playbacks \ + res-ari-recordings \ + res-ari-sounds \ + res-audiosocket \ + res-calendar \ + res-calendar-caldav \ + res-calendar-ews \ + res-calendar-exchange \ + res-calendar-icalendar \ + res-chan-stats \ + res-clialiases \ + res-cliexec \ + res-clioriginate \ + res-config-ldap \ + res-config-mysql \ + res-config-sqlite3 \ + res-convert \ + res-endpoint-stats \ + res-hep \ + res-hep-pjsip \ + res-hep-rtcp \ + res-fax-spandsp \ + res-fax \ + res-format-attr-celt \ + res-format-attr-g729 \ + res-format-attr-h263 \ + res-format-attr-h264 \ + res-format-attr-ilbc \ + res-format-attr-opus \ + res-format-attr-silk \ + res-format-attr-siren14 \ + res-format-attr-siren7 \ + res-format-attr-vp8 \ + res-geolocation \ + res-http-media-cache \ + res-http-websocket \ + res-limit \ + res-manager-devicestate \ + res-manager-presencestate \ + res-monitor \ + res-musiconhold \ + res-mutestream \ + res-mwi-devstate \ + res-mwi-external \ + res-mwi-external-ami \ + res-parking \ + res-phoneprov \ + res-pjsip-aoc \ + res-pjsip-geolocation \ + res-pjsip-phoneprov \ + res-pjsip-rfc3329 \ + res-pjsip-stir-shaken \ + res-pjproject \ + res-pktccops \ + res-prometheus \ + res-realtime \ + res-remb-modifier \ + res-resolver-unbound \ + res-rtp-asterisk \ + res-rtp-multicast \ + res-security-log \ + res-smdi \ + res-snmp \ + res-sorcery \ + res-sorcery-memory-cache \ + res-speech \ + res-speech-aeap \ + res-srtp \ + res-stasis \ + res-stasis-answer \ + res-stasis-device-state \ + res-stasis-mailbox \ + res-stasis-playback \ + res-stasis-recording \ + res-stasis-snoop \ + res-statsd \ + res-stir-shaken \ + res-stun-monitor \ + res-timing-dahdi \ + res-timing-pthread \ + res-tonedetect \ + res-xmpp + +UTILS_AVAILABLE:= \ + aelparse \ + astcanary \ + astdb2sqlite3 \ + astdb2bdb \ + check_expr \ + check_expr2 \ + smsq \ + stereorize \ + streamplayer + +AST_ENABLE:= + +PKG_CONFIG_DEPENDS:= \ + $(patsubst %,CONFIG_PACKAGE_$(PKG_NAME)-%,$(MODULES_AVAILABLE)) \ + $(patsubst %,CONFIG_PACKAGE_$(PKG_NAME)-util-%,$(subst _,-,$(UTILS_AVAILABLE))) \ + CONFIG_ASTERISK_LIBXSLT_SUPPORT \ + CONFIG_ASTERISK_LOW_MEMORY + +include $(INCLUDE_DIR)/package.mk +include $(INCLUDE_DIR)/host-build.mk +# Needed for res-config-mysql and func-iconv to find iconv +include $(INCLUDE_DIR)/nls.mk + +define Package/$(PKG_NAME)/install/module + $(INSTALL_DIR) $(1)/usr/lib/asterisk/modules + $(INSTALL_BIN) $(PKG_INSTALL_DIR)/usr/lib/asterisk/modules/*$(2).so* $(1)/usr/lib/asterisk/modules/ +endef + +define Package/$(PKG_NAME)/install/conffile + $(INSTALL_DIR) $(1)/etc/asterisk + $(INSTALL_DATA) $(PKG_INSTALL_DIR)/etc/asterisk/$(2) $(1)/etc/asterisk/ +endef + +define Package/$(PKG_NAME)/install/lib + $(INSTALL_DIR) $(1)/usr/lib + $(CP) $(PKG_INSTALL_DIR)/usr/lib/$(2).so* $(1)/usr/lib/ +endef + +define Package/$(PKG_NAME)/install/sbin + $(INSTALL_DIR) $(1)/usr/sbin + $(INSTALL_BIN) $(PKG_INSTALL_DIR)/usr/sbin/$(2) $(1)/usr/sbin/ +endef + +define Package/$(PKG_NAME)/install/sounds + $(INSTALL_DIR) $(1)/usr/share/asterisk/sounds/ + $(CP) $(PKG_INSTALL_DIR)/usr/share/asterisk/sounds/en/$(2) $(1)/usr/share/asterisk/sounds/ +endef + +define Package/$(PKG_NAME)/install/util-conffile + $(INSTALL_DIR) $(1)/etc + $(INSTALL_DATA) $(PKG_INSTALL_DIR)/etc/asterisk/$(2) $(1)/etc +endef + +define Package/$(PKG_NAME)/config + menu "Advanced configuration" + depends on PACKAGE_asterisk + + config ASTERISK_LIBXSLT_SUPPORT + bool "Link Asterisk against libxslt" + default y if x86_64 + help + Build Asterisk with libxslt support. This is required for + res-geolocation. + + config ASTERISK_LOW_MEMORY + bool "Optimize Asterisk for low memory usage" + default n + help + Warning: this feature is known to cause problems with some modules. + Disable it if you experience problems like segmentation faults. + + endmenu +endef + +define BuildAsteriskModule + define Package/$(PKG_NAME)-$(1) + $$(call Package/$(PKG_NAME)/Default) + TITLE:=$(2) support + DEPENDS:= $(PKG_NAME) $(patsubst +%,+PACKAGE_$(PKG_NAME)-$(1):%,$(4)) $(9) + ifneq ($$(CONFIG_PACKAGE_$(PKG_NAME)-$(1)),) + AST_ENABLE+=$(6) + endif + endef + + define Package/$(PKG_NAME)-$(1)/conffiles +$(subst $(space),$(newline),$(foreach c,$(5),/etc/asterisk/$(c))) + endef + + define Package/$(PKG_NAME)-$(1)/description +$(subst \n,$(newline),$(3)) + endef + + define Package/$(PKG_NAME)-$(1)/install +$(foreach c,$(5),$(call Package/$(PKG_NAME)/install/conffile,$$(1),$(c));) +$(foreach m,$(6),$(call Package/$(PKG_NAME)/install/module,$$(1),$(m));) +$(foreach s,$(7),$(call Package/$(PKG_NAME)/install/sounds,$$(1),$(s));) +$(foreach b,$(8),$(call Package/$(PKG_NAME)/install/sbin,$$(1),$(b));) + endef + + $$(eval $$(call BuildPackage,$(PKG_NAME)-$(1))) +endef + +define BuildAsteriskUtil + define Package/$(PKG_NAME)-util-$(subst _,-,$(1)) + $$(call Package/$(PKG_NAME)/Default) + TITLE:=$(1) utility + DEPENDS:=$(PKG_NAME) $(patsubst +%,+PACKAGE_$(PKG_NAME)-util-$(subst _,-,$(1)):%,$(3)) + ifneq ($$(CONFIG_PACKAGE_$(PKG_NAME)-util-$(subst _,-,$(1))),) + AST_ENABLE+=$(1) + endif + endef + + define Package/$(PKG_NAME)-util-$(subst _,-,$(1))/conffiles +$(subst $(space),$(newline),$(foreach c,$(4),/etc/$(c))) + endef + + define Package/$(PKG_NAME)-util-$(subst _,-,$(1))/description +$(2) + endef + + define Package/$(PKG_NAME)-util-$(subst _,-,$(1))/install +$(call Package/$(PKG_NAME)/install/sbin,$$(1),$(1)) +$(foreach c,$(4),$(call Package/$(PKG_NAME)/install/util-conffile,$$(1),$(c));) + endef + + $$(eval $$(call BuildPackage,$(PKG_NAME)-util-$(subst _,-,$(1)))) +endef + +define Package/$(PKG_NAME)/Default + SUBMENU:=Telephony + SECTION:=net + CATEGORY:=Network + URL:=http://www.asterisk.org/ +endef + +define Package/$(PKG_NAME)/Default/description + Asterisk is a complete PBX in software. It provides all of the features + you would expect from a PBX and more. Asterisk does voice over IP in three + protocols, and can interoperate with almost all standards-based telephony + equipment using relatively inexpensive hardware. +endef + +define Package/$(PKG_NAME) +$(call Package/$(PKG_NAME)/Default) + TITLE:=Complete open source PBX, v$(PKG_VERSION) + MENU:=1 + DEPENDS:=+ASTERISK_LIBXSLT_SUPPORT:libxslt +libstdcpp +jansson +libcap +libedit +libopenssl +libsqlite3 +libuuid +libxml2 +zlib + USERID:=asterisk=385:asterisk=385 +endef + +define Package/$(PKG_NAME)/description +$(call Package/$(PKG_NAME)/Default/description) +endef + +define Package/$(PKG_NAME)/conffiles +/etc/asterisk/asterisk.conf +/etc/asterisk/acl.conf +/etc/asterisk/cel.conf +/etc/asterisk/ccss.conf +/etc/asterisk/cli.conf +/etc/asterisk/cli_permissions.conf +/etc/asterisk/codecs.conf +/etc/asterisk/dnsmgr.conf +/etc/asterisk/dsp.conf +/etc/asterisk/extconfig.conf +/etc/asterisk/extensions.conf +/etc/asterisk/features.conf +/etc/asterisk/http.conf +/etc/asterisk/indications.conf +/etc/asterisk/logger.conf +/etc/asterisk/manager.conf +/etc/asterisk/modules.conf +/etc/asterisk/res_config_sqlite3.conf +/etc/asterisk/stasis.conf +/etc/asterisk/udptl.conf +/etc/asterisk/users.conf +/etc/config/asterisk +/etc/init.d/asterisk +endef + +AST_CFG_FILES:= \ + asterisk.conf acl.conf cel.conf ccss.conf cli.conf \ + cli_permissions.conf codecs.conf dnsmgr.conf dsp.conf extconfig.conf \ + extensions.conf features.conf http.conf indications.conf \ + logger.conf manager.conf modules.conf stasis.conf udptl.conf \ + users.conf res_config_sqlite3.conf + +AST_EMB_MODULES:=\ + app_dial app_echo app_macro app_playback \ + func_callerid func_logic func_strings func_timeout \ + pbx_config res_crypto res_timing_timerfd + +define Package/$(PKG_NAME)/install +$(call Package/$(PKG_NAME)/install/lib,$(1),libasteriskssl) +$(call Package/$(PKG_NAME)/install/sbin,$(1),asterisk) +$(call Package/$(PKG_NAME)/install/sbin,$(1),safe_asterisk) +$(call Package/$(PKG_NAME)/install/sbin,$(1),astgenkey) +$(foreach m,$(AST_CFG_FILES),$(call Package/$(PKG_NAME)/install/conffile,$(1),$(m));) +$(foreach m,$(AST_EMB_MODULES),$(call Package/$(PKG_NAME)/install/module,$(1),$(m));) + $(INSTALL_DIR) $(1)/etc/config + $(INSTALL_DIR) $(1)/etc/init.d + $(INSTALL_DIR) $(1)/usr/share/asterisk/agi-bin + $(INSTALL_DIR) $(1)/usr/share/asterisk/firmware/iax + $(INSTALL_DIR) $(1)/usr/share/asterisk/keys + $(INSTALL_DIR) $(1)/usr/share/asterisk/sounds + $(INSTALL_BIN) ./files/asterisk.init $(1)/etc/init.d/asterisk + $(INSTALL_CONF) ./files/asterisk.conf $(1)/etc/config/asterisk +endef + +define Package/$(PKG_NAME)-sounds +$(call Package/$(PKG_NAME)/Default) + TITLE:=Sounds support + DEPENDS:=$(PKG_NAME) +endef + +define Package/$(PKG_NAME)-sounds/description +This package provides the sound-files for Asterisk. +endef + +define Package/$(PKG_NAME)-sounds/install + $(INSTALL_DIR) $(1)/usr/share/asterisk/sounds/ + $(CP) $(PKG_INSTALL_DIR)/usr/share/asterisk/sounds/en/* $(1)/usr/share/asterisk/sounds/ + rm -f $(1)/usr/share/asterisk/sounds/vm-* +endef + +ifeq ($(call qstrip,$(CONFIG_LIBC)),musl) + CONFIGURE_ARGS+= \ + --enable-permanent-dlopen +endif + +ifneq ($(CONFIG_PACKAGE_$(PKG_NAME)-chan-dahdi),) + CONFIGURE_ARGS+= \ + --with-dahdi="$(STAGING_DIR)/usr" \ + --with-pri="$(STAGING_DIR)/usr" \ + --with-tonezone="$(STAGING_DIR)/usr" +else + CONFIGURE_ARGS+= \ + --without-dahdi \ + --without-pri \ + --without-tonezone +endif + +# Pass CPPFLAGS in the CFLAGS as otherwise the build system will +# ignore them. +TARGET_CFLAGS+=$(TARGET_CPPFLAGS) + +CONFIGURE_ARGS+= \ + --disable-xmldoc \ + $(if $(CONFIG_PACKAGE_$(PKG_NAME)-chan-alsa),--with-asound="$(STAGING_DIR)/usr",--without-asound) \ + --without-execinfo \ + $(if $(CONFIG_PACKAGE_$(PKG_NAME)-chan-mobile),--with-bluetooth="$(STAGING_DIR)/usr",--without-bluetooth) \ + --with-cap="$(STAGING_DIR)/usr" \ + $(if $(CONFIG_PACKAGE_$(PKG_NAME)-curl),--with-libcurl="$(STAGING_DIR)/usr") \ + --with-gsm=internal \ + --without-gtk2 \ + --with-ilbc=internal \ + --without-pjproject-bundled \ + --with-libedit="$(STAGING_DIR)/usr" \ + --with-libxml2 \ + $(if $(CONFIG_ASTERISK_LIBXSLT_SUPPORT),--with-libxslt,--without-libxslt) \ + $(if $(CONFIG_PACKAGE_$(PKG_NAME)-res-snmp),--with-netsnmp="$(STAGING_DIR)/usr",--without-netsnmp) \ + --without-newt \ + --without-osptk \ + $(if $(CONFIG_PACKAGE_$(PKG_NAME)-pbx-lua),--with-lua="$(STAGING_DIR)/usr",--without-lua) \ + $(if $(CONFIG_PACKAGE_$(PKG_NAME)-pgsql),--with-postgres="$(STAGING_DIR)/usr",--without-postgres) \ + $(if $(CONFIG_PACKAGE_$(PKG_NAME)-util-smsq),--with-popt="$(STAGING_DIR)/usr",--without-popt) \ + $(if $(CONFIG_PACKAGE_$(PKG_NAME)-chan-console),--with-portaudio="$(STAGING_DIR)/usr",--without-portaudio) \ + --without-radius \ + $(if $(CONFIG_PACKAGE_$(PKG_NAME)-res-fax-spandsp),--with-spandsp="$(STAGING_DIR)/usr",--without-spandsp) \ + --without-sdl \ + --with-sqlite3="$(STAGING_DIR)/usr" \ + --without-tds \ + $(if $(CONFIG_PACKAGE_$(PKG_NAME)-res-resolver-unbound),--with-unbound="$(STAGING_DIR)/usr",--without-unbound) \ + $(if $(CONFIG_PACKAGE_$(PKG_NAME)-format-ogg-vorbis),--with-vorbis="$(STAGING_DIR)/usr",--without-vorbis) \ + $(if $(CONFIG_PACKAGE_$(PKG_NAME)-app-voicemail-imap),--with-imap=system,--without-imap) \ + --without-uriparser \ + --with-z="$(STAGING_DIR)/usr" + +ifeq ($(CONFIG_PACKAGE_$(PKG_NAME)-codec-speex)$(CONFIG_PACKAGE_$(PKG_NAME)-format-ogg-speex)$(CONFIG_PACKAGE_$(PKG_NAME)-func-speex),) +CONFIGURE_ARGS+= \ + --without-speex +else +CONFIGURE_ARGS+= \ + --with-speex="$(STAGING_DIR)/usr" +endif + +ifeq ($(CONFIG_PACKAGE_$(PKG_NAME)-codec-speex)$(CONFIG_PACKAGE_$(PKG_NAME)-func-speex),) +CONFIGURE_ARGS+= \ + --without-speexdsp +else +CONFIGURE_ARGS+= \ + --with-speexdsp="$(STAGING_DIR)/usr" +endif + +ifeq ($(CONFIG_PACKAGE_$(PKG_NAME)-format-ogg-speex)$(CONFIG_PACKAGE_$(PKG_NAME)-format-ogg-vorbis),) +CONFIGURE_ARGS+= \ + --without-ogg +else +CONFIGURE_ARGS+= \ + --with-ogg="$(STAGING_DIR)/usr" +endif + +ifeq ($(CONFIG_PACKAGE_$(PKG_NAME)-res-srtp),) +CONFIGURE_ARGS+= \ + --without-srtp +else +CONFIGURE_ARGS+= \ + --with-srtp="$(STAGING_DIR)/usr" +endif + +ifeq ($(CONFIG_PACKAGE_$(PKG_NAME)-pjsip)$(CONFIG_PACKAGE_$(PKG_NAME)-res-pjproject)$(CONFIG_PACKAGE_$(PKG_NAME)-res-rtp-asterisk),) +CONFIGURE_ARGS+= \ + --without-pjproject +else +CONFIGURE_ARGS+= \ + --with-pjproject="$(STAGING_DIR)/usr" +endif + +# res-calendar-ews requires both neon and neon29 detection +ifeq ($(CONFIG_PACKAGE_$(PKG_NAME)-res-calendar-caldav)$(CONFIG_PACKAGE_$(PKG_NAME)-res-calendar-ews)$(CONFIG_PACKAGE_$(PKG_NAME)-res-calendar-exchange)$(CONFIG_PACKAGE_$(PKG_NAME)-res-calendar-icalendar),) +CONFIGURE_ARGS+= \ + --without-neon +endif + +ifeq ($(CONFIG_PACKAGE_$(PKG_NAME)-res-calendar-caldav)$(CONFIG_PACKAGE_$(PKG_NAME)-res-calendar-exchange)$(CONFIG_PACKAGE_$(PKG_NAME)-res-calendar-icalendar),) +CONFIGURE_ARGS+= \ + --without-ical +else +CONFIGURE_ARGS+= \ + --with-ical="$(STAGING_DIR)/usr" +endif + +ifeq ($(CONFIG_PACKAGE_$(PKG_NAME)-res-calendar-ews),) +CONFIGURE_ARGS+= \ + --without-neon29 +endif + +ifeq ($(CONFIG_PACKAGE_$(PKG_NAME)-res-calendar-exchange)$(CONFIG_PACKAGE_$(PKG_NAME)-res-xmpp),) +CONFIGURE_ARGS+= \ + --without-iksemel +else +CONFIGURE_ARGS+= \ + --with-iksemel="$(STAGING_DIR)/usr" +endif + +ifneq ($(CONFIG_PACKAGE_$(PKG_NAME)-res-calendar-caldav)$(CONFIG_PACKAGE_$(PKG_NAME)-res-calendar-ews)$(CONFIG_PACKAGE_$(PKG_NAME)-res-calendar-exchange)$(CONFIG_PACKAGE_$(PKG_NAME)-res-calendar-icalendar),) +CONFIGURE_VARS += \ + ac_cv_path_CONFIG_NEON=$(STAGING_DIR)/usr/bin/neon-config +endif + +ifneq ($(CONFIG_PACKAGE_$(PKG_NAME)-res-calendar-ews),) +CONFIGURE_VARS += \ + ac_cv_path_CONFIG_NEON29=$(STAGING_DIR)/usr/bin/neon-config +endif + +MAKE_FLAGS+= \ + ASTDATADIR="/usr/share/asterisk" \ + DESTDIR="$(PKG_INSTALL_DIR)" + +# show full gcc arguments instead of [CC] and [LD] +MAKE_FLAGS+= \ + NOISY_BUILD="yes" + +# don't let asterisk mess with build flags +MAKE_FLAGS+= \ + AST_FORTIFY_SOURCE="" \ + DEBUG="" \ + OPTIMIZE="" + +AST_MENUSELECT_OPTS = \ + --without-newt \ + --without-curses + +define Build/menuselect + CC="$(HOSTCC)" \ + CFLAGS="$(HOST_CFLAGS)" \ + LDFLAGS="$(HOST_LDFLAGS) -Wl,-rpath,$(STAGING_DIR_HOSTPKG)/lib" \ + $(MAKE) -C "$(PKG_BUILD_DIR)/menuselect" +endef + +define Build/Configure + cd $(PKG_BUILD_DIR); \ + ./bootstrap.sh + $(call Build/Configure/Default) + cd $(PKG_BUILD_DIR)/menuselect; \ + CC="$(HOSTCC)" \ + CFLAGS="$(HOST_CFLAGS)" \ + CONFIG_SITE= \ + LDFLAGS="$(HOST_LDFLAGS) -Wl,-rpath,$(STAGING_DIR_HOSTPKG)/lib" \ + ./configure \ + $(HOST_CONFIGURE_ARGS) \ + $(AST_MENUSELECT_OPTS) +endef + +define Build/Compile + $(call Build/menuselect) + $(call Build/Compile/Default,menuselect-tree) + + cd "$(PKG_BUILD_DIR)" && MENUSELECT_ARGS= && \ + for cat in $(MENUSELECT_CATEGORIES); do \ + MENUSELECT_ARGS="$$$$MENUSELECT_ARGS --disable-category $$$$cat"; \ + done; \ + ./menuselect/menuselect \ + $$$$MENUSELECT_ARGS \ + menuselect.makeopts + cd "$(PKG_BUILD_DIR)" && MENUSELECT_ARGS= && \ + for item in $(AST_EMB_MODULES) $$(AST_ENABLE); do \ + MENUSELECT_ARGS="$$$$MENUSELECT_ARGS --enable $$$$item"; \ + done; \ + ./menuselect/menuselect \ + $$$$MENUSELECT_ARGS \ + menuselect.makeopts + cd "$(PKG_BUILD_DIR)" && \ + ./menuselect/menuselect \ + --disable BUILD_NATIVE \ + $(if $(CONFIG_ASTERISK_LOW_MEMORY),--enable LOW_MEMORY) \ + menuselect.makeopts + + # When changing anything in MENUSELECT_CFLAGS the file ".lastclean" + # gets deleted. E.g. when compiling on x86 for x86 "--disable + # BUILD_NATIVE" changes MENUSELECT_CFLAGS and the file gets removed. + # But that will result in a rebuild attempt of menuselect which will + # likely fail. Prevent that by recreating ".lastclean" and menuselect. + $(call Build/Compile/Default,.lastclean) + $(call Build/menuselect) + + $(call Build/Compile/Default,all install install-headers samples) +endef + +define Build/InstallDev + $(INSTALL_DIR) $(1)/usr/include/asterisk + $(INSTALL_DATA) $(PKG_INSTALL_DIR)/usr/include/asterisk/*.h $(1)/usr/include/asterisk/ + $(INSTALL_DATA) $(PKG_INSTALL_DIR)/usr/include/asterisk.h $(1)/usr/include/ +endef + +$(eval $(call BuildPackage,$(PKG_NAME))) +$(eval $(call BuildPackage,$(PKG_NAME)-sounds)) + +####################################### +# AST modules +# Params: +# 1 - Package subname +# 2 - Package title +# 3 - Module description +# 4 - Module dependencies +# 5 - conf files +# 6 - module files +# 7 - sound files +# 8 - binary files +# 9 - complex depends (passed on as is) +####################################### +#$(eval $(call BuildAsteriskModule,subname,title,module description,module dependencies,conf files,module files,sound files,binary files,complex depends)) + +$(eval $(call BuildAsteriskModule,app-adsiprog,ADSI programming,Asterisk ADSI programming application.,+$(PKG_NAME)-res-adsi,adsi.conf asterisk.adsi telcordia-1.adsi,app_adsiprog,,)) +$(eval $(call BuildAsteriskModule,app-agent-pool,Call center agent pool,Call center agent pool applications.,,agents.conf,app_agent_pool,,)) +$(eval $(call BuildAsteriskModule,app-alarmreceiver,Alarm receiver,Alarm receiver for Asterisk.,,,app_alarmreceiver,,)) +$(eval $(call BuildAsteriskModule,app-amd,Answering machine detection,Answering Machine Detection application.,,amd.conf,app_amd,,)) +$(eval $(call BuildAsteriskModule,app-attended-transfer,Attended transfer,Queues up an attended transfer to a given extension.,,,app_attended_transfer,,)) +$(eval $(call BuildAsteriskModule,app-audiosocket,Audiosocket app,Audiosocket app.,+$(PKG_NAME)-res-audiosocket,,app_audiosocket,,)) +$(eval $(call BuildAsteriskModule,app-authenticate,Authenticate commands,Authentication application.,,,app_authenticate,,)) +$(eval $(call BuildAsteriskModule,app-blind-transfer,Blind transfer,Redirects all channels currently bridged to the caller channel to a specified destination.,,,app_blind_transfer,,)) +$(eval $(call BuildAsteriskModule,app-bridgeaddchan,Bridge add channel,Bridge-add-channel application.,,,app_bridgeaddchan,,)) +$(eval $(call BuildAsteriskModule,app-bridgewait,Holding bridge,Application to place a channel into a holding bridge.,+$(PKG_NAME)-bridge-holding,,app_bridgewait,,)) +$(eval $(call BuildAsteriskModule,app-broadcast,Channel audio broadcasting,Channel Audio Broadcasting.,,,app_broadcast,,)) +$(eval $(call BuildAsteriskModule,app-celgenuserevent,User-defined CEL event,Generate a user defined CEL event.,,,app_celgenuserevent,,)) +$(eval $(call BuildAsteriskModule,app-chanisavail,Channel availability check,Check channel availability.,,,app_chanisavail,,)) +$(eval $(call BuildAsteriskModule,app-channelredirect,Redirect a channel,Redirects a given channel to a dialplan target.,,,app_channelredirect,,)) +$(eval $(call BuildAsteriskModule,app-chanspy,Channel listen in,Listen to the audio of an active channel.,,,app_chanspy,,)) +$(eval $(call BuildAsteriskModule,app-confbridge,ConfBridge,Conference bridge application.,+$(PKG_NAME)-bridge-builtin-features +$(PKG_NAME)-bridge-simple +$(PKG_NAME)-bridge-softmix,confbridge.conf,app_confbridge,,)) +$(eval $(call BuildAsteriskModule,app-controlplayback,Control playback,Control playback application.,,,app_controlplayback,,)) +$(eval $(call BuildAsteriskModule,app-dictate,Virtual dictation machine,Virtual dictation machine.,,,app_dictate,,)) +$(eval $(call BuildAsteriskModule,app-directed-pickup,Directed call pickup,Directed call pickup application.,,,app_directed_pickup,,)) +$(eval $(call BuildAsteriskModule,app-directory,Extension directory,Extension directory.,,,app_directory,,)) +$(eval $(call BuildAsteriskModule,app-disa,Direct Inward System Access,Direct Inward System Access application.,,,app_disa,,)) +$(eval $(call BuildAsteriskModule,app-dtmfstore,DTMF storage,Technology independent async DTMF storage.,,,app_dtmfstore,,)) +$(eval $(call BuildAsteriskModule,app-dumpchan,Dump info about channel,Dump info about the calling channel.,,,app_dumpchan,,)) +$(eval $(call BuildAsteriskModule,app-exec,Exec application,Executes dialplan applications.,,,app_exec,,)) +$(eval $(call BuildAsteriskModule,app-externalivr,External IVR interface,External IVR interface application.,,,app_externalivr,,)) +$(eval $(call BuildAsteriskModule,app-festival,Simple festival interface,Simple Festival interface.,,festival.conf,app_festival,,)) +$(eval $(call BuildAsteriskModule,app-flash,Flash channel,Flash channel application.,+$(PKG_NAME)-chan-dahdi,,app_flash,,)) +$(eval $(call BuildAsteriskModule,app-followme,Find-me/follow-me,Find-Me/Follow-Me application.,,followme.conf,app_followme,,)) +$(eval $(call BuildAsteriskModule,app-getcpeid,Get ADSI CPE ID,Get ADSI CPE ID.,+asterisk-res-adsi,,app_getcpeid,,)) +$(eval $(call BuildAsteriskModule,app-if,If branch and conditional execution,If Branch and Conditional Execution.,,,app_if,,)) +$(eval $(call BuildAsteriskModule,app-ivrdemo,IVR demo,IVR demo application.,,,app_ivrdemo,,)) +$(eval $(call BuildAsteriskModule,app-mf,MF digits,Send MF digits Application.,,,app_mf,,)) +$(eval $(call BuildAsteriskModule,app-milliwatt,Digital milliwatt [mu-law] test app,Digital milliwatt test application.,,,app_milliwatt,,)) +$(eval $(call BuildAsteriskModule,app-minivm,Minimal voicemail system,A minimal voicemail e-mail system.,,extensions_minivm.conf minivm.conf,app_minivm,,)) +$(eval $(call BuildAsteriskModule,app-mixmonitor,Record a call and mix the audio,Mixed audio monitoring application.,,,app_mixmonitor,,)) +$(eval $(call BuildAsteriskModule,app-morsecode,Morse code,Morse code.,,,app_morsecode,,)) +$(eval $(call BuildAsteriskModule,app-mp3,Silly MP3,Silly MP3 application.,+mpg123,,app_mp3,,)) +$(eval $(call BuildAsteriskModule,app-originate,Originate a call,Originate call.,,,app_originate,,)) +$(eval $(call BuildAsteriskModule,app-page,Page multiple phones,Page multiple phones.,+$(PKG_NAME)-app-confbridge,,app_page,,)) +$(eval $(call BuildAsteriskModule,app-playtones,Playtones application,Playtones application.,,,app_playtones,,)) +$(eval $(call BuildAsteriskModule,app-privacy,Require phone number,Require phone number to be entered if no Caller ID sent.,,,app_privacy,,)) +$(eval $(call BuildAsteriskModule,app-queue,True Call Queueing,True call queueing.,,queues.conf queuerules.conf,app_queue,,)) +$(eval $(call BuildAsteriskModule,app-read,Variable read,Read variable application.,,,app_read,,)) +$(eval $(call BuildAsteriskModule,app-readexten,Extension to variable,Read and evaluate extension validity.,,,app_readexten,,)) +$(eval $(call BuildAsteriskModule,app-record,Record sound file,Trivial record application.,,,app_record,,)) +$(eval $(call BuildAsteriskModule,app-reload,Reload,Reload module[s].,,,app_reload,,)) +$(eval $(call BuildAsteriskModule,app-saycounted,Decline words,Decline words according to channel language.,,,app_saycounted,,)) +$(eval $(call BuildAsteriskModule,app-sayunixtime,Say Unix time,Say time.,,,app_sayunixtime,,)) +$(eval $(call BuildAsteriskModule,app-senddtmf,Send DTMF digits,Send DTMF digits application.,,,app_senddtmf,,)) +$(eval $(call BuildAsteriskModule,app-sendtext,Send text,Send text applications.,,,app_sendtext,,)) +$(eval $(call BuildAsteriskModule,app-sf,SF Sender and Receiver Applications,SF Sender and Receiver Applications.,,,app_sf,,)) +$(eval $(call BuildAsteriskModule,app-signal,Channel signaling,Channel Signaling Applications.,,,app_signal,,)) +$(eval $(call BuildAsteriskModule,app-skel,Skeleton [sample],Skeleton application.,,app_skel.conf,app_skel,,)) +$(eval $(call BuildAsteriskModule,app-sms,SMS,SMS/PSTN handler.,,,app_sms,,)) +$(eval $(call BuildAsteriskModule,app-softhangup,Hang up requested channel,Hangs up the requested channel.,,,app_softhangup,,)) +$(eval $(call BuildAsteriskModule,app-speech,Dialplan Speech,Dialplan speech applications.,+$(PKG_NAME)-res-speech,,app_speech_utils,,)) +$(eval $(call BuildAsteriskModule,app-stack,Stack applications,Dialplan subroutines.,+$(PKG_NAME)-res-agi,,app_stack,,)) +$(eval $(call BuildAsteriskModule,app-stasis,Stasis dialplan,Stasis dialplan application.,+$(PKG_NAME)-res-stasis,,app_stasis,,)) +$(eval $(call BuildAsteriskModule,app-statsd,statsd dialplan,StatsD dialplan application.,+$(PKG_NAME)-res-statsd,,app_statsd,,)) +$(eval $(call BuildAsteriskModule,app-stream-echo,Stream echo,Stream echo application.,,,app_stream_echo,,)) +$(eval $(call BuildAsteriskModule,app-system,System exec,Generic system application.,,,app_system,,)) +$(eval $(call BuildAsteriskModule,app-talkdetect,File playback with audio detect,Playback with talk detection.,,,app_talkdetect,,)) +$(eval $(call BuildAsteriskModule,app-test,Interface test,Interface test application.,,,app_test,,)) +$(eval $(call BuildAsteriskModule,app-transfer,Transfers caller to other ext,Transfers a caller to another extension.,,,app_transfer,,)) +$(eval $(call BuildAsteriskModule,app-userevent,Custom user event,Custom user event application.,,,app_userevent,,)) +$(eval $(call BuildAsteriskModule,app-verbose,Verbose logging,Send verbose output.,,,app_verbose,,)) +$(eval $(call BuildAsteriskModule,app-waitforcond,Wait for condition,Wait until condition is true.,,,app_waitforcond,,)) +$(eval $(call BuildAsteriskModule,app-voicemail,Voicemail,Voicemail module.,,voicemail.conf,app_voicemail,vm-*,)) +$(eval $(call BuildAsteriskModule,app-voicemail-imap,Voicemail IMAP,Voicemail module.,+uw-imap,,app_voicemail_imap,,)) +$(eval $(call BuildAsteriskModule,app-voicemail-odbc,Voicemail ODBC,Voicemail module.,+unixodbc,,app_voicemail_odbc,,)) +$(eval $(call BuildAsteriskModule,app-waitforring,Wait for first ring,Waits until first ring after time.,,,app_waitforring,,)) +$(eval $(call BuildAsteriskModule,app-waitforsilence,Wait for silence/noise,Wait for silence/noise.,,,app_waitforsilence,,)) +$(eval $(call BuildAsteriskModule,app-waituntil,Sleep,Wait until specified time.,,,app_waituntil,,)) +$(eval $(call BuildAsteriskModule,app-while,While loop,While loops and conditional execution.,,,app_while,,)) +$(eval $(call BuildAsteriskModule,app-zapateller,Block telemarketers,Block telemarketers with special information tone.,,,app_zapateller,,)) +$(eval $(call BuildAsteriskModule,bridge-builtin-features,Bridging features,Built in bridging features.,,,bridge_builtin_features,,)) +$(eval $(call BuildAsteriskModule,bridge-builtin-interval-features,Built in bridging interval features,Built in bridging interval features.,,,bridge_builtin_interval_features,,)) +$(eval $(call BuildAsteriskModule,bridge-holding,Bridging for storing channels in a bridge,Holding bridge module.,,,bridge_holding,,)) +$(eval $(call BuildAsteriskModule,bridge-native-rtp,Native RTP bridging technology module,Native RTP bridging module.,,,bridge_native_rtp,,)) +$(eval $(call BuildAsteriskModule,bridge-simple,Simple two channel bridging module,Simple two channel bridging module.,,,bridge_simple,,)) +$(eval $(call BuildAsteriskModule,bridge-softmix,Multi-party software based channel mixing,Multi-party software based channel mixing.,,,bridge_softmix,,)) +$(eval $(call BuildAsteriskModule,cdr,Provides CDR,Call Detail Records.,,cdr.conf cdr_custom.conf cdr_manager.conf,app_cdr app_forkcdr cdr_custom cdr_manager func_cdr,,)) +$(eval $(call BuildAsteriskModule,cdr-csv,Provides CDR CSV,Comma Separated Values CDR backend.,,,cdr_csv,,)) +$(eval $(call BuildAsteriskModule,cdr-sqlite3,Provides CDR SQLITE3,SQLite3 CDR backend.,libsqlite3,,cdr_sqlite3_custom,,)) +$(eval $(call BuildAsteriskModule,cel-custom,Customizable CSV CEL backend,Customizable Comma Separated Values CEL backend.,,cel_custom.conf,cel_custom,,)) +$(eval $(call BuildAsteriskModule,cel-manager,AMI CEL backend,Asterisk Manager Interface CEL backend.,,,cel_manager,,)) +$(eval $(call BuildAsteriskModule,cel-sqlite3-custom,SQLite3 custom CEL,SQLite3 custom CEL module.,,cel_sqlite3_custom.conf,cel_sqlite3_custom,,)) +$(eval $(call BuildAsteriskModule,chan-alsa,ALSA channel,ALSA console channel driver.,+alsa-lib,alsa.conf,chan_alsa,,)) +$(eval $(call BuildAsteriskModule,chan-audiosocket,Audiosocket channel,Audiosocket channel.,+$(PKG_NAME)-res-audiosocket,,chan_audiosocket,,)) +$(eval $(call BuildAsteriskModule,chan-bridge-media,Bridge media channel driver,Bridge media channel driver.,,,chan_bridge_media,,)) +$(eval $(call BuildAsteriskModule,chan-console,Console channel driver,Console channel driver.,+portaudio,console.conf,chan_console,,)) +$(eval $(call BuildAsteriskModule,chan-dahdi,DAHDI channel,DAHDI telephony.,+dahdi-tools-libtonezone +kmod-dahdi +libpri @!aarch64,chan_dahdi.conf,chan_dahdi,,)) +$(eval $(call BuildAsteriskModule,chan-iax2,IAX2 channel,Inter Asterisk eXchange.,,iax.conf iaxprov.conf,chan_iax2,,)) +$(eval $(call BuildAsteriskModule,chan-mgcp,MGCP,Media Gateway Control Protocol.,,mgcp.conf,chan_mgcp,,)) +$(eval $(call BuildAsteriskModule,chan-mobile,Bluetooth channel,Bluetooth mobile device channel driver.,+bluez-libs,chan_mobile.conf,chan_mobile,,)) +$(eval $(call BuildAsteriskModule,chan-motif,Jingle channel,Motif Jingle channel driver.,+$(PKG_NAME)-res-xmpp,motif.conf,chan_motif,,)) +$(eval $(call BuildAsteriskModule,chan-ooh323,H.323 channel,Objective Systems H.323 channel.,,ooh323.conf,chan_ooh323,,)) +$(eval $(call BuildAsteriskModule,chan-rtp,RTP media channel,RTP media channel.,+asterisk-res-rtp-multicast,,chan_rtp,,)) +$(eval $(call BuildAsteriskModule,chan-sip,SIP channel,Session Initiation Protocol.,+$(PKG_NAME)-app-confbridge,sip.conf sip_notify.conf,chan_sip,,)) +$(eval $(call BuildAsteriskModule,chan-skinny,Skinny channel,Skinny Client Control Protocol.,,skinny.conf,chan_skinny,,)) +$(eval $(call BuildAsteriskModule,chan-unistim,Unistim channel,UNISTIM protocol.,,unistim.conf,chan_unistim,,)) +$(eval $(call BuildAsteriskModule,codec-a-mu,Alaw to ulaw translation,Alaw and ulaw direct coder/decoder.,,,codec_a_mu,,)) +$(eval $(call BuildAsteriskModule,codec-adpcm,ADPCM text,Adaptive Differential PCM coder/decoder.,,,codec_adpcm,,)) +$(eval $(call BuildAsteriskModule,codec-alaw,Signed linear to alaw translation,Alaw coder/decoder.,,,codec_alaw,,)) +$(eval $(call BuildAsteriskModule,codec-dahdi,DAHDI codec,Generic DAHDI transcoder codec translator.,+$(PKG_NAME)-chan-dahdi,,codec_dahdi,,)) +$(eval $(call BuildAsteriskModule,codec-g722,G.722,ITU G.722-64kbps G722 transcoder.,,,codec_g722,,)) +$(eval $(call BuildAsteriskModule,codec-g726,Signed linear to G.726 translation,ITU G.726-32kbps G726 transcoder.,,,codec_g726,,)) +$(eval $(call BuildAsteriskModule,codec-gsm,linear to GSM translation,GSM coder/decoder.,,,codec_gsm,,)) +$(eval $(call BuildAsteriskModule,codec-ilbc,linear to ILBC translation,iLBC coder/decoder.,,,codec_ilbc,,)) +$(eval $(call BuildAsteriskModule,codec-lpc10,Linear to LPC10 translation,LPC10 2.4kbps coder/decoder.,,,codec_lpc10,,)) +$(eval $(call BuildAsteriskModule,codec-resample,resample sLinear audio,SLIN resampling codec.,,,codec_resample,,)) +$(eval $(call BuildAsteriskModule,codec-speex,Speex Coder/Decoder,Speex coder/decoder.,@!SOFT_FLOAT +libspeex +libspeexdsp,,codec_speex,,)) +$(eval $(call BuildAsteriskModule,codec-ulaw,Signed linear to ulaw translation,Ulaw coder/decoder.,,,codec_ulaw,,)) +$(eval $(call BuildAsteriskModule,curl,CURL,cURL,+libcurl,,func_curl res_config_curl res_curl,,)) +$(eval $(call BuildAsteriskModule,format-g719,G.719,ITU G.719.,,,format_g719,,)) +$(eval $(call BuildAsteriskModule,format-g723,G.723.1,G.723.1 simple timestamp file format.,,,format_g723,,)) +$(eval $(call BuildAsteriskModule,format-g726,G.726,Raw G.726 data.,,,format_g726,,)) +$(eval $(call BuildAsteriskModule,format-g729,G.729,Raw G.729 data.,,,format_g729,,)) +$(eval $(call BuildAsteriskModule,format-gsm,GSM format,Raw GSM data.,,,format_gsm,,)) +$(eval $(call BuildAsteriskModule,format-h263,H263 format,Raw H.263 data.,,,format_h263,,)) +$(eval $(call BuildAsteriskModule,format-h264,H264 format,Raw H.264 data.,,,format_h264,,)) +$(eval $(call BuildAsteriskModule,format-ilbc,ILBC format,Raw iLBC data.,,,format_ilbc,,)) +$(eval $(call BuildAsteriskModule,format-mp3,MP3 format,MP3 format.,@BROKEN,,format_mp3,,)) # requires patched mpg123 source +$(eval $(call BuildAsteriskModule,format-ogg-speex,OGG/Speex audio,OGG/Speex audio.,@!SOFT_FLOAT +libogg +libspeex,,format_ogg_speex,,)) +$(eval $(call BuildAsteriskModule,format-ogg-vorbis,OGG/Vorbis audio,OGG/Vorbis audio.,+libvorbis,,format_ogg_vorbis,,)) +$(eval $(call BuildAsteriskModule,format-pcm,PCM format,Raw/Sun ulaw/alaw 8KHz and G.722 16Khz.,,,format_pcm,,)) +$(eval $(call BuildAsteriskModule,format-siren14,Siren14,ITU G.722.1 Annex C.,,,format_siren14,,)) +$(eval $(call BuildAsteriskModule,format-siren7,Siren7,ITU G.722.1.,,,format_siren7,,)) +$(eval $(call BuildAsteriskModule,format-sln,Raw slinear format,Raw signed linear audio support 8khz-192khz.,,,format_sln,,)) +$(eval $(call BuildAsteriskModule,format-vox,VOX format,Dialogic VOX file format.,,,format_vox,,)) +$(eval $(call BuildAsteriskModule,format-wav,WAV format (8000hz Signed Linear),Microsoft WAV/WAV16 format.,,,format_wav,,)) +$(eval $(call BuildAsteriskModule,format-wav-gsm,WAV format (Proprietary GSM),Microsoft WAV format.,,,format_wav_gsm,,)) +$(eval $(call BuildAsteriskModule,func-aes,AES dialplan functions,AES dialplan functions.,,,func_aes,,)) +$(eval $(call BuildAsteriskModule,func-base64,base64,Base64 encode/decode dialplan functions.,,,func_base64,,)) +$(eval $(call BuildAsteriskModule,func-blacklist,Blacklist on callerid,Look up Caller ID name/number from blacklist database.,,,func_blacklist,,)) +$(eval $(call BuildAsteriskModule,func-callcompletion,Call control configuration function,Call control configuration function.,,,func_callcompletion,,)) +$(eval $(call BuildAsteriskModule,func-channel,Channel info,Channel information dialplan functions.,,,func_channel,,)) +$(eval $(call BuildAsteriskModule,func-config,Configuration file variable access,Asterisk configuration file variable access.,,,func_config,,)) +$(eval $(call BuildAsteriskModule,func-cut,CUT function,Cut out information from a string.,,,func_cut,,)) +$(eval $(call BuildAsteriskModule,func-db,Database interaction,Database related dialplan functions.,,,func_db app_db,,)) +$(eval $(call BuildAsteriskModule,func-devstate,Blinky lights control,Gets or sets a device state in the dialplan.,,,func_devstate,,)) +$(eval $(call BuildAsteriskModule,func-dialgroup,Dialgroup dialplan function,Dialgroup dialplan function.,,,func_dialgroup,,)) +$(eval $(call BuildAsteriskModule,func-dialplan,Dialplan context/extension/priority checking functions,Dialplan context/extension/priority checking functions.,,,func_dialplan,,)) +$(eval $(call BuildAsteriskModule,func-enum,ENUM,ENUM related dialplan functions.,,enum.conf,func_enum,,)) +$(eval $(call BuildAsteriskModule,func-env,Environment functions,Environment/filesystem dialplan functions.,,,func_env,,)) +$(eval $(call BuildAsteriskModule,func-evalexten,Extension evaluation,Extension evaluation functions.,,,func_evalexten,,)) +$(eval $(call BuildAsteriskModule,func-export,Export function,Set variables and functions on other channels.,,,func_export,,)) +$(eval $(call BuildAsteriskModule,func-extstate,Hinted extension state,Gets the state of an extension in the dialplan.,,,func_extstate,,)) +$(eval $(call BuildAsteriskModule,func-frame-drop,Frame drop,Function to drop frames on a channel.,,,func_frame_drop,,)) +$(eval $(call BuildAsteriskModule,func-frame-trace,Frame trace for internal ast_frame debugging,Frame trace for internal ast_frame debugging.,,,func_frame_trace,,)) +$(eval $(call BuildAsteriskModule,func-global,Global variable,Variable dialplan functions.,,,func_global,,)) +$(eval $(call BuildAsteriskModule,func-groupcount,Group count,Channel group dialplan functions.,,,func_groupcount,,)) +$(eval $(call BuildAsteriskModule,func-hangupcause,HANGUPCAUSE related functions,Hangup cause related functions and applications.,,,func_hangupcause,,)) +$(eval $(call BuildAsteriskModule,func-holdintercept,Hold interception dialplan function,Hold interception dialplan function.,,,func_holdintercept,,)) +$(eval $(call BuildAsteriskModule,func-iconv,Charset conversion,Charset conversions.,,,func_iconv,,,$(ICONV_DEPENDS))) +$(eval $(call BuildAsteriskModule,func-jitterbuffer,Jitter buffer for read side of channel,Jitter buffer for read side of channel.,,,func_jitterbuffer,,)) +$(eval $(call BuildAsteriskModule,func-json,JSON decoding function,JSON decoding function.,,,func_json,,)) +$(eval $(call BuildAsteriskModule,func-lock,Dialplan mutexes,Dialplan mutexes.,,,func_lock,,)) +$(eval $(call BuildAsteriskModule,func-math,Math functions,Mathematical dialplan function.,,,func_math,,)) +$(eval $(call BuildAsteriskModule,func-md5,MD5 digest dialplan functions,MD5 digest dialplan functions.,,,func_md5,,)) +$(eval $(call BuildAsteriskModule,func-module,Simple module check function,Checks if Asterisk module is loaded in memory.,,,func_module,,)) +$(eval $(call BuildAsteriskModule,func-periodic-hook,Periodic dialplan hooks,Periodic dialplan hooks.,+$(PKG_NAME)-app-chanspy +$(PKG_NAME)-func-cut +$(PKG_NAME)-func-groupcount +$(PKG_NAME)-func-uri,,func_periodic_hook,,)) +$(eval $(call BuildAsteriskModule,func-pitchshift,Audio effects dialplan functions,Audio effects dialplan functions.,,,func_pitchshift,,)) +$(eval $(call BuildAsteriskModule,func-presencestate,Hinted presence state,Gets or sets a presence state in the dialplan.,,,func_presencestate,,)) +$(eval $(call BuildAsteriskModule,func-rand,RAND dialplan function,Random number dialplan function.,,,func_rand,,)) +$(eval $(call BuildAsteriskModule,func-realtime,REALTIME dialplan function,Read/write/store/destroy values from a realtime repository.,,,func_realtime,,)) +$(eval $(call BuildAsteriskModule,func-sayfiles,Say files,Say application files.,,,func_sayfiles,,)) +$(eval $(call BuildAsteriskModule,func-scramble,Scramble,Frequency inverting voice scrambler.,,,func_scramble,,)) +$(eval $(call BuildAsteriskModule,func-sha1,SHA-1 computation dialplan function,SHA-1 computation dialplan function.,,,func_sha1,,)) +$(eval $(call BuildAsteriskModule,func-shell,Shell,Collects the output generated by a command executed by the system shell.,,,func_shell,,)) +$(eval $(call BuildAsteriskModule,func-sorcery,Get a field from a sorcery object,Get a field from a sorcery object.,,,func_sorcery,,)) +$(eval $(call BuildAsteriskModule,func-speex,Noise reduction and AGC,Noise reduction and Automatic Gain Control.,@!SOFT_FLOAT +libspeex +libspeexdsp,,func_speex,,)) +$(eval $(call BuildAsteriskModule,func-sprintf,SPRINTF dialplan function,SPRINTF dialplan function.,,,func_sprintf,,)) +$(eval $(call BuildAsteriskModule,func-srv,SRV functions,SRV related dialplan functions.,,,func_srv,,)) +$(eval $(call BuildAsteriskModule,func-sysinfo,System information related functions,System information related functions.,,,func_sysinfo,,)) +$(eval $(call BuildAsteriskModule,func-talkdetect,Talk detection dialplan function,Talk detection dialplan function.,,,func_talkdetect,,)) +$(eval $(call BuildAsteriskModule,func-uri,URI encoding and decoding,URI encode/decode dialplan functions.,,,func_uri,,)) +$(eval $(call BuildAsteriskModule,func-version,Get Asterisk version/build info,Get Asterisk version/build info.,,,func_version,,)) +$(eval $(call BuildAsteriskModule,func-vmcount,vmcount dialplan,Indicator for whether a voice mailbox has messages in a given folder.,,,func_vmcount,,)) +$(eval $(call BuildAsteriskModule,func-volume,Technology independent volume control,Technology independent volume control.,,,func_volume,,)) +$(eval $(call BuildAsteriskModule,odbc,ODBC,ODBC support.,+libpthread +libc +unixodbc,cdr_adaptive_odbc.conf cdr_odbc.conf cel_odbc.conf func_odbc.conf res_odbc.conf,cdr_adaptive_odbc cdr_odbc cel_odbc func_odbc res_config_odbc res_odbc res_odbc_transaction,,)) +$(eval $(call BuildAsteriskModule,pbx-ael,Asterisk Extension Logic,Asterisk Extension Language compiler.,+$(PKG_NAME)-res-ael-share,extensions.ael,pbx_ael,,)) +$(eval $(call BuildAsteriskModule,pbx-dundi,Dundi,Distributed Universal Number Discovery.,,dundi.conf,pbx_dundi,,)) +$(eval $(call BuildAsteriskModule,pbx-loopback,Loopback switch,Loopback switch.,,,pbx_loopback,,)) +$(eval $(call BuildAsteriskModule,pbx-lua,Lua,Lua PBX switch.,+liblua,extensions.lua,pbx_lua,,)) +$(eval $(call BuildAsteriskModule,pbx-realtime,Realtime Switch,Realtime switch.,,,pbx_realtime,,)) +$(eval $(call BuildAsteriskModule,pbx-spool,Call Spool,Outgoing spool support.,,,pbx_spool,,)) +$(eval $(call BuildAsteriskModule,pgsql,PostgreSQL,PostgreSQL support.,+libpq,cel_pgsql.conf cdr_pgsql.conf res_pgsql.conf,cel_pgsql cdr_pgsql res_config_pgsql,,)) +$(eval $(call BuildAsteriskModule,pjsip,pjsip channel,PJSIP SIP stack.,+$(PKG_NAME)-res-http-websocket +$(PKG_NAME)-res-pjproject +$(PKG_NAME)-res-sorcery +libpjsip +libpjmedia +libpjnath +libpjsip-simple +libpjsip-ua +libpjsua +libpjsua2,pjsip.conf pjsip_notify.conf pjsip_wizard.conf,chan_pjsip func_pjsip_aor func_pjsip_contact func_pjsip_endpoint res_pjsip res_pjsip_acl res_pjsip_authenticator_digest res_pjsip_caller_id res_pjsip_config_wizard res_pjsip_dialog_info_body_generator res_pjsip_diversion res_pjsip_dlg_options res_pjsip_dtmf_info res_pjsip_empty_info res_pjsip_endpoint_identifier_anonymous res_pjsip_endpoint_identifier_ip res_pjsip_endpoint_identifier_user res_pjsip_exten_state res_pjsip_header_funcs res_pjsip_history res_pjsip_logger res_pjsip_messaging res_pjsip_mwi res_pjsip_mwi_body_generator res_pjsip_nat res_pjsip_notify res_pjsip_one_touch_record_info res_pjsip_outbound_authenticator_digest res_pjsip_outbound_publish res_pjsip_outbound_registration res_pjsip_path res_pjsip_pidf_body_generator res_pjsip_pidf_digium_body_supplement res_pjsip_pidf_eyebeam_body_supplement res_pjsip_publish_asterisk res_pjsip_pubsub res_pjsip_refer res_pjsip_registrar res_pjsip_rfc3326 res_pjsip_sdp_rtp res_pjsip_send_to_voicemail res_pjsip_session res_pjsip_sips_contact res_pjsip_t38 res_pjsip_transport_websocket res_pjsip_xpidf_body_generator,,)) +$(eval $(call BuildAsteriskModule,res-adsi,Provide ADSI,ADSI resource.,,,res_adsi,,)) +$(eval $(call BuildAsteriskModule,res-aeap,Provide AEAP,AEAP resource.,+asterisk-res-http-websocket,aeap.conf,res_aeap,,)) +$(eval $(call BuildAsteriskModule,res-ael-share,Shareable AEL code,Shareable code for AEL.,,,res_ael_share,,)) +$(eval $(call BuildAsteriskModule,res-agi,Asterisk Gateway Interface,Asterisk Gateway Interface.,+$(PKG_NAME)-res-speech,,res_agi,,)) +$(eval $(call BuildAsteriskModule,res-ari,Asterisk RESTful interface,Asterisk RESTful Interface.,+$(PKG_NAME)-res-http-websocket,ari.conf,res_ari,,)) +$(eval $(call BuildAsteriskModule,res-ari-applications,RESTful Stasis application resources,RESTful API module - Stasis application resources.,+$(PKG_NAME)-res-ari +$(PKG_NAME)-res-ari-model +$(PKG_NAME)-res-stasis,,res_ari_applications,)) +$(eval $(call BuildAsteriskModule,res-ari-asterisk,RESTful Asterisk resources,RESTful API module - Asterisk resources.,+$(PKG_NAME)-res-ari +$(PKG_NAME)-res-ari-model +$(PKG_NAME)-res-stasis,,res_ari_asterisk,,)) +$(eval $(call BuildAsteriskModule,res-ari-bridges,RESTful bridge resources,RESTful API module - bridge resources.,+$(PKG_NAME)-res-ari +$(PKG_NAME)-res-ari-model +$(PKG_NAME)-res-stasis-playback,,res_ari_bridges,,)) +$(eval $(call BuildAsteriskModule,res-ari-channels,RESTful channel resources,RESTful API module - channel resources.,+$(PKG_NAME)-res-ari +$(PKG_NAME)-res-ari-model +$(PKG_NAME)-res-stasis-answer +$(PKG_NAME)-res-stasis-playback +$(PKG_NAME)-res-stasis-snoop,,res_ari_channels,,)) +$(eval $(call BuildAsteriskModule,res-ari-device-states,RESTful device state resources,RESTful API module - device state resources.,+$(PKG_NAME)-res-ari +$(PKG_NAME)-res-ari-model +$(PKG_NAME)-res-stasis-device-state,,res_ari_device_states,,)) +$(eval $(call BuildAsteriskModule,res-ari-endpoints,RESTful endpoint resources,RESTful API module - endpoint resources.,+$(PKG_NAME)-res-ari +$(PKG_NAME)-res-ari-model +$(PKG_NAME)-res-stasis,,res_ari_endpoints,,)) +$(eval $(call BuildAsteriskModule,res-ari-events,RESTful WebSocket resource,RESTful API module - WebSocket resource.,+$(PKG_NAME)-res-ari +$(PKG_NAME)-res-ari-model +$(PKG_NAME)-res-stasis,,res_ari_events,,)) +$(eval $(call BuildAsteriskModule,res-ari-mailboxes,RESTful mailboxes resources,RESTful API module - mailboxes resources.,+$(PKG_NAME)-res-ari +$(PKG_NAME)-res-ari-model +$(PKG_NAME)-res-stasis-mailbox,,res_ari_mailboxes,,)) +$(eval $(call BuildAsteriskModule,res-ari-model,ARI model validators,ARI model validators.,,,res_ari_model,,)) +$(eval $(call BuildAsteriskModule,res-ari-playbacks,RESTful playback control resources,RESTful API module - playback control resources.,+$(PKG_NAME)-res-ari +$(PKG_NAME)-res-ari-model +$(PKG_NAME)-res-stasis-playback,,res_ari_playbacks,,)) +$(eval $(call BuildAsteriskModule,res-ari-recordings,RESTful recording resources,RESTful API module - recording resources.,+$(PKG_NAME)-res-ari +$(PKG_NAME)-res-ari-model +$(PKG_NAME)-res-stasis-recording,,res_ari_recordings,,)) +$(eval $(call BuildAsteriskModule,res-ari-sounds,RESTful sound resources,RESTful API module - sound resources.,+$(PKG_NAME)-res-ari +$(PKG_NAME)-res-ari-model +$(PKG_NAME)-res-stasis,,res_ari_sounds,)) +$(eval $(call BuildAsteriskModule,res-audiosocket,Audiosocket resource module,Audiosocket resource module.,,,res_audiosocket,)) +$(eval $(call BuildAsteriskModule,res-calendar,Calendar API,Asterisk calendar integration.,,calendar.conf,res_calendar,,)) +$(eval $(call BuildAsteriskModule,res-calendar-caldav,CalDAV calendar,Asterisk CalDAV calendar integration.,+$(PKG_NAME)-res-calendar +libical +libneon,,res_calendar_caldav,,)) +$(eval $(call BuildAsteriskModule,res-calendar-ews,EWS calendar,Asterisk MS Exchange Web Service calendar integration.,+$(PKG_NAME)-res-calendar +libneon,,res_calendar_ews,,)) +$(eval $(call BuildAsteriskModule,res-calendar-exchange,Exchange calendar,Asterisk MS Exchange calendar integration.,+$(PKG_NAME)-res-calendar +libical +libiksemel +libneon,,res_calendar_exchange,,)) +$(eval $(call BuildAsteriskModule,res-calendar-icalendar,iCalendar calendar,Asterisk iCalendar .ics file integration.,+$(PKG_NAME)-res-calendar +libical +libneon,,res_calendar_icalendar,,)) +$(eval $(call BuildAsteriskModule,res-chan-stats,statsd channel stats,Example of how to use Stasis.,+$(PKG_NAME)-res-statsd,,res_chan_stats,,)) +$(eval $(call BuildAsteriskModule,res-clialiases,CLI aliases,CLI aliases.,,cli_aliases.conf,res_clialiases,,)) +$(eval $(call BuildAsteriskModule,res-cliexec,Execute from CLI,Simple dialplan execution from the CLI.,,,res_cliexec,,)) +$(eval $(call BuildAsteriskModule,res-clioriginate,Calls via CLI,Call origination and redirection from the CLI.,,,res_clioriginate,,)) +$(eval $(call BuildAsteriskModule,res-config-ldap,LDAP realtime interface,LDAP realtime interface.,+libopenldap,res_ldap.conf,res_config_ldap,,)) +$(eval $(call BuildAsteriskModule,res-config-mysql,MySQL CDR backend,MySQL realtime configuration driver.,+libmysqlclient,,res_config_mysql,,)) +$(eval $(call BuildAsteriskModule,res-config-sqlite3,SQLite 3 realtime config engine,SQLite3 realtime config engine.,,,res_config_sqlite3,,)) +$(eval $(call BuildAsteriskModule,res-convert,File format conversion CLI command,File format conversion CLI command.,,,res_convert,,)) +$(eval $(call BuildAsteriskModule,res-endpoint-stats,Endpoint statistics,Endpoint statistics.,+$(PKG_NAME)-res-statsd,,res_endpoint_stats,,)) +$(eval $(call BuildAsteriskModule,res-hep,HEPv3 API,HEPv3 API.,,hep.conf,res_hep,,)) +$(eval $(call BuildAsteriskModule,res-hep-pjsip,PJSIP HEPv3 Logger,PJSIP HEPv3 logger.,+$(PKG_NAME)-res-hep +$(PKG_NAME)-pjsip,,res_hep_pjsip,,)) +$(eval $(call BuildAsteriskModule,res-hep-rtcp,RTCP HEPv3 Logger,RTCP HEPv3 logger.,+$(PKG_NAME)-res-hep,,res_hep_rtcp,,)) +$(eval $(call BuildAsteriskModule,res-fax-spandsp,Spandsp T.38 and G.711,Spandsp G.711 and T.38 FAX technologies.,+$(PKG_NAME)-res-fax +libspandsp +libtiff,,res_fax_spandsp,,)) +$(eval $(call BuildAsteriskModule,res-fax,FAX modules,Generic FAX applications.,,res_fax.conf,res_fax,,)) +$(eval $(call BuildAsteriskModule,res-format-attr-celt,CELT format attribute module,CELT format attribute module.,,,res_format_attr_celt,,)) +$(eval $(call BuildAsteriskModule,res-format-attr-g729,G.729 format attribute module,G.729 format attribute module.,,,res_format_attr_g729,,)) +$(eval $(call BuildAsteriskModule,res-format-attr-h263,H.263 format attribute module,H.263 format attribute module.,,,res_format_attr_h263,,)) +$(eval $(call BuildAsteriskModule,res-format-attr-h264,H.264 format attribute module,H.264 format attribute module.,,,res_format_attr_h264,,)) +$(eval $(call BuildAsteriskModule,res-format-attr-ilbc,ILBC format attribute module,iLBC format attribute module.,,,res_format_attr_ilbc,,)) +$(eval $(call BuildAsteriskModule,res-format-attr-opus,Opus format attribute module,Opus format attribute module.,,,res_format_attr_opus,,)) +$(eval $(call BuildAsteriskModule,res-format-attr-silk,SILK format attribute module,SILK format attribute module.,,,res_format_attr_silk,,)) +$(eval $(call BuildAsteriskModule,res-format-attr-siren14,Siren14 format attribute module,Siren14 format attribute module.,,,res_format_attr_siren14,,)) +$(eval $(call BuildAsteriskModule,res-format-attr-siren7,Siren7 format attribute module,Siren7 format attribute module.,,,res_format_attr_siren7,,)) +$(eval $(call BuildAsteriskModule,res-format-attr-vp8,VP8 format attribute module,VP8 format attribute module.,,,res_format_attr_vp8,,)) +$(eval $(call BuildAsteriskModule,res-geolocation,Geolocation,Geolocation support.,@ASTERISK_LIBXSLT_SUPPORT,geolocation.conf,res_geolocation,,)) +$(eval $(call BuildAsteriskModule,res-http-media-cache,HTTP media cache backend,HTTP media cache backend.,+$(PKG_NAME)-curl,res_http_media_cache.conf,res_http_media_cache,,)) +$(eval $(call BuildAsteriskModule,res-http-websocket,HTTP websocket,HTTP WebSocket support.,,,res_http_websocket,,)) +$(eval $(call BuildAsteriskModule,res-limit,Resource limits,Resource limits.,,,res_limit,,)) +$(eval $(call BuildAsteriskModule,res-manager-devicestate,Device state topic forwarder,Manager device state topic forwarder.,,,res_manager_devicestate,,)) +$(eval $(call BuildAsteriskModule,res-manager-presencestate,Presence state topic forwarder,Manager presence state topic forwarder.,,,res_manager_presencestate,,)) +$(eval $(call BuildAsteriskModule,res-monitor,PBX channel monitoring,Call monitoring resource.,,,res_monitor,,)) +$(eval $(call BuildAsteriskModule,res-musiconhold,MOH,Music On Hold resource.,,musiconhold.conf,res_musiconhold,,)) +$(eval $(call BuildAsteriskModule,res-mutestream,Mute audio stream resources,Mute audio stream resources.,,,res_mutestream,,)) +$(eval $(call BuildAsteriskModule,res-mwi-devstate,MWI device state subs,This module allows presence subscriptions to voicemail boxes. This\nallows common BLF keys to act as voicemail waiting indicators.,,,res_mwi_devstate,,)) +$(eval $(call BuildAsteriskModule,res-mwi-external,Core external MWI resource,Core external MWI resource.,,,res_mwi_external,,)) +$(eval $(call BuildAsteriskModule,res-mwi-external-ami,AMI for external MWI,AMI support for external MWI.,+$(PKG_NAME)-res-mwi-external,,res_mwi_external_ami,,)) +$(eval $(call BuildAsteriskModule,res-parking,Phone Parking,Call parking resource.,+$(PKG_NAME)-bridge-holding,res_parking.conf,res_parking,,)) +$(eval $(call BuildAsteriskModule,res-phoneprov,Phone Provisioning,HTTP phone provisioning.,,phoneprov.conf,res_phoneprov,,)) +$(eval $(call BuildAsteriskModule,res-pjsip-aoc,PJSIP AOC,PJSIP AOC Support.,+asterisk-pjsip +asterisk-res-pjproject,,res_pjsip_aoc,,)) +$(eval $(call BuildAsteriskModule,res-pjsip-geolocation,PJSIP Geolocation,PJSIP Geolocation support.,+asterisk-pjsip +asterisk-res-geolocation,,res_pjsip_geolocation,,)) +$(eval $(call BuildAsteriskModule,res-pjsip-phoneprov,PJSIP Phone Provisioning,PJSIP phone provisioning.,+$(PKG_NAME)-pjsip +$(PKG_NAME)-res-phoneprov,,res_pjsip_phoneprov_provider,,)) +$(eval $(call BuildAsteriskModule,res-pjsip-rfc3329,PJSIP RFC3329,PJSIP RFC3329 Support (partial).,+asterisk-pjsip +asterisk-res-pjproject,,res_pjsip_rfc3329,,)) +$(eval $(call BuildAsteriskModule,res-pjsip-stir-shaken,PJSIP STIR/SHAKEN resource module,PJSIP STIR/SHAKEN resource module.,+$(PKG_NAME)-pjsip +$(PKG_NAME)-res-stir-shaken,,res_pjsip_stir_shaken,,)) +$(eval $(call BuildAsteriskModule,res-pjproject,Bridge PJPROJECT to Asterisk logging,PJProject log and utility support.,+asterisk-res-sorcery +libpj +libpjlib-util +libpjmedia +libpjmedia +libpjnath +libpjsip-simple +libpjsip-ua +libpjsip +libpjsua +libpjsua2,pjproject.conf,res_pjproject,,)) +$(eval $(call BuildAsteriskModule,res-pktccops,PktcCOPS manager for MGCP,PktcCOPS manager for MGCP.,,res_pktccops.conf,res_pktccops,,)) +$(eval $(call BuildAsteriskModule,res-prometheus,Prometheus resource module,Prometheus resource module.,+libpjsip +libpjmedia +libpjnath +libpjsip-simple +libpjsip-ua +libpjsua +libpjsua2,prometheus.conf,res_prometheus,,)) +$(eval $(call BuildAsteriskModule,res-realtime,RealTime CLI,Realtime data lookup/rewrite.,,,res_realtime,,)) +$(eval $(call BuildAsteriskModule,res-remb-modifier,REMB modifier,REMB modifier module.,,,res_remb_modifier,,)) +$(eval $(call BuildAsteriskModule,res-resolver-unbound,Unbound DNS resolver,Unbound DNS resolver support.,+libunbound,resolver_unbound.conf,res_resolver_unbound,,)) +$(eval $(call BuildAsteriskModule,res-rtp-asterisk,RTP stack,Asterisk RTP stack.,+libpjsip +libpjmedia +libpjnath +libpjsip-simple +libpjsip-ua +libpjsua +libpjsua2,rtp.conf,res_rtp_asterisk,,)) +$(eval $(call BuildAsteriskModule,res-rtp-multicast,RTP multicast engine,Multicast RTP engine.,,,res_rtp_multicast,,)) +$(eval $(call BuildAsteriskModule,res-security-log,Security event logging,Security event logging.,,,res_security_log,,)) +$(eval $(call BuildAsteriskModule,res-smdi,Provide SMDI,Simplified Message Desk Interface resource.,,smdi.conf,res_smdi,,)) +$(eval $(call BuildAsteriskModule,res-snmp,SNMP [Sub]Agent for Asterisk,SNMP agent for Asterisk.,+libnetsnmp,res_snmp.conf,res_snmp,,)) +$(eval $(call BuildAsteriskModule,res-sorcery,Sorcery data layer,Sorcery backend modules for data access intended for using realtime as\nbackend.,,sorcery.conf,res_sorcery_astdb res_sorcery_config res_sorcery_memory res_sorcery_realtime,,)) +$(eval $(call BuildAsteriskModule,res-sorcery-memory-cache,Sorcery memory cache object wizard,Sorcery memory cache object wizard.,,,res_sorcery_memory_cache,,)) +$(eval $(call BuildAsteriskModule,res-speech,Speech Recognition API,Generic speech recognition API.,,,res_speech,,)) +$(eval $(call BuildAsteriskModule,res-speech-aeap,AEAP Speech Engine,AEAP Speech Engine support.,+asterisk-res-aeap +asterisk-res-speech,,res_speech_aeap,,)) +$(eval $(call BuildAsteriskModule,res-srtp,SRTP Support,Secure RTP.,+libsrtp2,,res_srtp,,)) +$(eval $(call BuildAsteriskModule,res-stasis,Stasis application,Stasis application support.,,,res_stasis,,)) +$(eval $(call BuildAsteriskModule,res-stasis-answer,Stasis application answer,Stasis application answer support.,+$(PKG_NAME)-res-stasis,,res_stasis_answer,,)) +$(eval $(call BuildAsteriskModule,res-stasis-device-state,Stasis application device state,Stasis application device state support.,+$(PKG_NAME)-res-stasis,,res_stasis_device_state,,)) +$(eval $(call BuildAsteriskModule,res-stasis-mailbox,Stasis application mailbox,Stasis application mailbox support.,+$(PKG_NAME)-res-stasis +$(PKG_NAME)-res-mwi-external,,res_stasis_mailbox,,)) +$(eval $(call BuildAsteriskModule,res-stasis-playback,Stasis application playback,Stasis application playback support.,+$(PKG_NAME)-res-stasis-recording,,res_stasis_playback,,)) +$(eval $(call BuildAsteriskModule,res-stasis-recording,Stasis application recording,Stasis application recording support.,+$(PKG_NAME)-res-stasis,,res_stasis_recording,,)) +$(eval $(call BuildAsteriskModule,res-stasis-snoop,Stasis application snoop,Stasis application snoop support.,+$(PKG_NAME)-res-stasis-recording,,res_stasis_snoop,,)) +$(eval $(call BuildAsteriskModule,res-statsd,statsd client,Statsd client support.,,statsd.conf,res_statsd,,)) +$(eval $(call BuildAsteriskModule,res-stir-shaken,STIR/SHAKEN resource module,STIR/SHAKEN resource module.,+$(PKG_NAME)-curl,stir_shaken.conf,res_stir_shaken,,)) +$(eval $(call BuildAsteriskModule,res-stun-monitor,STUN monitoring,STUN network monitor.,,res_stun_monitor.conf,res_stun_monitor,,)) +$(eval $(call BuildAsteriskModule,res-timing-dahdi,DAHDI Timing Interface,DAHDI timing interface.,+$(PKG_NAME)-chan-dahdi,,res_timing_dahdi,,)) +$(eval $(call BuildAsteriskModule,res-timing-pthread,pthread Timing Interface,pthread timing interface.,,,res_timing_pthread,,)) +$(eval $(call BuildAsteriskModule,res-tonedetect,Tone detection,Tone detection module.,,,res_tonedetect,,)) +$(eval $(call BuildAsteriskModule,res-xmpp,XMPP client and component module,Asterisk XMPP interface.,+libiksemel +libopenssl,xmpp.conf,res_xmpp,,)) + +################################ +# AST utils +# Params: +# 1 - Utility name +# 2 - Description +# 3 - Dependencies +# 4 - Configuration files +################################ +# $(eval $(call BuildAsteriskUtil,Utility,Description,Dependencies,Configuration Files)) + +$(eval $(call BuildAsteriskUtil,aelparse,Check extensions.ael file.,+$(PKG_NAME)-pbx-ael,)) +$(eval $(call BuildAsteriskUtil,astcanary,Assures Asterisk no threads have gone missing.,,)) +$(eval $(call BuildAsteriskUtil,astdb2sqlite3,Convert astdb to SQLite 3.,,)) +$(eval $(call BuildAsteriskUtil,astdb2bdb,Convert astdb back to Berkeley DB 1.86.,,)) +$(eval $(call BuildAsteriskUtil,check_expr,Expression checker [older version].,,)) +$(eval $(call BuildAsteriskUtil,check_expr2,Expression checker [newer version].,,)) +$(eval $(call BuildAsteriskUtil,smsq,Send messages from command line.,+libpopt,)) +$(eval $(call BuildAsteriskUtil,stereorize,Merge two mono WAV-files to one stereo WAV-file.,,)) +$(eval $(call BuildAsteriskUtil,streamplayer,A utility for reading from a raw TCP stream [MOH source].,,)) diff --git a/net/asterisk/files/asterisk.conf b/net/asterisk/files/asterisk.conf new file mode 100644 index 000000000..d6d461c46 --- /dev/null +++ b/net/asterisk/files/asterisk.conf @@ -0,0 +1,16 @@ +# The init script will create below default directories automatically. +# In case you change these paths in your Asterisk configuration, make +# sure that your directories exist and have the appropriate permissions +# (Asterisk will use the user "asterisk", not root). + +# dbdir => '/var/lib/asterisk/astdb' +# logdir => '/var/log/asterisk' +# rundir => '/var/run/asterisk' +# spooldir => '/var/spool/asterisk' +# varlibdir => '/var/lib/asterisk' + +config asterisk 'general' + option enabled '0' + option log_stderr '1' + option log_stdout '0' + option options '' diff --git a/net/asterisk/files/asterisk.init b/net/asterisk/files/asterisk.init new file mode 100644 index 000000000..51ab25949 --- /dev/null +++ b/net/asterisk/files/asterisk.init @@ -0,0 +1,67 @@ +#!/bin/sh /etc/rc.common +# Copyright (C) 2014 OpenWrt.org + +START=99 + +USE_PROCD=1 + +#PROCD_DEBUG=1 + +NAME=asterisk +COMMAND=/usr/sbin/$NAME + +LOGGER="/usr/bin/logger -p daemon.err -s -t $NAME --" + +start_service() { + + dbdir=/var/lib/asterisk/astdb + logdir=/var/log/asterisk + cdrcsvdir=$logdir/cdr-csv + rundir=/var/run/asterisk + spooldir=/var/spool/asterisk + varlibdir=/var/lib/asterisk + + config_load $NAME + + config_get_bool enabled general enabled 0 + if [ $enabled -eq 0 ]; then + $LOGGER service not enabled in /etc/config/$NAME + return 1 + fi + + config_get_bool log_stderr general log_stderr 1 + config_get_bool log_stdout general log_stdout 0 + + config_get options general options + + for i in \ + "$logdir" \ + "$cdrcsvdir" \ + "$rundir" \ + "$spooldir" \ + "$varlibdir" \ + "$dbdir" + do + if ! [ -e "$i" ]; then + mkdir -m 0750 -p "$i" + [ -d "$i" ] && chown $NAME:$NAME "$i" + fi + done + + procd_open_instance + procd_set_param command $COMMAND + procd_append_param command \ + -U "$NAME" \ + $options \ + -f + # forward stderr to logd + procd_set_param stderr $log_stderr + # same for stdout + procd_set_param stdout $log_stdout + procd_close_instance + +} + +reload_service() { + procd_send_signal $NAME +} diff --git a/net/asterisk/patches/030-GNU-GLOB-exts-only-on-glibc.patch b/net/asterisk/patches/030-GNU-GLOB-exts-only-on-glibc.patch new file mode 100644 index 000000000..0dad20366 --- /dev/null +++ b/net/asterisk/patches/030-GNU-GLOB-exts-only-on-glibc.patch @@ -0,0 +1,22 @@ +--- a/res/ael/ael.flex ++++ b/res/ael/ael.flex +@@ -598,7 +598,7 @@ includes { STORE_POS; return KW_INCLUDES + snprintf(fnamebuf2,sizeof(fnamebuf2), "%s/%s", (char *)ast_config_AST_CONFIG_DIR, fnamebuf); + ast_copy_string(fnamebuf,fnamebuf2,sizeof(fnamebuf)); + } +-#ifdef SOLARIS ++#if !defined(HAVE_GLOB_NOMAGIC) || !defined(HAVE_GLOB_BRACE) || defined(DEBUG_NONGNU) + glob_ret = glob(fnamebuf, GLOB_NOCHECK, NULL, &globbuf); + #else + glob_ret = glob(fnamebuf, GLOB_NOMAGIC|GLOB_BRACE, NULL, &globbuf); +--- a/res/ael/ael_lex.c ++++ b/res/ael/ael_lex.c +@@ -1966,7 +1966,7 @@ YY_RULE_SETUP + snprintf(fnamebuf2,sizeof(fnamebuf2), "%s/%s", (char *)ast_config_AST_CONFIG_DIR, fnamebuf); + ast_copy_string(fnamebuf,fnamebuf2,sizeof(fnamebuf)); + } +-#ifdef SOLARIS ++#if !defined(HAVE_GLOB_NOMAGIC) || !defined(HAVE_GLOB_BRACE) || defined(DEBUG_NONGNU) + glob_ret = glob(fnamebuf, GLOB_NOCHECK, NULL, &globbuf); + #else + glob_ret = glob(fnamebuf, GLOB_NOMAGIC|GLOB_BRACE, NULL, &globbuf); diff --git a/net/asterisk/patches/053-musl-mutex-init.patch b/net/asterisk/patches/053-musl-mutex-init.patch new file mode 100644 index 000000000..98cdccf3d --- /dev/null +++ b/net/asterisk/patches/053-musl-mutex-init.patch @@ -0,0 +1,11 @@ +--- a/include/asterisk/lock.h ++++ b/include/asterisk/lock.h +@@ -66,7 +66,7 @@ + #define AST_PTHREADT_NULL (pthread_t) -1 + #define AST_PTHREADT_STOP (pthread_t) -2 + +-#if (defined(SOLARIS) || defined(BSD)) ++#if (defined(SOLARIS) || defined(BSD) || !defined(HAVE_PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP)) + #define AST_MUTEX_INIT_W_CONSTRUCTORS + #endif /* SOLARIS || BSD */ + diff --git a/net/asterisk/patches/100-build-reproducibly.patch b/net/asterisk/patches/100-build-reproducibly.patch new file mode 100644 index 000000000..f16421b4a --- /dev/null +++ b/net/asterisk/patches/100-build-reproducibly.patch @@ -0,0 +1,28 @@ +--- a/build_tools/make_build_h ++++ b/build_tools/make_build_h +@@ -5,6 +5,14 @@ MACHINE=`uname -m | sed 's/\\\\/\\\\\\\ + OS=`uname -s` + USER=`id | awk -F")" '{print $1}'| awk -F"(" '{print $2}' | sed 's/\\\\/\\\\\\\\/g'` + DATE=`date -u "+%Y-%m-%d %H:%M:%S"` ++if [ -n "${SOURCE_DATE_EPOCH}" ]; then ++ # building reproducibly, faking some data ++ HOSTNAME='openwrt.org' ++ KERNEL='unknown' ++ MACHINE='unknown' ++ USER='nobody' ++ DATE=`date -u "+%Y-%m-%d %H:%M:%S" -d @${SOURCE_DATE_EPOCH}` ++fi + cat << END + /* + * build.h +--- a/build_tools/make_xml_documentation ++++ b/build_tools/make_xml_documentation +@@ -187,7 +187,7 @@ printf "Building Documentation For: " + for subdir in ${mod_subdirs} ; do + printf "%s " "${subdir}" + subdir_path="${source_tree}/${subdir}" +- for i in $(${FIND} "${subdir_path}" -name '*.c' -or -name '*.cc'); do ++ for i in $(${FIND} "${subdir_path}" -name '*.c' -or -name '*.cc' | LC_ALL=C sort); do + if [ "${with_moduleinfo}" -eq "1" ] ; then + MODULEINFO=$(${AWK} -f "${source_tree}/build_tools/get_moduleinfo" "${i}") + if [ "${MODULEINFO}" != "" ] ; then diff --git a/net/asterisk/patches/110-fix-astmm.patch b/net/asterisk/patches/110-fix-astmm.patch new file mode 100644 index 000000000..1d779010d --- /dev/null +++ b/net/asterisk/patches/110-fix-astmm.patch @@ -0,0 +1,10 @@ +--- a/include/asterisk/compat.h ++++ b/include/asterisk/compat.h +@@ -30,6 +30,7 @@ + #include + #include + #include ++#include + + #ifdef HAVE_STDDEF_H + #include diff --git a/net/asterisk/patches/130-eventfd.patch b/net/asterisk/patches/130-eventfd.patch new file mode 100644 index 000000000..60e7d26b4 --- /dev/null +++ b/net/asterisk/patches/130-eventfd.patch @@ -0,0 +1,11 @@ +--- a/configure.ac ++++ b/configure.ac +@@ -1257,7 +1257,7 @@ if test "${ac_cv_have_variable_fdset}x" + fi + + AC_MSG_CHECKING([if we have usable eventfd support]) +-AC_RUN_IFELSE( ++AC_LINK_IFELSE( + [AC_LANG_PROGRAM([#include ], + [return eventfd(0, EFD_NONBLOCK | EFD_SEMAPHORE) == -1;])], + AC_MSG_RESULT(yes) diff --git a/net/asterisk/patches/140-use-default-lua.patch b/net/asterisk/patches/140-use-default-lua.patch new file mode 100644 index 000000000..006a07fff --- /dev/null +++ b/net/asterisk/patches/140-use-default-lua.patch @@ -0,0 +1,11 @@ +--- a/configure.ac ++++ b/configure.ac +@@ -2608,7 +2608,7 @@ if test -z "$__opus_include" -o x"$__opu + fi + AST_EXT_LIB_CHECK([OPUSFILE], [opusfile], [op_open_callbacks], [opus/opusfile.h], [], [$__opus_include]) + +-for ver in ${LUA_VERSIONS:-5.4 5.3 5.2 5.1}; do ++for ver in ${LUA_VERSIONS}; do + AST_EXT_LIB_CHECK([LUA], lua${ver}, [luaL_newstate], lua${ver}/lua.h, [-lm]) + if test "x${PBX_LUA}" = "x1" ; then + if test x"${LUA_DIR}" = x; then diff --git a/net/asterisk/patches/150-musl-12x.patch b/net/asterisk/patches/150-musl-12x.patch new file mode 100644 index 000000000..08441be43 --- /dev/null +++ b/net/asterisk/patches/150-musl-12x.patch @@ -0,0 +1,35 @@ +--- a/include/asterisk/compat.h ++++ b/include/asterisk/compat.h +@@ -130,14 +130,16 @@ void timersub(struct timeval *tvend, str + + #include + +-#ifdef SOLARIS ++#ifndef __BEGIN_DECLS + #define __BEGIN_DECLS + #define __END_DECLS ++#endif + + #ifndef __P + #define __P(p) p + #endif + ++#ifdef SOLARIS + #include + #include + #include +--- a/utils/db1-ast/include/db.h ++++ b/utils/db1-ast/include/db.h +@@ -68,8 +68,11 @@ typedef unsigned long long u_int64_t; + #endif /* __FreeBSD__ */ + #endif + +-#ifdef SOLARIS ++#ifndef __P + #define __P(p) p ++#endif ++ ++#ifndef __BEGIN_DECLS + #define __BEGIN_DECLS + #define __END_DECLS + #endif diff --git a/net/asterisk/patches/160-AST_EXT_TOOL_CHECK.patch b/net/asterisk/patches/160-AST_EXT_TOOL_CHECK.patch new file mode 100644 index 000000000..97c9d35c7 --- /dev/null +++ b/net/asterisk/patches/160-AST_EXT_TOOL_CHECK.patch @@ -0,0 +1,22 @@ +--- a/autoconf/ast_ext_tool_check.m4 ++++ b/autoconf/ast_ext_tool_check.m4 +@@ -8,13 +8,16 @@ AC_DEFUN([AST_EXT_TOOL_CHECK], + AC_REQUIRE([AST_PROG_SED])dnl + if test "x${PBX_$1}" != "x1" -a "${USE_$1}" != "no"; then + PBX_$1=0 +- AC_PATH_TOOL(CONFIG_$1, $2, No, [${$1_DIR}/bin:$PATH]) ++ if test "x${$1_DIR}" != "x"; then ++ AC_PATH_TOOL(CONFIG_$1, $2, No, [${$1_DIR}/bin:$PATH]) ++ else ++ AC_PATH_TOOL(CONFIG_$1, $2, No, [$PATH]) ++ fi + if test ! "x${CONFIG_$1}" = xNo; then + $1_INCLUDE=$(${CONFIG_$1} m4_default([$3],[--cflags])) +- $1_INCLUDE=$(echo ${$1_INCLUDE} | $SED -e "s|-I|-I${$1_DIR}|g" -e "s|-std=c99||g") ++ $1_INCLUDE=$(echo ${$1_INCLUDE} | $SED -e "s|-std=c99||g") + + $1_LIB=$(${CONFIG_$1} m4_default([$4],[--libs])) +- $1_LIB=$(echo ${$1_LIB} | $SED -e "s|-L|-L${$1_DIR}|g") + + m4_ifval([$5], [ + saved_cppflags="${CPPFLAGS}" diff --git a/net/asterisk/patches/170-menuselect-force-use-of-xml2-config.patch b/net/asterisk/patches/170-menuselect-force-use-of-xml2-config.patch new file mode 100644 index 000000000..486a1a548 --- /dev/null +++ b/net/asterisk/patches/170-menuselect-force-use-of-xml2-config.patch @@ -0,0 +1,17 @@ +Since commit dc701d6 in the OpenWrt packages repo the host libxml2 package +provides a static lib only. But Asterisk does not check that and calls +pkg-config without "--static". The result is that menuselect doesn't build. + +So don't use pkg-config for the libxml2 detection. Asterisk will resort to +use xml2-config, which outputs all the flags needed. + +--- a/menuselect/configure.ac ++++ b/menuselect/configure.ac +@@ -91,7 +91,6 @@ else + AST_EXT_LIB_CHECK([TINFO], [tinfo], [keypad], [curses.h]) + fi + +-AST_PKG_CONFIG_CHECK([LIBXML2], [libxml-2.0]) + AST_EXT_TOOL_CHECK([LIBXML2], [xml2-config], , , + [#include + #include ], diff --git a/net/asterisk/patches/180-app_queue_time_t.patch b/net/asterisk/patches/180-app_queue_time_t.patch new file mode 100644 index 000000000..d582a3940 --- /dev/null +++ b/net/asterisk/patches/180-app_queue_time_t.patch @@ -0,0 +1,17 @@ +--- a/apps/app_queue.c ++++ b/apps/app_queue.c +@@ -4614,8 +4614,12 @@ static int is_longest_waiting_caller(str + * will be unused until the first caller is picked up. + */ + if (ch->start < caller->start && !ch->pending) { +- ast_debug(1, "Queue %s has a call at position %i that's been waiting longer (%li vs %li)\n", +- q->name, ch->pos, ch->start, caller->start); ++ char time1[AST_TIME_T_LEN]; ++ char time2[AST_TIME_T_LEN]; ++ ast_time_t_to_string(ch->start, time1, sizeof(time1)); ++ ast_time_t_to_string(caller->start, time2, sizeof(time2)); ++ ast_debug(1, "Queue %s has a call at position %i that's been waiting longer (%s vs %s)\n", ++ q->name, ch->pos, time1, time2); + is_longest_waiting = 0; + break; + } diff --git a/net/baresip/Makefile b/net/baresip/Makefile new file mode 100644 index 000000000..a377d8e5e --- /dev/null +++ b/net/baresip/Makefile @@ -0,0 +1,252 @@ +# +# Copyright (C) 2010-2017 OpenWrt.org +# Copyright (C) 2010 Alfred E. Heggestad +# +# This is free software, licensed under the GNU General Public License v2. +# See /LICENSE for more information. +# + +include $(TOPDIR)/rules.mk + +PKG_NAME:=baresip +PKG_VERSION:=1.1.0 +PKG_RELEASE:=6 + +PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.gz +PKG_SOURCE_URL:=https://codeload.github.com/baresip/baresip/tar.gz/v$(PKG_VERSION)? +PKG_HASH:=f9230b27c4a62f31223847bc485c51f3d960f8a09f36998dedb73358e1784b4e + +PKG_LICENSE:=BSD-3-Clause +PKG_LICENSE_FILES:=docs/COPYING +PKG_MAINTAINER:=Jiri Slachta + +PKG_BUILD_PARALLEL:=1 +PKG_INSTALL:=1 + +baresip-mods:= \ + aac \ + alsa \ + amr \ + avcodec \ + avfilter \ + avformat \ + cons \ + ctrl-dbus \ + evdev \ + g711 \ + g722 \ + g726 \ + gst \ + gst-video \ + httpreq \ + l16 \ + mqtt \ + opus \ + opus_multistream \ + oss \ + plc \ + portaudio \ + pulse \ + snapshot \ + sndfile \ + speex-pp \ + srtp \ + stdio \ + syslog \ + v4l2 \ + vp8 \ + vp9 + +PKG_CONFIG_DEPENDS:= \ + $(patsubst %,CONFIG_PACKAGE_baresip-mod-%,$(subst _,-,$(baresip-mods))) + +include $(INCLUDE_DIR)/package.mk +include $(INCLUDE_DIR)/nls.mk + +define Package/baresip/Default + SECTION:=net + CATEGORY:=Network + SUBMENU:=Telephony + URL:=https://github.com/baresip/baresip +endef + +define Package/baresip +$(call Package/baresip/Default) + TITLE:=Portable and modular SIP User-Agent with A/V support + DEPENDS:=+libre +librem + USERID:=$(PKG_NAME)=374:$(PKG_NAME)=374 + MENU:=1 + FILE_MODES:= \ + /etc/baresip:baresip:baresip:0750 \ + /etc/baresip/accounts:baresip:baresip:0640 \ + /etc/baresip/config:baresip:baresip:0640 \ + /etc/baresip/contacts:baresip:baresip:0640 +endef + +baresip-mod-aac := USE_AAC +baresip-mod-alsa := USE_ALSA +baresip-mod-amr := USE_AMR +baresip-mod-avcodec := USE_AVCODEC +baresip-mod-avfilter := USE_AVFILTER +baresip-mod-avformat := USE_AVFORMAT +baresip-mod-cons := USE_CONS +baresip-mod-ctrl-dbus := HAVE_GLIB USE_DBUS +baresip-mod-evdev := USE_EVDEV +baresip-mod-g711 := USE_G711 +baresip-mod-g722 := USE_G722 +baresip-mod-g726 := USE_G726 +baresip-mod-gst := USE_GST +baresip-mod-gst-video := USE_GST_VIDEO +baresip-mod-httpreq := USE_HTTPREQ +baresip-mod-l16 := USE_L16 +baresip-mod-mqtt := USE_MQTT +baresip-mod-opus := USE_OPUS +baresip-mod-opus_multistream := USE_OPUS_MS +baresip-mod-oss := USE_OSS +baresip-mod-plc := USE_PLC +baresip-mod-portaudio := USE_PORTAUDIO +baresip-mod-pulse := USE_PULSE +baresip-mod-snapshot := USE_SNAPSHOT +baresip-mod-sndfile := USE_SNDFILE +baresip-mod-speex-pp := USE_SPEEX_PP +baresip-mod-srtp := USE_SRTP +baresip-mod-stdio := USE_STDIO +baresip-mod-syslog := USE_SYSLOG +baresip-mod-vp8 := USE_VPX +baresip-mod-vp9 := USE_VPX +baresip-mod-v4l2 := USE_V4L2 + +BARESIP_MOD_OPTIONS:= \ + MOD_AUTODETECT= \ + $(foreach m,$(baresip-mods),$(foreach v,$(baresip-mod-$(m)),$(v)=$(if $(CONFIG_PACKAGE_baresip-mod-$(subst _,-,$(m))),1))) + +MAKE_FLAGS+= \ + CROSS_COMPILE="$(TARGET_CROSS)" \ + DESTDIR="$(PKG_INSTALL_DIR)" \ + EXTRA_LFLAGS="$(TARGET_LDFLAGS)" \ + LD="$(TARGET_CC)" \ + LIBRE_MK="$(STAGING_DIR)/usr/share/re/re.mk" \ + LIBRE_INC="$(STAGING_DIR)/usr/include/re" \ + LIBRE_SO="$(STAGING_DIR)/usr/lib" \ + LIBREM_PATH="$(STAGING_DIR)/usr" \ + OS=linux \ + RELEASE=1 \ + SYSROOT="$(shell $(FIND) $(TOOLCHAIN_DIR) -path '*/include/pthread.h' | sed -ne '1s|/include/pthread.h||p')" \ + SYSROOT_ALT="$(STAGING_DIR)/usr" \ + $(BARESIP_MOD_OPTIONS) + +TARGET_CFLAGS+=-D_GNU_SOURCE + +define Package/baresip/install + $(INSTALL_DIR) $(1)/usr/bin + $(INSTALL_BIN) $(PKG_INSTALL_DIR)/usr/bin/baresip $(1)/usr/bin + $(INSTALL_DIR) $(1)/usr/lib/baresip/modules + $(INSTALL_DATA) \ + $(PKG_INSTALL_DIR)/usr/lib/baresip/modules/{account,auloop,contact,ice,menu,stun,turn}.so \ + $(1)/usr/lib/baresip/modules + $(INSTALL_DIR) $(1)/usr/share/baresip + $(INSTALL_DATA) $(PKG_INSTALL_DIR)/usr/share/baresip/* $(1)/usr/share/baresip + $(INSTALL_DIR) $(1)/etc/baresip + $(SED) '/^#/!s/^/#/' $(PKG_BUILD_DIR)/docs/examples/accounts + $(SED) '/^#module_path/s|^#||;s|/local||' $(PKG_BUILD_DIR)/docs/examples/config + $(INSTALL_DATA) $(PKG_BUILD_DIR)/docs/examples/{accounts,config,contacts} $(1)/etc/baresip + $(INSTALL_DIR) $(1)/etc/default + $(INSTALL_CONF) ./files/baresip.default $(1)/etc/default/baresip + $(INSTALL_DIR) $(1)/etc/init.d + $(INSTALL_BIN) ./files/baresip.init $(1)/etc/init.d/baresip +endef + +define Package/baresip/conffiles +/etc/baresip/accounts +/etc/baresip/config +/etc/baresip/contacts +/etc/default/baresip +/etc/init.d/baresip +endef + +################## +# bareSIP modules +# 1. Name +# 2. Title +# 3. Files +# 4. Dependencies +################## + +define BuildPlugin + + define Package/baresip-mod-$(subst _,-,$(1)) + $$(call Package/baresip/Default) + TITLE:=$(2) + DEPENDS:=baresip $(patsubst +%,+PACKAGE_$(PKG_NAME)-mod-$(subst _,-,$(1)):%,$(4)) + endef + + define Package/baresip-mod-$(subst _,-,$(1))/install + [ -z "$(3)" ] || $(INSTALL_DIR) $$(1)/usr/lib/baresip/modules + for f in $(3); do \ + $(INSTALL_DATA) \ + $(PKG_INSTALL_DIR)/usr/lib/baresip/modules/$$$$$$$${f}.so \ + $$(1)/usr/lib/baresip/modules; \ + done + endef + + $$(eval $$(call BuildPackage,baresip-mod-$(subst _,-,$(1)))) +endef + +$(eval $(call BuildPackage,baresip)) + +$(eval $(call BuildPlugin,aac,MPEG-4 AAC Audio Codec,aac,+fdk-aac)) +$(eval $(call BuildPlugin,alsa,ALSA audio driver,alsa,+alsa-lib)) +$(eval $(call BuildPlugin,amr,Adaptive Multi-Rate [AMR] audio codec,amr,)) +$(eval $(call BuildPlugin,aubridge,Audio bridge module,aubridge,)) +$(eval $(call BuildPlugin,aufile,Audio module for using a WAV-file as audio input,aufile,)) +$(eval $(call BuildPlugin,ausine,Sine Audio Source,ausine,)) +$(eval $(call BuildPlugin,avcodec,Video codec using FFmpeg,avcodec,+libffmpeg-full)) +$(eval $(call BuildPlugin,avformat,Video source using FFmpeg,avformat,baresip-mod-avcodec)) +$(eval $(call BuildPlugin,b2bua,Back-to-Back User-Agent module,b2bua,)) +$(eval $(call BuildPlugin,cons,UDP/TCP console UI driver,cons,)) +$(eval $(call BuildPlugin,ctrl_dbus,DBus control interface,ctrl_dbus,+glib2)) +$(eval $(call BuildPlugin,ctrl_tcp,TCP control interface,ctrl_tcp,)) +$(eval $(call BuildPlugin,debug_cmd,Debug commands,debug_cmd,)) +$(eval $(call BuildPlugin,dtls_srtp,DTLS-SRTP end-to-end encryption,dtls_srtp,)) +$(eval $(call BuildPlugin,ebuacip,EBU ACIP [Audio Contribution over IP] Profile,ebuacip,)) +$(eval $(call BuildPlugin,echo,Echo server module,echo,)) +$(eval $(call BuildPlugin,evdev,Linux input driver,evdev,)) +$(eval $(call BuildPlugin,fakevideo,Fake video input/output driver,fakevideo,)) +$(eval $(call BuildPlugin,g711,G.711 audio codec,g711,)) +$(eval $(call BuildPlugin,g722,G.722 audio codec,g722,+libspandsp)) +$(eval $(call BuildPlugin,g726,G.726 audio codec,g726,+libspandsp)) +$(eval $(call BuildPlugin,gst,Gstreamer 1.0 playbin pipeline,gst,@AUDIO_SUPPORT +glib2 +libgstreamer1)) +$(eval $(call BuildPlugin,gst_video,Video codecs using Gstreamer 1.0,gst_video,@AUDIO_SUPPORT +glib2 +libgst1app +libgstreamer1)) +$(eval $(call BuildPlugin,httpd,HTTP webserver UI-module,httpd,)) +$(eval $(call BuildPlugin,httpreq,HTTP request module,httpreq,)) +$(eval $(call BuildPlugin,l16,16-bit linear codec,l16,)) +$(eval $(call BuildPlugin,mixausrc,Mixes another audio source into audio stream,mixausrc,)) +$(eval $(call BuildPlugin,mqtt,Message Queue Telemetry Transport [MQTT] client,mqtt,+libmosquitto)) +$(eval $(call BuildPlugin,multicast,Multicast support,multicast,)) +$(eval $(call BuildPlugin,mwi,Message Waiting Indication,mwi,)) +$(eval $(call BuildPlugin,natpmp,NAT Port Mapping Protocol module,natpmp,)) +$(eval $(call BuildPlugin,opus,OPUS Interactive audio codec,opus,+libopus)) +$(eval $(call BuildPlugin,opus_multistream,Opus Multistream Audio Codec,opus_multistream,+libopus)) +$(eval $(call BuildPlugin,oss,OSS audio driver,oss,)) +$(eval $(call BuildPlugin,plc,Packet Loss Concealment,plc,+libspandsp)) +$(eval $(call BuildPlugin,portaudio,Portaudio audio driver,portaudio,+portaudio)) +$(eval $(call BuildPlugin,presence,Presence module,presence,)) +$(eval $(call BuildPlugin,pulse,Pulseaudio audio driver,pulse,PACKAGE_$(PKG_NAME)-mod-pulse:pulseaudio)) +$(eval $(call BuildPlugin,rtcpsummary,RTCP summary module,rtcpsummary,)) +$(eval $(call BuildPlugin,selfview,Video selfview module,selfview,)) +$(eval $(call BuildPlugin,serreg,Serial registration mode,serreg,)) +$(eval $(call BuildPlugin,snapshot,Snapshot video module,snapshot,+libpng)) +$(eval $(call BuildPlugin,sndfile,Audio dumper using libsndfile,sndfile,+libsndfile)) +$(eval $(call BuildPlugin,speex_pp,Speex Pre-processor,speex_pp,+libspeexdsp)) +$(eval $(call BuildPlugin,srtp,Secure RTP module using libre,srtp,)) +$(eval $(call BuildPlugin,stdio,Standard input/output UI driver,stdio,)) +$(eval $(call BuildPlugin,syslog,Syslog module,syslog,)) +$(eval $(call BuildPlugin,uuid,UUID generator and loader,uuid,)) +$(eval $(call BuildPlugin,v4l2,Video4Linux2 video source,v4l2,+libv4l)) +$(eval $(call BuildPlugin,v4l2_codec,Video4Linux2 video codec module,v4l2_codec,)) +$(eval $(call BuildPlugin,vidbridge,Video bridge module,vidbridge,)) +$(eval $(call BuildPlugin,vidinfo,Video-info filter,vidinfo,)) +$(eval $(call BuildPlugin,vidloop,Video-loop test module,vidloop,)) +$(eval $(call BuildPlugin,vumeter,Display audio levels in console,vumeter,)) +$(eval $(call BuildPlugin,vp8,VP8 video codec,vp8,+libvpx)) +$(eval $(call BuildPlugin,vp9,VP9 video codec,vp9,+libvpx)) diff --git a/net/baresip/files/baresip.default b/net/baresip/files/baresip.default new file mode 100644 index 000000000..b251c80e7 --- /dev/null +++ b/net/baresip/files/baresip.default @@ -0,0 +1,10 @@ +### bareSIP init configuration ### + +# Uncomment once you verified your configuration, otherwise the init script will +# not start bareSIP. +#ENABLE_BARESIP="yes" + +# The following is added to the command line when starting bareSIP: +OPTIONS="" + +# The configuration for the daemon is done in /etc/baresip! diff --git a/net/baresip/files/baresip.init b/net/baresip/files/baresip.init new file mode 100644 index 000000000..d48e5d60f --- /dev/null +++ b/net/baresip/files/baresip.init @@ -0,0 +1,39 @@ +#!/bin/sh /etc/rc.common +# Copyright (C) 2017 OpenWrt.org + +START=92 + +USE_PROCD=1 + +#PROCD_DEBUG=1 + +DAEMON=baresip +DEFAULT=/etc/default/$DAEMON +LOGGER="/usr/bin/logger -p user.err -s -t $DAEMON" +OPTIONS= +PROG=/usr/bin/$DAEMON + +[ -f $DEFAULT ] && . $DEFAULT + +start_service() { + local dir= + + if [ "$ENABLE_BARESIP" != yes ]; then + $LOGGER User configuration incomplete - not starting $DAEMON + $LOGGER Check ENABLE_BARESIP in $DEFAULT + return 1 + fi + + procd_open_instance + procd_set_param command $PROG + procd_append_param command \ + -f /etc/$DAEMON \ + $OPTIONS + procd_set_param pidfile /var/run/${DAEMON}.pid + # forward stderr to logd + procd_set_param stderr 1 + # forward stdout to logd + #procd_set_param stdout 1 + procd_set_param user $DAEMON + procd_close_instance +} diff --git a/net/baresip/patches/010-fix-parallel-build.patch b/net/baresip/patches/010-fix-parallel-build.patch new file mode 100644 index 000000000..25f901315 --- /dev/null +++ b/net/baresip/patches/010-fix-parallel-build.patch @@ -0,0 +1,23 @@ +From d7aeb9393876af3746dacdbacd70c4a5d6dfcf39 Mon Sep 17 00:00:00 2001 +From: Christian Spielberger +Date: Sun, 23 May 2021 10:01:04 +0200 +Subject: [PATCH] ctrl_dbus: add dependency to baresipbus.h (#1447) (#1457) + +--- + modules/ctrl_dbus/module.mk | 5 ++++- + 1 file changed, 4 insertions(+), 1 deletion(-) + +--- a/modules/ctrl_dbus/module.mk ++++ b/modules/ctrl_dbus/module.mk +@@ -16,7 +16,10 @@ $(MOD)_CFLAGS += -Wno-unused-parameter - + + $(MOD)_CCHECK_OPT = -e baresipbus.h -e baresipbus.c + +-modules/ctrl_dbus/baresipbus.h modules/ctrl_dbus/baresipbus.c: \ ++modules/$(MOD)/baresipbus.o : modules/$(MOD)/baresipbus.h ++modules/$(MOD)/ctrl_dbus.o : modules/$(MOD)/baresipbus.h ++ ++modules/$(MOD)/baresipbus.h modules/$(MOD)/baresipbus.c: \ + modules/ctrl_dbus/com.github.Baresip.xml + @cd $(dir $@) && ./gen.sh + diff --git a/net/coturn/Makefile b/net/coturn/Makefile new file mode 100644 index 000000000..ef57cf14e --- /dev/null +++ b/net/coturn/Makefile @@ -0,0 +1,146 @@ +# +# Copyright (C) 2021 Sebastian Kemper +# +# This is free software, licensed under the GNU General Public License v2. +# See /LICENSE for more information. +# + +include $(TOPDIR)/rules.mk + +PKG_NAME:=coturn +PKG_VERSION:=4.6.1 +PKG_RELEASE:=1 + +PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.gz +PKG_SOURCE_URL:=https://codeload.github.com/coturn/coturn/tar.gz/$(PKG_VERSION)? +PKG_HASH:=8fba86e593ed74adc46e002e925cccff2819745371814f42465fbe717483f1d8 + +PKG_LICENSE:=BSD-COTURN-CITRIX COMBINED-CITRIX-VIVOCHA-BSD MIT-HASH +PKG_LICENSE_FILES:=LICENSE src/apps/relay/dbdrivers/* src/server/ns_turn_khash.h + +PKG_MAINTAINER:=Jiri Slachta , Sebastian Kemper + +PKG_BUILD_PARALLEL:=1 + +PKG_INSTALL:=1 + +PKG_CONFIG_DEPENDS+= \ + CONFIG_COTURN_ENABLE_MYSQL \ + CONFIG_COTURN_ENABLE_POSTGRESQL \ + CONFIG_COTURN_ENABLE_REDIS \ + CONFIG_COTURN_ENABLE_SQLITE + +PKG_CPE_ID:=cpe:/a:coturn_project:coturn + +include $(INCLUDE_DIR)/package.mk +include $(INCLUDE_DIR)/nls.mk + +define Package/coturn + TITLE:=coturn TURN and STUN Server + CATEGORY:=Network + SECTION:=net + SUBMENU:=Telephony + URL:=https://github.com/coturn/coturn + USERID:=turnserver=379:turnserver=379 + DEPENDS := \ + +libevent2 \ + +libevent2-extra \ + +libevent2-pthreads \ + +libevent2-openssl \ + +libopenssl \ + +COTURN_ENABLE_MYSQL:libmariadb \ + +COTURN_ENABLE_POSTGRESQL:libpq \ + +COTURN_ENABLE_REDIS:libhiredis \ + +COTURN_ENABLE_SQLITE:libsqlite3 + FILE_MODES:=/etc/turnserver:turnserver:turnserver:0750 +endef + +define Package/coturn/conffiles +/etc/config/turnserver +/etc/init.d/turnserver +/etc/turnserver.conf +/etc/turnserver +endef + +define Package/coturn/config + menu "coturn configuration" + depends on PACKAGE_coturn + + config COTURN_ENABLE_SQLITE + bool "SQLite support" + default y + help + Enable SQLite support + + config COTURN_ENABLE_MYSQL + bool "MySQL support" + default n + help + Enable MySQL support + + config COTURN_ENABLE_POSTGRESQL + bool "PostgreSQL support" + default n + help + Enable PostgreSQL support + + config COTURN_ENABLE_REDIS + bool "Redis support" + default n + help + Enable Redis support + + endmenu +endef + +define Package/coturn/description +The TURN Server is a VoIP media traffic NAT traversal server and +gateway. It can be used as a general-purpose network traffic TURN server +and gateway, too. +endef + +define Package/coturn/install + $(INSTALL_DIR) \ + $(1)/etc/{config,init.d,turnserver} $(1)/usr/{bin,share/coturn} + $(INSTALL_DATA) $(PKG_INSTALL_DIR)/etc/turnserver.conf.default \ + $(1)/etc/turnserver.conf + $(INSTALL_BIN) $(PKG_INSTALL_DIR)/usr/bin/turn* $(1)/usr/bin + $(INSTALL_BIN) ./files/turnserver.init \ + $(1)/etc/init.d/turnserver + $(INSTALL_CONF) ./files/turnserver.conf \ + $(1)/etc/config/turnserver +ifneq ($(CONFIG_COTURN_ENABLE_MYSQL)$(CONFIG_COTURN_ENABLE_POSTGRESQL)$(CONFIG_COTURN_ENABLE_SQLITE),) + $(INSTALL_DATA) \ + $(PKG_INSTALL_DIR)/usr/share/coturn/{schema,testsqldbsetup}.sql \ + $(1)/usr/share/coturn +endif +ifneq ($(CONFIG_COTURN_ENABLE_REDIS),) + $(INSTALL_DATA) \ + $(PKG_INSTALL_DIR)/usr/share/coturn/schema.{stats,userdb}.redis \ + $(1)/usr/share/coturn + $(INSTALL_BIN) $(PKG_INSTALL_DIR)/usr/share/coturn/testredisdbsetup.sh \ + $(1)/usr/share/coturn +endif +endef + +CONFIGURE_ARGS+= \ + --disable-rpath \ + --schemadir=/usr/share/coturn \ + --turndbdir=/etc/turnserver + +CONFIGURE_VARS+= \ + ARCHIVERCMD="$(TARGET_AR) -r" \ + LIBEV_OK=1 \ + TURN_NO_PROMETHEUS=1 \ + TURN_NO_SCTP=1 \ + TURN_NO_SYSTEMD=1 \ + TURN_NO_MONGO=1 \ + $(if $(CONFIG_COTURN_ENABLE_MYSQL),,TURN_NO_MYSQL=1) \ + $(if $(CONFIG_COTURN_ENABLE_POSTGRESQL),,TURN_NO_PQ=1) \ + $(if $(CONFIG_COTURN_ENABLE_REDIS),,TURN_NO_HIREDIS=1) \ + $(if $(CONFIG_COTURN_ENABLE_SQLITE),,TURN_NO_SQLITE=1) + +define Build/InstallDev +endef + +$(eval $(call BuildPackage,coturn)) diff --git a/net/coturn/files/turnserver.conf b/net/coturn/files/turnserver.conf new file mode 100644 index 000000000..d6eec32fb --- /dev/null +++ b/net/coturn/files/turnserver.conf @@ -0,0 +1,6 @@ + +config turnserver 'general' + option enabled '0' + option log_stderr '0' + option log_stdout '0' + option options '--pidfile /var/run/turnserver.pid --log-file syslog --no-cli --proc-user turnserver --proc-group turnserver' diff --git a/net/coturn/files/turnserver.init b/net/coturn/files/turnserver.init new file mode 100755 index 000000000..73bf916d3 --- /dev/null +++ b/net/coturn/files/turnserver.init @@ -0,0 +1,39 @@ +#!/bin/sh /etc/rc.common + +START=90 +STOP=10 + +USE_PROCD=1 + +#PROCD_DEBUG=1 + +NAME=turnserver +COMMAND=/usr/bin/$NAME + +LOGGER="/usr/bin/logger -s -t $NAME" +LOG_ERR="$LOGGER -p daemon.err --" + +start_service() { + + config_load $NAME + + config_get_bool enabled general enabled 0 + if [ $enabled -eq 0 ]; then + $LOG_ERR service not enabled in /etc/config/$NAME + return 1 + fi + + config_get_bool log_stderr general log_stderr 1 + config_get_bool log_stdout general log_stdout 1 + + config_get options general options + + procd_open_instance + procd_set_param command $COMMAND + procd_append_param command $options + # forward stderr to logd + procd_set_param stderr $log_stderr + # same for stdout + procd_set_param stdout $log_stdout + procd_close_instance +} diff --git a/net/coturn/patches/01-includes.patch b/net/coturn/patches/01-includes.patch new file mode 100644 index 000000000..9cd7a7ccd --- /dev/null +++ b/net/coturn/patches/01-includes.patch @@ -0,0 +1,9 @@ +--- a/Makefile.in ++++ b/Makefile.in +@@ -1,5 +1,5 @@ + +-LIBEVENT_INCLUDE = -I${PREFIX}/include/ -I/usr/local/include/ ++LIBEVENT_INCLUDE = + + INCFLAGS = -Isrc -Isrc/apps/common -Isrc/server -Isrc/client -Isrc/client++ ${LIBEVENT_INCLUDE} + diff --git a/net/coturn/patches/02-fix-flags-dupes.patch b/net/coturn/patches/02-fix-flags-dupes.patch new file mode 100644 index 000000000..516ec24ed --- /dev/null +++ b/net/coturn/patches/02-fix-flags-dupes.patch @@ -0,0 +1,14 @@ +--- a/configure ++++ b/configure +@@ -1047,9 +1047,9 @@ ${ECHO_CMD} "# Generated by configure sc + ${ECHO_CMD} "#################################" >> Makefile + ${ECHO_CMD} "ECHO_CMD = ${ECHO_CMD}" >> Makefile + ${ECHO_CMD} "CC = ${CC}" >> Makefile +-${ECHO_CMD} "LDFLAGS += ${OSLIBS}" >> Makefile ++${ECHO_CMD} "LDFLAGS = ${OSLIBS}" >> Makefile + ${ECHO_CMD} "DBLIBS += ${DBLIBS}" >> Makefile +-${ECHO_CMD} "CFLAGS += ${OSCFLAGS}" >> Makefile ++${ECHO_CMD} "CFLAGS = ${OSCFLAGS}" >> Makefile + ${ECHO_CMD} "CPPFLAGS = ${CPPFLAGS}" >> Makefile + ${ECHO_CMD} "DBCFLAGS += ${DBCFLAGS} ${TURN_NO_PQ} ${TURN_NO_MYSQL} ${TURN_NO_SQLITE} ${TURN_NO_MONGO} ${TURN_NO_HIREDIS} ${TURN_NO_SYSTEMD}" >> Makefile + ${ECHO_CMD} "#" >> Makefile diff --git a/net/coturn/patches/100-coturn-4.6.0-openssl3-from-gentoo.patch b/net/coturn/patches/100-coturn-4.6.0-openssl3-from-gentoo.patch new file mode 100644 index 000000000..42f9dd29e --- /dev/null +++ b/net/coturn/patches/100-coturn-4.6.0-openssl3-from-gentoo.patch @@ -0,0 +1,288 @@ +https://github.com/coturn/coturn/commit/9af9f6306ab73c3403f9e11086b1936e9148f7de +https://github.com/coturn/coturn/commit/4ce784a8781ab086c150e2b9f5641b1a37fd9b31 +https://github.com/coturn/coturn/commit/9370bb742d976166a51032760da1ecedefb92267 +https://github.com/coturn/coturn/commit/d72a2a8920b80ce66b36e22b2c22f308ad06c424 + +From 9af9f6306ab73c3403f9e11086b1936e9148f7de Mon Sep 17 00:00:00 2001 +From: Pavel Punsky +Date: Wed, 14 Sep 2022 03:29:26 -0700 +Subject: [PATCH] Fix renegotiation flag for older version of openssl (#978) + +`SSL_OP_NO_RENEGOTIATION` is only supported in openssl-1.1.0 and above +Older versions have `SSL3_FLAGS_NO_RENEGOTIATE_CIPHERS ` + +Fixes #977 and #952 + +Test: +Build in a docker container running running openssl-1.0.2g (ubuntu +16.04) successfully (without the fix getting the same errors) +--- a/src/apps/relay/dtls_listener.c ++++ b/src/apps/relay/dtls_listener.c +@@ -295,8 +295,17 @@ static ioa_socket_handle dtls_server_inp + SSL_set_accept_state(connecting_ssl); + + SSL_set_bio(connecting_ssl, NULL, wbio); +- SSL_set_options(connecting_ssl, SSL_OP_COOKIE_EXCHANGE | SSL_OP_NO_RENEGOTIATION); +- ++ SSL_set_options(connecting_ssl, SSL_OP_COOKIE_EXCHANGE ++#if OPENSSL_VERSION_NUMBER < 0x10100000L ++#if defined(SSL3_FLAGS_NO_RENEGOTIATE_CIPHERS) ++ | SSL3_FLAGS_NO_RENEGOTIATE_CIPHERS ++#endif ++#else ++#if defined(SSL_OP_NO_RENEGOTIATION) ++ | SSL_OP_NO_RENEGOTIATION ++#endif ++#endif ++ ); + SSL_set_max_cert_list(connecting_ssl, 655350); + + ioa_socket_handle rc = dtls_accept_client_connection(server, s, connecting_ssl, +@@ -581,7 +590,17 @@ static int create_new_connected_udp_sock + + SSL_set_bio(connecting_ssl, NULL, wbio); + +- SSL_set_options(connecting_ssl, SSL_OP_COOKIE_EXCHANGE | SSL_OP_NO_RENEGOTIATION); ++ SSL_set_options(connecting_ssl, SSL_OP_COOKIE_EXCHANGE ++#if OPENSSL_VERSION_NUMBER < 0x10100000L ++#if defined(SSL3_FLAGS_NO_RENEGOTIATE_CIPHERS) ++ | SSL3_FLAGS_NO_RENEGOTIATE_CIPHERS ++#endif ++#else ++#if defined(SSL_OP_NO_RENEGOTIATION) ++ | SSL_OP_NO_RENEGOTIATION ++#endif ++#endif ++ ); + + SSL_set_max_cert_list(connecting_ssl, 655350); + int rc = ssl_read(ret->fd, connecting_ssl, server->sm.m.sm.nd.nbh, +--- a/src/apps/relay/ns_ioalib_engine_impl.c ++++ b/src/apps/relay/ns_ioalib_engine_impl.c +@@ -1428,7 +1428,17 @@ static void set_socket_ssl(ioa_socket_ha + if(ssl) { + SSL_set_app_data(ssl,s); + SSL_set_info_callback(ssl, (ssl_info_callback_t)ssl_info_callback); +- SSL_set_options(ssl, SSL_OP_NO_RENEGOTIATION); ++ SSL_set_options(ssl, ++#if OPENSSL_VERSION_NUMBER < 0x10100000L ++#if defined(SSL3_FLAGS_NO_RENEGOTIATE_CIPHERS) ++ SSL3_FLAGS_NO_RENEGOTIATE_CIPHERS ++#endif ++#else ++#if defined(SSL_OP_NO_RENEGOTIATION) ++ SSL_OP_NO_RENEGOTIATION ++#endif ++#endif ++ ); + } + } + } +@@ -1864,7 +1874,11 @@ int ssl_read(evutil_socket_t fd, SSL* ss + + } else if (!if1 && if2) { + ++#if (OPENSSL_VERSION_NUMBER >= 0x30000000L) ++ if(verbose && SSL_get1_peer_certificate(ssl)) { ++#else + if(verbose && SSL_get_peer_certificate(ssl)) { ++#endif + printf("\n------------------------------------------------------------\n"); + X509_NAME_print_ex_fp(stdout, X509_get_subject_name(SSL_get_peer_certificate(ssl)), 1, + XN_FLAG_MULTILINE); +--- a/src/apps/uclient/startuclient.c ++++ b/src/apps/uclient/startuclient.c +@@ -138,7 +138,11 @@ static SSL* tls_connect(ioa_socket_raw f + if (rc > 0) { + TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO,"%s: client session connected with cipher %s, method=%s\n",__FUNCTION__, + SSL_get_cipher(ssl),turn_get_ssl_method(ssl,NULL)); ++#if (OPENSSL_VERSION_NUMBER >= 0x30000000L) ++ if(clnet_verbose && SSL_get1_peer_certificate(ssl)) { ++#else + if(clnet_verbose && SSL_get_peer_certificate(ssl)) { ++#endif + TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO, "------------------------------------------------------------\n"); + X509_NAME_print_ex_fp(stdout, X509_get_subject_name(SSL_get_peer_certificate(ssl)), 1, + XN_FLAG_MULTILINE); +--- a/src/client/ns_turn_msg.c ++++ b/src/client/ns_turn_msg.c +@@ -248,12 +248,22 @@ int stun_produce_integrity_key_str(const + if (FIPS_mode()) { + EVP_MD_CTX_set_flags(&ctx,EVP_MD_CTX_FLAG_NON_FIPS_ALLOW); + } +-#endif ++#endif // defined EVP_MD_CTX_FLAG_NON_FIPS_ALLOW && !defined(LIBRESSL_VERSION_NUMBER) + EVP_DigestInit_ex(&ctx,EVP_md5(), NULL); + EVP_DigestUpdate(&ctx,str,strl); + EVP_DigestFinal(&ctx,key,&keylen); + EVP_MD_CTX_cleanup(&ctx); +-#else ++#elif OPENSSL_VERSION_NUMBER >= 0x30000000L ++ unsigned int keylen = 0; ++ EVP_MD_CTX *ctx = EVP_MD_CTX_new(); ++ if (EVP_default_properties_is_fips_enabled(NULL)) { ++ EVP_default_properties_enable_fips(NULL, 0); ++ } ++ EVP_DigestInit_ex(ctx,EVP_md5(), NULL); ++ EVP_DigestUpdate(ctx,str,strl); ++ EVP_DigestFinal(ctx,key,&keylen); ++ EVP_MD_CTX_free(ctx); ++#else // OPENSSL_VERSION_NUMBER < 0x10100000L + unsigned int keylen = 0; + EVP_MD_CTX *ctx = EVP_MD_CTX_new(); + #if defined EVP_MD_CTX_FLAG_NON_FIPS_ALLOW && ! defined(LIBRESSL_VERSION_NUMBER) +@@ -265,7 +275,7 @@ int stun_produce_integrity_key_str(const + EVP_DigestUpdate(ctx,str,strl); + EVP_DigestFinal(ctx,key,&keylen); + EVP_MD_CTX_free(ctx); +-#endif ++#endif // OPENSSL_VERSION_NUMBER < 0X10100000L + ret = 0; + } + +--- a/src/apps/relay/netengine.c ++++ b/src/apps/relay/netengine.c +@@ -31,13 +31,7 @@ + #include "mainrelay.h" + + //////////// Backward compatibility with OpenSSL 1.0.x ////////////// +-#define HAVE_OPENSSL11_API (!(OPENSSL_VERSION_NUMBER < 0x10100001L || defined LIBRESSL_VERSION_NUMBER)) +- +-#ifndef HAVE_SSL_CTX_UP_REF +-#define HAVE_SSL_CTX_UP_REF HAVE_OPENSSL11_API +-#endif +- +-#if !HAVE_SSL_CTX_UP_REF ++#if (OPENSSL_VERSION_NUMBER < 0x10100001L || defined LIBRESSL_VERSION_NUMBER) + #define SSL_CTX_up_ref(ctx) CRYPTO_add(&(ctx)->references, 1, CRYPTO_LOCK_SSL_CTX) + #endif + +--- a/src/apps/relay/mainrelay.c ++++ b/src/apps/relay/mainrelay.c +@@ -1353,7 +1353,6 @@ static void set_option(int c, char *valu + STRCPY(turn_params.relay_ifname, value); + break; + case 'm': +-#if defined(OPENSSL_THREADS) + if(atoi(value)>MAX_NUMBER_OF_GENERAL_RELAY_SERVERS) { + TURN_LOG_FUNC(TURN_LOG_LEVEL_WARNING, "WARNING: max number of relay threads is 128.\n"); + turn_params.general_relay_servers_number = MAX_NUMBER_OF_GENERAL_RELAY_SERVERS; +@@ -1362,9 +1361,6 @@ static void set_option(int c, char *valu + } else { + turn_params.general_relay_servers_number = atoi(value); + } +-#else +- TURN_LOG_FUNC(TURN_LOG_LEVEL_WARNING, "WARNING: OpenSSL version is too old OR does not support threading,\n I am using single thread for relaying.\n"); +-#endif + break; + case 'd': + STRCPY(turn_params.listener_ifname, value); +@@ -2640,9 +2636,8 @@ int main(int argc, char **argv) + + ////////// OpenSSL locking //////////////////////////////////////// + +-#if defined(OPENSSL_THREADS) +- +-static char some_buffer[65536]; ++#if defined(OPENSSL_THREADS) ++#if OPENSSL_VERSION_NUMBER < OPENSSL_VERSION_1_1_0 + + //array larger than anything that OpenSSL may need: + static pthread_mutex_t mutex_buf[256]; +@@ -2660,76 +2655,52 @@ void coturn_locking_function(int mode, i + } + } + +-#if OPENSSL_VERSION_NUMBER >= 0x10000000L + void coturn_id_function(CRYPTO_THREADID *ctid); + void coturn_id_function(CRYPTO_THREADID *ctid) + { + UNUSED_ARG(ctid); + CRYPTO_THREADID_set_numeric(ctid, (unsigned long)pthread_self()); + } +-#else +-unsigned long coturn_id_function(void); +-unsigned long coturn_id_function(void) +-{ +- return (unsigned long)pthread_self(); +-} +-#endif +- +-#endif + + static int THREAD_setup(void) { +- +-#if defined(OPENSSL_THREADS) +- +- int i; +- +- some_buffer[0] = 0; +- ++ int i; + for (i = 0; i < CRYPTO_num_locks(); i++) { + pthread_mutex_init(&(mutex_buf[i]), NULL); + } + + mutex_buf_initialized = 1; +- +-#if OPENSSL_VERSION_NUMBER >= 0x10000000L && OPENSSL_VERSION_NUMBER <= OPENSSL_VERSION_1_1_1 + CRYPTO_THREADID_set_callback(coturn_id_function); +-#else +- CRYPTO_set_id_callback(coturn_id_function); +-#endif +- + CRYPTO_set_locking_callback(coturn_locking_function); +-#endif +- + return 1; + } + + int THREAD_cleanup(void); + int THREAD_cleanup(void) { ++ int i; + +-#if defined(OPENSSL_THREADS) +- +- int i; ++ if (!mutex_buf_initialized) ++ return 0; + +- if (!mutex_buf_initialized) +- return 0; ++ CRYPTO_THREADID_set_callback(NULL); ++ CRYPTO_set_locking_callback(NULL); ++ for (i = 0; i < CRYPTO_num_locks(); i++) { ++ pthread_mutex_destroy(&(mutex_buf[i])); ++ } + +-#if OPENSSL_VERSION_NUMBER >= 0x10000000L && OPENSSL_VERSION_NUMBER <= OPENSSL_VERSION_1_1_1 +- CRYPTO_THREADID_set_callback(NULL); ++ mutex_buf_initialized = 0; ++ return 1; ++} + #else +- CRYPTO_set_id_callback(NULL); +-#endif +- +- CRYPTO_set_locking_callback(NULL); +- for (i = 0; i < CRYPTO_num_locks(); i++) { +- pthread_mutex_destroy(&(mutex_buf[i])); +- } +- +- mutex_buf_initialized = 0; +- +-#endif ++static int THREAD_setup(void) { ++ return 1; ++} + +- return 1; ++int THREAD_cleanup(void); ++int THREAD_cleanup(void){ ++ return 1; + } ++#endif /* OPENSSL_VERSION_NUMBER < OPENSSL_VERSION_1_1_0 */ ++#endif /* defined(OPENSSL_THREADS) */ + + static void adjust_key_file_name(char *fn, const char* file_title, int critical) + { diff --git a/net/freeswitch-mod-bcg729/Makefile b/net/freeswitch-mod-bcg729/Makefile new file mode 100644 index 000000000..478f1c571 --- /dev/null +++ b/net/freeswitch-mod-bcg729/Makefile @@ -0,0 +1,79 @@ +# +# Copyright (C) 2017 OpenWrt.org +# +# This is free software, licensed under the GNU General Public License v2. +# See /LICENSE for more information. +# + +include $(TOPDIR)/rules.mk + +PKG_NAME:=freeswitch-mod-bcg729 + +PKG_RELEASE:=1 +PKG_MAINTAINER:=Sebastian Kemper + +PKG_LICENSE:=MPL-1.1 +PKG_LICENSE_FILES:=LICENSE + +PKG_SOURCE_URL:=https://github.com/xadhoom/mod_bcg729.git +PKG_SOURCE_PROTO:=git +PKG_SOURCE_VERSION:=686eb06d4a395d94c364efff4b63579af76ebec7 +PKG_SOURCE_DATE:=2017-06-29 +PKG_MIRROR_HASH:=7b9ae6e5ce983d534f9e02bdc3b8d2e77c8d773e25974f6ad65ac1319fff07a4 + +include $(INCLUDE_DIR)/package.mk + +BCG729_MOD_DIR:=/usr/lib/freeswitch/mod + +BCG729_CFLAGS:=\ + $(FPIC) \ + $(TARGET_CFLAGS) \ + -fno-exceptions \ + -Wall \ + -std=c99 \ + -pedantic + +BCG729_INCLUDES:= \ + $(TARGET_CPPFLAGS) \ + -I$(STAGING_DIR)/usr/include/bcg729 \ + -I$(STAGING_DIR)/usr/include/freeswitch + +BCG729_LDFLAGS:=-lm -Wl,-shared -lbcg729 -Wl,-Bdynamic + +define Package/freeswitch-mod-bcg729 + TITLE:=bcg729 module + SUBMENU:=Telephony + SECTION:=net + CATEGORY:=Network + URL:=https://github.com/xadhoom/mod_bcg729 + DEPENDS:=freeswitch +bcg729 +endef + +define Package/freeswitch-mod-bcg729/description +FreeSWITCH G.729 module using the opensource bcg729 implementation by +Belledonne Communications. +endef + +define Package/freeswitch-mod-bcg729/install + $(INSTALL_DIR) $(1)$(BCG729_MOD_DIR) + $(INSTALL_BIN) $(PKG_BUILD_DIR)/mod_bcg729.so $(1)$(BCG729_MOD_DIR) +endef + +define Build/Compile + cd $(PKG_BUILD_DIR) && \ + $(TARGET_CC) \ + $(BCG729_CFLAGS) \ + $(BCG729_INCLUDES) \ + -c mod_bcg729.c && \ + $(TARGET_CC) \ + $(BCG729_CFLAGS) \ + $(BCG729_INCLUDES) \ + -shared \ + -Xlinker \ + -x \ + -o mod_bcg729.so \ + mod_bcg729.o \ + $(BCG729_LDFLAGS) +endef + +$(eval $(call BuildPackage,freeswitch-mod-bcg729)) diff --git a/net/freeswitch/Config.in b/net/freeswitch/Config.in new file mode 100644 index 000000000..52b1c06d0 --- /dev/null +++ b/net/freeswitch/Config.in @@ -0,0 +1,56 @@ +menu "Advanced configuration" + depends on PACKAGE_freeswitch + +config FS_WITH_DEBUG + bool "Compile with debug information" + default n + help + Enable extra debug codepaths, like asserts and extra output. If you + want to get meaningful backtraces see + https://wiki.openwrt.org/doc/devel/debugging for starting points. + +config FS_WITH_FREETYPE + bool "Compile with FreeType support" + default y if x86_64 + help + Add FreeType support to FreeSWITCH + +config FS_WITH_LIBYUV + bool "Compile with libyuv support" + default y if x86_64 + help + Add libyuv support to FreeSWITCH + +config FS_WITH_ODBC + bool "Compile with ODBC support" + default y if x86_64 + help + Enable ODBC support. + +config FS_WITH_PNG + bool "Compile with PNG support" + default y if x86_64 + help + Add PNG support to FreeSWITCH + +config FS_WITH_SRTP + bool "Compile with SRTP support" + default y + help + Compile with SRTP support. + +config FS_WITH_VPX + bool "Compile with VPx support" + depends on FS_WITH_LIBYUV + default y if x86_64 + help + Compile with VPx video codec support + +config FS_WITH_MODCONF + bool "Include module examples" + default y if x86_64 + help + Some modules include examples in their source directory, e.g. xml + snippets. Select y to include them. + +endmenu diff --git a/net/freeswitch/Makefile b/net/freeswitch/Makefile new file mode 100644 index 000000000..213e45bb8 --- /dev/null +++ b/net/freeswitch/Makefile @@ -0,0 +1,1023 @@ +# +# Copyright (C) 2017 Sebastian Kemper +# +# This is free software, licensed under the GNU General Public License v2. +# See /LICENSE for more information. +# + +include $(TOPDIR)/rules.mk + +PKG_NAME:=freeswitch +PKG_VERSION:=1.10.11 +PKG_RELEASE:=1 +PKG_MAINTAINER:=Sebastian Kemper + +PKG_SOURCE:=freeswitch-$(PKG_VERSION).-release.tar.xz +PKG_SOURCE_URL:=https://files.freeswitch.org/releases/freeswitch +PKG_HASH:=7f9603a691220d9f47da42f3b19290b629b69dceb2eee56448f0a7cefcf9d1a1 + +PKG_CPE_ID:=cpe:/a:freeswitch:freeswitch + +PKG_BUILD_DIR:=$(BUILD_DIR)/freeswitch-$(PKG_VERSION).-release + +PKG_BUILD_DEPENDS:=perl/host + +PKG_FIXUP:=autoreconf + +PKG_BUILD_PARALLEL:=1 +PKG_INSTALL:=1 + +PKG_LICENSE:= \ + AGPL-3.0 \ + Apache-2.0 \ + BSD-2-Clause \ + BSD-3-Clause \ + BSD-4-Clause \ + BSD-like \ + Beerware \ + GPL-1.0+ \ + GPL-2.0 \ + GPL-2.0+ \ + GPL-3.0 \ + ISC \ + LGPL-2.0+ \ + LGPL-2.1 \ + LGPL-2.1+ \ + MIT/X11 (BSD like) \ + MPL-1.1 \ + OpenLDAP \ + RSA-MD \ + zlib-acknowledgement + +PKG_LICENSE_FILES:=debian/copyright + +FS_DATA_DIR:=/usr/share/freeswitch + +FS_BIN_DIR:=/usr/bin +FS_EXAMPLES_DIR:=$(FS_DATA_DIR)/examples +FS_FONTS_DIR:=$(FS_DATA_DIR)/fonts +FS_GRAMMAR_DIR:=$(FS_DATA_DIR)/grammar +FS_HTDOCS_DIR:=$(FS_DATA_DIR)/htdocs +FS_IMAGES_DIR:=$(FS_DATA_DIR)/images +FS_INCLUDES_DIR:=/usr/include/freeswitch +FS_LANG_DIR:=$(FS_DATA_DIR)/lang +FS_LIB_DIR:=/usr/lib +FS_MOD_DIR:=$(FS_LIB_DIR)/freeswitch/mod +FS_PKGCONFIG_DIR:=$(FS_LIB_DIR)/pkgconfig +FS_SCRIPTS_DIR:=$(FS_DATA_DIR)/scripts +FS_SOUNDS_DIR:=$(FS_DATA_DIR)/sounds +FS_SYSCONF_DIR:=/etc +FS_TLS_DIR:=$(FS_SYSCONF_DIR)/freeswitch/tls +FS_TZ_DIR:=$(FS_DATA_DIR)/tz + +FS_MOD_AVAILABLE:= \ + abstraction \ + alsa \ + amr \ + amrwb \ + av \ + avmd \ + b64 \ + basic \ + bert \ + blacklist \ + callcenter \ + cdr_csv \ + cdr_mongodb \ + cdr_pg_csv \ + cdr_sqlite \ + cidlookup \ + clearmode \ + cluechoo \ + commands \ + conference \ + console \ + curl \ + dahdi_codec \ + db \ + dialplan_asterisk \ + dialplan_directory \ + dialplan_xml \ + directory \ + distributor \ + dptools \ + easyroute \ + enum \ + erlang_event \ + esf \ + esl \ + event_multicast \ + event_socket \ + event_test \ + event_zmq \ + expr \ + fail2ban \ + fifo \ + format_cdr \ + fsk \ + fsv \ + g723_1 \ + g729 \ + graylog2 \ + gsmopen \ + h26x \ + hash \ + hiredis \ + httapi \ + http_cache \ + isac \ + json_cdr \ + kazoo \ + lcr \ + ldap \ + local_stream \ + logfile \ + loopback \ + lua \ + mariadb \ + mp4v \ + native_file \ + nibblebill \ + odbc_cdr \ + opus \ + opusfile \ + oreka \ + perl \ + pgsql \ + png \ + pocketsphinx \ + portaudio \ + portaudio_stream \ + posix_timer \ + prefix \ + python3 \ + radius_cdr \ + random \ + raven \ + rayo \ + redis \ + rss \ + rtc \ + rtmp \ + say_de \ + say_en \ + say_es \ + say_es_ar \ + say_fa \ + say_fr \ + say_he \ + say_hr \ + say_hu \ + say_it \ + say_ja \ + say_nl \ + say_pl \ + say_pt \ + say_ru \ + say_sv \ + say_th \ + say_zh \ + shell_stream \ + shout \ + signalwire \ + skinny \ + sms \ + snapshot \ + sndfile \ + snmp \ + snom \ + sofia \ + sonar \ + spandsp \ + spy \ + ssml \ + stress \ + syslog \ + theora \ + tone_stream \ + translate \ + tts_commandline \ + valet_parking \ + verto \ + video_filter \ + vmd \ + voicemail \ + voicemail_ivr \ + xml_cdr \ + xml_curl \ + xml_ldap \ + xml_rpc \ + xml_scgi \ + yaml \ + yuv + +PKG_CONFIG_DEPENDS:= \ + $(patsubst %,CONFIG_PACKAGE_freeswitch-mod-%,$(subst _,-,$(FS_MOD_AVAILABLE))) \ + CONFIG_FS_WITH_DEBUG \ + CONFIG_FS_WITH_FREETYPE \ + CONFIG_FS_WITH_LIBYUV \ + CONFIG_FS_WITH_ODBC \ + CONFIG_FS_WITH_PNG \ + CONFIG_FS_WITH_SRTP \ + CONFIG_FS_WITH_VPX \ + CONFIG_LIBC \ + CONFIG_PACKAGE_freeswitch-misc-perl-esl \ + CONFIG_PACKAGE_freeswitch-misc-python3-esl \ + CONFIG_SOFT_FLOAT + +include $(INCLUDE_DIR)/package.mk +# iconv support +include $(INCLUDE_DIR)/nls.mk + +FS_PERL_FEED:=$(TOPDIR)/feeds/packages/lang/perl + +include $(TOPDIR)/feeds/packages/lang/python/python3-version.mk +include $(FS_PERL_FEED)/perlver.mk + +PERL_SITELIB:=/usr/lib/perl$(PERL_MAJOR)/$(PERL_VERSION2) + +FS_PERL_LIBS:=$(shell grep "^libs=" \ + $(FS_PERL_FEED)/files/base.config | \ + sed "s/^libs=//;s/'//g") + +FS_PYTHON3_SITE_DIR:=$(FS_LIB_DIR)/python$(PYTHON3_VERSION)/site-packages + +define Download/files +define Download/$(1) + FILE:=$(2) + URL:=$(3) + HASH:=$(4) + VERSION:=$(5) + SUBDIR:=$(6) + MIRROR_HASH:=$(7) + PROTO:=$(8) +endef +$$(eval $$(call Download,$(1))) +endef + +define Package/freeswitch/enable/plugin + $(SED) '/$(1)$$$$/s/^#//' $(PKG_BUILD_DIR)/modules.conf +endef + +define Package/freeswitch/install/bin + $(INSTALL_DIR) $(1)$(FS_BIN_DIR) + $(INSTALL_BIN) $(PKG_INSTALL_DIR)$(FS_BIN_DIR)/$(2) \ + $(1)$(FS_BIN_DIR) +endef + +define Package/freeswitch/install/dir + if [ -d $(2) ]; then $(INSTALL_DIR) $(1); fi + for dir in $$$$(shell [ -d $(2) ] && cd $(2) && $(FIND) -type d -print | sed 's|^./\?||'); \ + do \ + $(INSTALL_DIR) $(1)/$$$$$$$$dir; \ + done + for file in $$$$(shell [ -d $(2) ] && cd $(2) && $(FIND) -type f -print | sed 's|^./||'); \ + do \ + $(INSTALL_DATA) $(2)/$$$$$$$$file $(1)/$$$$$$$$file; \ + done +endef + +define Package/freeswitch/install/lib + $(INSTALL_DIR) $(1)$(FS_LIB_DIR) + $(CP) $(PKG_INSTALL_DIR)$(FS_LIB_DIR)/$(2).so.* \ + $(1)$(FS_LIB_DIR) +endef + +define Package/freeswitch/install/mod + $(INSTALL_DIR) $(1)$(FS_MOD_DIR) + $(INSTALL_BIN) $(PKG_INSTALL_DIR)$(FS_MOD_DIR)/mod_$(2).so \ + $(1)$(FS_MOD_DIR) +endef + +define Package/freeswitch/config + source "$(SOURCE)/Config.in" +endef + +define Package/freeswitch/Default + SUBMENU:=Telephony + SECTION:=net + CATEGORY:=Network + URL:=https://www.freeswitch.org +endef + +# Note: shadow deps are a bit strange; you need to select shadow-utils +# package first for shadow-su to be selected, even though the +# shadow-utils package later becomes a no-op. +define Package/freeswitch +$(call Package/freeswitch/Default) + TITLE:=Open source telephony platform, v$(PKG_VERSION) + MENU:=1 + USERID:=freeswitch=372:freeswitch=372 + DEPENDS:= \ + $(ICONV_DEPENDS) \ + +libstdcpp \ + +!BUSYBOX_DEFAULT_SU:shadow-utils \ + +!BUSYBOX_DEFAULT_SU:shadow-su \ + +@OPENSSL_WITH_DEPRECATED \ + +FS_WITH_FREETYPE:libfreetype \ + +FS_WITH_ODBC:unixodbc \ + +FS_WITH_PNG:libpng \ + +libcurl \ + +libedit \ + +libopenssl \ + +libpcre \ + +libpthread \ + +librt \ + +libspandsp3 \ + +libspeex \ + +libspeexdsp \ + +libsqlite3 \ + +libuuid \ + +sofia-sip \ + +zlib +endef + +define Package/freeswitch/description +FreeSWITCH is a scalable open source cross-platform telephony platform +designed to route and interconnect popular communication protocols +using audio, video, text or any other form of media. +endef + +define Package/freeswitch/conffiles +$(FS_SYSCONF_DIR)/freeswitch +$(FS_SYSCONF_DIR)/config/freeswitch +$(FS_SYSCONF_DIR)/init.d/freeswitch +endef + +define Package/freeswitch/install +$(call Package/freeswitch/install/bin,$(1),freeswitch) +$(call Package/freeswitch/install/lib,$(1),libfreeswitch) + $(INSTALL_DIR) $(1)$(FS_FONTS_DIR) + $(INSTALL_DIR) $(1)$(FS_GRAMMAR_DIR) + $(INSTALL_DIR) $(1)$(FS_HTDOCS_DIR) + $(INSTALL_DIR) $(1)$(FS_IMAGES_DIR) + $(INSTALL_DIR) $(1)$(FS_SCRIPTS_DIR) + $(INSTALL_DIR) $(1)$(FS_SOUNDS_DIR) + $(INSTALL_DIR) $(1)$(FS_SYSCONF_DIR)/config + $(INSTALL_DIR) $(1)$(FS_SYSCONF_DIR)/hotplug.d/iface + $(INSTALL_DIR) $(1)$(FS_SYSCONF_DIR)/init.d + $(INSTALL_DIR) $(1)$(FS_TLS_DIR) + $(INSTALL_BIN) ./files/freeswitch.init \ + $(1)$(FS_SYSCONF_DIR)/init.d/freeswitch + $(INSTALL_BIN) ./files/freeswitch.hotplug \ + $(1)$(FS_SYSCONF_DIR)/hotplug.d/iface/90-freeswitch + $(INSTALL_CONF) ./files/freeswitch.conf \ + $(1)$(FS_SYSCONF_DIR)/config/freeswitch +endef + +define Package/freeswitch/postinst +#!/bin/sh +if [ -z "$${IPKG_INSTROOT}" ]; then + echo + echo "o-------------------------------------------------------------------o" + echo "| FreeSWITCH note |" + echo "o-------------------------------------------------------------------o" + echo "| Edit /etc/config/freeswitch to change basic init configuration. |" + echo "| |" + echo "| Also visit the Wiki at: |" + echo "| https://openwrt.org/docs/guide-user/services/voip/freeswitch |" + echo "o-------------------------------------------------------------=^_^=-o" + echo +fi +exit 0 +endef + +define Package/freeswitch-misc-perl-esl +$(call Package/freeswitch/Default) + TITLE:=Perl ESL + DEPENDS:=freeswitch \ + +PACKAGE_freeswitch-misc-perl-esl:perlbase-autoloader \ + +PACKAGE_freeswitch-misc-perl-esl:perlbase-data \ + +PACKAGE_freeswitch-misc-perl-esl:perlbase-dynaloader \ + @PERL_THREADS +endef + +define Package/freeswitch-misc-perl-esl/description +This package contains the Perl binding for FreeSWITCH's Event Socket +Library (ESL). +endef + +define Package/freeswitch-misc-perl-esl/install + $(INSTALL_DIR) $(1)$(PERL_SITELIB)/ESL + $(INSTALL_DIR) $(1)$(PERL_SITELIB)/auto/ESL + $(INSTALL_BIN) \ + $(PKG_INSTALL_DIR)$(PERL_SITELIB)/ESL.so \ + $(1)$(PERL_SITELIB)/auto/ESL + $(INSTALL_DATA) \ + $(PKG_INSTALL_DIR)$(PERL_SITELIB)/ESL.pm \ + $(1)$(PERL_SITELIB) + $(INSTALL_DATA) \ + $(PKG_INSTALL_DIR)$(PERL_SITELIB)/ESL/Dispatch.pm \ + $(1)$(PERL_SITELIB)/ESL + $(INSTALL_DATA) \ + $(PKG_INSTALL_DIR)$(PERL_SITELIB)/ESL/IVR.pm \ + $(1)$(PERL_SITELIB)/ESL +endef + +define Package/freeswitch-misc-python3-esl +$(call Package/freeswitch/Default) + TITLE:=Python3 ESL + DEPENDS:=freeswitch +PACKAGE_freeswitch-misc-python3-esl:python3-light +endef + +define Package/freeswitch-misc-python3-esl/description +This package contains the Python3 binding for FreeSWITCH's Event Socket +Library (ESL). +endef + +define Package/freeswitch-misc-python3-esl/install + $(INSTALL_DIR) $(1)$(FS_PYTHON3_SITE_DIR) + $(INSTALL_BIN) \ + $(PKG_INSTALL_DIR)$(FS_PYTHON3_SITE_DIR)/_ESL.so \ + $(1)$(FS_PYTHON3_SITE_DIR) + $(INSTALL_DATA) \ + $(PKG_INSTALL_DIR)$(FS_PYTHON3_SITE_DIR)/ESL.py \ + $(1)$(FS_PYTHON3_SITE_DIR) +endef + +define Package/freeswitch-misc-timezones +$(call Package/freeswitch/Default) + TITLE:=Timezones file + DEPENDS:=freeswitch + PKGARCH:=all +endef + +define Package/freeswitch-misc-timezones/description +This package includes a timezones file for FreeSWITCH. +endef + +define Package/freeswitch-misc-timezones/install + $(INSTALL_DIR) $(1)$(FS_TZ_DIR) + $(INSTALL_DATA) \ + $(PKG_BUILD_DIR)/conf/vanilla/autoload_configs/timezones.conf.xml \ + $(1)$(FS_TZ_DIR) +endef + +define Package/freeswitch/Example +define Package/freeswitch-example-$(subst _,-,$(1)) +$(call Package/freeswitch/Default) + TITLE:=Example configuration + DEPENDS:=freeswitch + PKGARCH:=all +endef +define Package/freeswitch-example-$(subst _,-,$(1))/description +This package does not install any configuration for FreeSWITCH into +/etc/freeswitch. The system administrator is completely responsible +for that directory. If you install one of the example configuration +packages, it will install the corresponding sample configuration to +/usr/share/freeswitch/examples where you can take a look at it. +endef +define Package/freeswitch-example-$(subst _,-,$(1))/install +$(call Package/freeswitch/install/dir,$$(1)$(FS_EXAMPLES_DIR)/$(1),$(PKG_BUILD_DIR)/conf/$(1)) +endef +$$(eval $$(call BuildPackage,freeswitch-example-$(subst _,-,$(1)))) +endef + +define Package/freeswitch/Language +define Package/freeswitch-lang-$(subst _,-,$(1)) +$(call Package/freeswitch/Default) + TITLE:=$(2) language files + DEPENDS:=freeswitch + PKGARCH:=all +endef +define Package/freeswitch-lang-$(subst _,-,$(1))/description +This package includes the $(2) language files for FreeSWITCH. +endef +define Package/freeswitch-lang-$(subst _,-,$(1))/install +$(call Package/freeswitch/install/dir,$$(1)$(FS_LANG_DIR)/$(1),$(PKG_BUILD_DIR)/conf/vanilla/lang/$(1)) +endef +$$(eval $$(call BuildPackage,freeswitch-lang-$(subst _,-,$(1)))) +endef + +# The next package generator is for miscellaneous files that only +# require being copied from PKG_INSTALL_DIR to the ipkg. +define Package/freeswitch/Misc +define Package/freeswitch-$(subst _,-,$(1)) +$(call Package/freeswitch/Default) + TITLE:=$(2) + DEPENDS:=freeswitch + ifeq ($(6),y) + PKGARCH:=all + endif +endef +define Package/freeswitch-$(subst _,-,$(1))/description +$(subst \n,$(newline),$(3)) +endef +define Package/freeswitch-$(subst _,-,$(1))/install +$(call Package/freeswitch/install/dir,$$(1)$(5),$(PKG_INSTALL_DIR)$(4)) +endef +$$(eval $$(call BuildPackage,freeswitch-$(subst _,-,$(1)))) +endef + +define Package/freeswitch/Module +define Package/freeswitch-mod-$(subst _,-,$(1)) +$(call Package/freeswitch/Default) + TITLE:=$(2) module + DEPENDS:=freeswitch $(patsubst +%,+PACKAGE_freeswitch-mod-$(subst _,-,$(1)):%,$(4)) +endef +define Package/freeswitch-mod-$(subst _,-,$(1))/description +$(subst \n,$(newline),$(3)) +endef +define Package/freeswitch-mod-$(subst _,-,$(1))/install +$(call Package/freeswitch/install/mod,$$(1),$(1)) +ifeq ($(CONFIG_FS_WITH_MODCONF),y) +$(call Package/freeswitch/install/dir,$$(1)$(FS_EXAMPLES_DIR)/mod_$(1),$(PKG_BUILD_DIR)/src/mod/*/mod_$(1)/conf) +endif +ifeq ($(1),perl) + $(INSTALL_DIR) $$(1)$(PERL_SITELIB)/auto/freeswitch + $(INSTALL_BIN) \ + $(PKG_INSTALL_DIR)/usr/perl/freeswitch.so \ + $$(1)$(PERL_SITELIB)/auto/freeswitch + $(INSTALL_DATA) \ + $(PKG_INSTALL_DIR)/usr/perl/freeswitch.pm \ + $$(1)$(PERL_SITELIB) +endif +ifeq ($(1),python3) + $(INSTALL_DIR) $$(1)$(FS_PYTHON3_SITE_DIR) + $(INSTALL_DATA) \ + $(PKG_INSTALL_DIR)$(FS_PYTHON3_SITE_DIR)/freeswitch.py \ + $$(1)$(FS_PYTHON3_SITE_DIR) +endif +endef +$$(eval $$(call BuildPackage,freeswitch-mod-$(subst _,-,$(1)))) +endef + +define Package/freeswitch/Util +define Package/freeswitch-util-$(subst _,-,$(1)) +$(call Package/freeswitch/Default) + TITLE:=$(2) utility + DEPENDS:=freeswitch $(patsubst +%,+PACKAGE_freeswitch-util-$(subst _,-,$(1)):%,$(4)) + ifeq ($(5),y) + PKGARCH:=all + endif +endef +define Package/freeswitch-util-$(subst _,-,$(1))/description +$(subst \n,$(newline),$(3)) +endef +define Package/freeswitch-util-$(subst _,-,$(1))/install +$(call Package/freeswitch/install/bin,$$(1),$(1)) +endef +$$(eval $$(call BuildPackage,freeswitch-util-$(subst _,-,$(1)))) +endef + +CONFIGURE_ARGS+= \ + --srcdir=$(PKG_BUILD_DIR) \ + --disable-dependency-tracking \ + --disable-static \ + --disable-system-xmlrpc-c \ + --enable-core-libedit-support \ + --enable-fhs \ + --with-cachedir=/tmp/freeswitch/cache \ + --with-dbdir=/tmp/freeswitch/db \ + --with-imagesdir=$(FS_IMAGES_DIR) \ + --with-logfiledir=/tmp/freeswitch/log \ + --with-python=no \ + --with-recordingsdir=/tmp/freeswitch/recordings \ + --with-storagedir=/tmp/freeswitch/storage \ + $(call autoconf_bool,CONFIG_FS_WITH_DEBUG,debug) \ + $(call autoconf_bool,CONFIG_FS_WITH_LIBYUV,libyuv) \ + $(call autoconf_bool,CONFIG_FS_WITH_ODBC,core-odbc-support) \ + $(call autoconf_bool,CONFIG_FS_WITH_SRTP,srtp) \ + $(call autoconf_bool,CONFIG_FS_WITH_VPX,libvpx) \ + $(if $(CONFIG_FS_WITH_FREETYPE),,--without-freetype) \ + $(if $(CONFIG_FS_WITH_ODBC),--with-odbc-lib="$(STAGING_DIR)$(FS_LIB_DIR)") \ + $(if $(CONFIG_FS_WITH_ODBC),--with-odbc="$(STAGING_DIR)/usr") \ + $(if $(CONFIG_FS_WITH_PNG),,--without-png) + +ifneq ($(CONFIG_PACKAGE_freeswitch-misc-python3-esl)$(CONFIG_PACKAGE_freeswitch-mod-python3),) +CONFIGURE_ARGS+= \ + --with-python3=$(STAGING_DIR_HOST)/bin/python3 +else +CONFIGURE_ARGS+= \ + --with-python3=no +endif + +ifeq ($(CONFIG_PACKAGE_freeswitch-mod-erlang-event)$(CONFIG_PACKAGE_freeswitch-mod-kazoo),) +CONFIGURE_ARGS+= \ + --with-erlang=no +endif + +# FreeSWITCH dropped postgresql support from the core. postgresql +# support is now available via mod_pgsql. We still need to pass +# '--without-pgsql', otherwise apr-util links to libpq and we still +# would have the core link to it. +CONFIGURE_ARGS+= \ + --without-pgsql + +# Don't want host-php +CONFIGURE_VARS+= \ + ac_cv_have_php=no \ + ac_cv_have_php_config=no \ + ac_cv_prog_PHP=false \ + ac_cv_prog_PHP_CONFIG=false + +# The autoconf variables in this block are OK for both musl and glibc +CONFIGURE_VARS+= \ + ac_cv_dev_urandom=yes \ + ac_cv_file__dev_ptmx=yes \ + ac_cv_file__dev_urandom=yes \ + ac_cv_file_dbd_apr_dbd_mysql_c=no \ + ac_cv_free_null=yes \ + ac_cv_func_mmap_fixed_mapped=yes \ + ac_cv_func_pthread_rwlock_init=yes \ + ac_cv_func_sem_open=yes \ + ac_cv_have_working_memmove=yes \ + ac_cv_negative_eai=yes \ + ac_cv_o_nonblock_inherited=no \ + ac_cv_struct_rlimit=yes \ + apr_cv_epoll=yes \ + apr_cv_gai_addrconfig=yes \ + apr_cv_mutex_recursive=yes \ + apr_cv_process_shared_works=yes \ + apr_cv_pthreads_lib=-lpthread \ + apr_cv_tcp_nodelay_with_cork=yes \ + apr_cv_type_rwlock_t=yes + +# fs_cli +CONFIGURE_VARS+= \ + disable_cc=yes + +# Regarding apr_cv_mutex_robust_shared=no see +# http://www.openwall.com/lists/musl/2016/11/26/1 +ifeq ($(call qstrip,$(CONFIG_LIBC)),musl) +CONFIGURE_VARS+= \ + apr_cv_mutex_robust_shared=no \ + ac_cv_strerror_r_rc_int=yes +else +CONFIGURE_VARS+= \ + apr_cv_mutex_robust_shared=yes +endif + +ifneq ($(CONFIG_PACKAGE_freeswitch-misc-perl-esl)$(CONFIG_PACKAGE_freeswitch-mod-perl),) +CONFIGURE_VARS+= \ + PERL="$(STAGING_DIR_HOSTPKG)/usr/bin/perl$(PERL_VERSION)" \ + PERL_CFLAGS="-D_LARGEFILE_SOURCE $(if $(CONFIG_USE_MUSL),-D_LARGEFILE64_SOURCE) -D_FILE_OFFSET_BITS=64 -D_REENTRANT -D_GNU_SOURCE -I$(STAGING_DIR)$(PERL_SITELIB)/CORE" \ + PERL_INC="-I$(STAGING_DIR)$(PERL_SITELIB)/CORE" \ + PERL_LDFLAGS="-Wl,-rpath,$(PERL_SITELIB)/CORE -L$(STAGING_DIR)$(PERL_SITELIB)/CORE -lperl" \ + PERL_LIBDIR="-L$(PERL_SITELIB)/CORE" \ + PERL_LIBS="$(FS_PERL_LIBS) $(EXTRA_LIBDIRS:%=-L%) $(EXTRA_LIBS:%=-l%)" \ + PERL_SITEDIR="$(PERL_SITELIB)" +else +CONFIGURE_VARS+= \ + ac_cv_have_perl=no \ + ac_cv_prog_PERL=false +endif + +ifneq ($(CONFIG_PACKAGE_freeswitch-misc-python3-esl)$(CONFIG_PACKAGE_freeswitch-mod-python3),) +CONFIGURE_VARS+= \ + PYTHON3_CFLAGS="-I$(STAGING_DIR)/usr/include/python$(PYTHON3_VERSION)" \ + PYTHON3_LDFLAGS="-lpython$(PYTHON3_VERSION)" \ + PYTHON3_LIB="python$(PYTHON3_VERSION)" \ + PYTHON3_LIBDIR="$(FS_LIB_DIR)" \ + PYTHON3_SITE_DIR="$(FS_PYTHON3_SITE_DIR)" +endif + +# mod_radius_cdr runs configure in libs/freeradius-client. Let +# freeradius-client know /dev/urandom is available on target devices. +MAKE_VARS+= \ + ac_cv_dev_urandom=yes + +# Make sphinxbase use fixed point math when soft float support is +# enabled on target devices. +ifeq ($(CONFIG_SOFT_FLOAT),y) +MAKE_VARS+= \ + FS_USE_FIXED_POINT="--enable-fixed" +endif + +# Some common URLs +FS_LIBS_URL:=https://files.freeswitch.org/downloads/libs +FS_SPHINX_URL:=@SF/cmusphinx + +# mod_event_zmq +FS_ZEROMQ_FILE:=zeromq-2.1.9.tar.gz +FS_ZEROMQ_HASH:=f3542f756687e622beef3a75c8e027fe2d95d4654350cbca4c070ffc58d9ace0 +FS_ZEROMQ_URL:=http://download.zeromq.org + +# mod_pocketsphinx +FS_POCKETSPHINX_FILE:=pocketsphinx-0.8.tar.gz +FS_POCKETSPHINX_HASH:=874c4c083d91c8ff26a2aec250b689e537912ff728923c141c4dac48662cce7a + +FS_SPHINXBASE_FILE:=sphinxbase-0.8.tar.gz +FS_SPHINXBASE_HASH:=55708944872bab1015b8ae07b379bf463764f469163a8fd114cbb16c5e486ca8 + +FS_SPHINXMODEL_FILE:=communicator_semi_6000_20080321.tar.gz +FS_SPHINXMODEL_HASH:=dbb5e9fb85000a7cb97d6958a3ef8d77532dc55fc730ac6979705e8645cb0c18 + +# mod_radius_cdr +FS_FREERADIUS_CLIENT_FILE:=freeradius-client-1.1.7.tar.gz +FS_FREERADIUS_CLIENT_HASH:=eada2861b8f4928e3ac6b5bbfe11e92cd6cdcacfce40cae1085e77c1b6add0e9 + +ifneq ($(CONFIG_PACKAGE_freeswitch-mod-event-zmq),) +$(eval $(call Download/files,zmq,$(FS_ZEROMQ_FILE),$(FS_ZEROMQ_URL),$(FS_ZEROMQ_HASH))) +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))) +$(eval $(call Download/files,communicator,$(FS_SPHINXMODEL_FILE),$(FS_LIBS_URL),$(FS_SPHINXMODEL_HASH))) +endif + +ifneq ($(CONFIG_PACKAGE_freeswitch-mod-radius-cdr),) +$(eval $(call Download/files,freeradius-client,$(FS_FREERADIUS_CLIENT_FILE),$(FS_LIBS_URL),$(FS_FREERADIUS_CLIENT_HASH))) +endif + +define Build/Prepare + $(call Build/Prepare/Default) + + echo '#applications/mod_random' >> $(PKG_BUILD_DIR)/modules.conf + echo '#codecs/mod_yuv' >> $(PKG_BUILD_DIR)/modules.conf + echo '#event_handlers/mod_event_test' >> $(PKG_BUILD_DIR)/modules.conf +endef + +define Build/Configure + $(SED) '/^#/!s/^/#/' $(PKG_BUILD_DIR)/modules.conf + $(foreach m,$(FS_MOD_AVAILABLE), + $(if $(CONFIG_PACKAGE_freeswitch-mod-$(subst _,-,$(m))), + $(call Package/freeswitch/enable/plugin,mod_$(m)))) + +# Some of the dependencies that necessitate below hacks are documented in +# src/mod/Makefile.am. + +# Hack for misc-grammar - needs mod_pocketsphinx to provide grammar files +ifneq ($(CONFIG_PACKAGE_freeswitch-misc-grammar),) + $(call Package/freeswitch/enable/plugin,mod_pocketsphinx) +endif + +# Hack for mod_gsmopen - it has a build-time dep on mod_spandsp +ifneq ($(CONFIG_PACKAGE_freeswitch-mod-gsmopen),) + $(call Package/freeswitch/enable/plugin,mod_spandsp) +endif + +# Hack for mod_ssml - it has a build-time dep on mod_rayo. +ifneq ($(CONFIG_PACKAGE_freeswitch-mod-ssml),) + $(call Package/freeswitch/enable/plugin,mod_rayo) +endif + + $(call Build/Configure/Default) +endef + +define Build/Compile +# Copy some source files if certain modules are selected +ifneq ($(CONFIG_PACKAGE_freeswitch-mod-event-zmq),) + $(CP) $(DL_DIR)/$(FS_ZEROMQ_FILE) $(PKG_BUILD_DIR)/libs +endif + +ifneq ($(CONFIG_PACKAGE_freeswitch-mod-pocketsphinx)$(CONFIG_PACKAGE_freeswitch-misc-grammar),) + $(CP) $(DL_DIR)/$(FS_POCKETSPHINX_FILE) $(PKG_BUILD_DIR)/libs + $(CP) $(DL_DIR)/$(FS_SPHINXBASE_FILE) $(PKG_BUILD_DIR)/libs + $(CP) $(DL_DIR)/$(FS_SPHINXMODEL_FILE) $(PKG_BUILD_DIR)/libs +endif + +ifneq ($(CONFIG_PACKAGE_freeswitch-mod-radius-cdr),) + $(CP) $(DL_DIR)/$(FS_FREERADIUS_CLIENT_FILE) $(PKG_BUILD_DIR)/libs +endif + + $(call Build/Compile/Default) + +ifneq ($(CONFIG_PACKAGE_freeswitch-misc-perl-esl),) + $(call Build/Compile/Default,-C $(PKG_BUILD_DIR)/libs/esl perlmod) +endif +ifneq ($(CONFIG_PACKAGE_freeswitch-misc-python3-esl),) + $(call Build/Compile/Default,-C $(PKG_BUILD_DIR)/libs/esl py3mod) +endif +endef + +define Build/Install + $(call Build/Install/Default) +ifneq ($(CONFIG_PACKAGE_freeswitch-misc-perl-esl),) + $(call Build/Compile/Default,-C $(PKG_BUILD_DIR)/libs/esl DESTDIR=$(PKG_INSTALL_DIR) perlmod-install) +endif +ifneq ($(CONFIG_PACKAGE_freeswitch-misc-python3-esl),) + $(call Build/Install/Default,-C $(PKG_BUILD_DIR)/libs/esl py3mod-install) +endif +endef + +define Build/InstallDev + $(INSTALL_DIR) $(1)$(FS_INCLUDES_DIR) $(1)$(FS_LIB_DIR) \ + $(1)$(FS_PKGCONFIG_DIR) + $(INSTALL_DATA) $(PKG_INSTALL_DIR)$(FS_INCLUDES_DIR)/*.h \ + $(1)$(FS_INCLUDES_DIR) + $(INSTALL_DATA) \ + $(PKG_INSTALL_DIR)$(FS_PKGCONFIG_DIR)/freeswitch.pc \ + $(1)$(FS_PKGCONFIG_DIR) + $(CP) $(PKG_INSTALL_DIR)$(FS_LIB_DIR)/libfreeswitch.so* \ + $(1)$(FS_LIB_DIR) +endef + +$(eval $(call BuildPackage,freeswitch)) +$(eval $(call BuildPackage,freeswitch-misc-perl-esl)) +$(eval $(call BuildPackage,freeswitch-misc-python3-esl)) +$(eval $(call BuildPackage,freeswitch-misc-timezones)) + +################################ +# FreeSWITCH example configs +# Params: +# 1 - Package subname +################################ + +$(eval $(call Package/freeswitch/Example,curl)) +$(eval $(call Package/freeswitch/Example,insideout)) +$(eval $(call Package/freeswitch/Example,minimal)) +$(eval $(call Package/freeswitch/Example,rayo)) +$(eval $(call Package/freeswitch/Example,sbc)) +$(eval $(call Package/freeswitch/Example,softphone)) +$(eval $(call Package/freeswitch/Example,testing)) +$(eval $(call Package/freeswitch/Example,vanilla)) + +################################ +# FreeSWITCH language files +# Params: +# 1 - Language code +# 2 - Language +################################ + +$(eval $(call Package/freeswitch/Language,de,German)) +$(eval $(call Package/freeswitch/Language,en,English)) +$(eval $(call Package/freeswitch/Language,es,Spanish)) +$(eval $(call Package/freeswitch/Language,fr,French)) +$(eval $(call Package/freeswitch/Language,he,Hebrew)) +$(eval $(call Package/freeswitch/Language,pt,Portuguese)) +$(eval $(call Package/freeswitch/Language,ru,Russian)) +$(eval $(call Package/freeswitch/Language,sv,Swedish)) + +################################ +# FreeSWITCH misc packages +# Params: +# 1 - Package subname +# 2 - Package title +# 3 - Package description +# 4 - Source dir relative to +# PKG_INSTALL_DIR +# 5 - Dest dir relative to ipkg +# 6 - Arch independent files +################################ + +$(eval $(call Package/freeswitch/Misc,misc-fonts,Fonts,This package includes the fonts bundled with FreeSWITCH.,$(FS_FONTS_DIR),$(FS_FONTS_DIR),y)) +$(eval $(call Package/freeswitch/Misc,misc-grammar,Grammar,This package contains grammar files. mod_pocketsphinx would be a\npotential user.,$(FS_GRAMMAR_DIR),$(FS_GRAMMAR_DIR),y)) +$(eval $(call Package/freeswitch/Misc,misc-images,Images,This package includes the images bundled with FreeSWITCH.,$(FS_IMAGES_DIR),$(FS_IMAGES_DIR),y)) + +################################ +# FreeSWITCH modules +# Params: +# 1 - Package subname +# 2 - Package title +# 3 - Module description +# 4 - Module dependencies +################################ + +$(eval $(call Package/freeswitch/Module,abstraction,API abstraction,This module provides a way to create new API functions via regex\nrewriting.,)) +$(eval $(call Package/freeswitch/Module,alsa,ALSA endpoint,ALSA endpoint module.,+alsa-lib)) +$(eval $(call Package/freeswitch/Module,amr,AMR passthrough,Passthrough AMR codec support.,)) +$(eval $(call Package/freeswitch/Module,amrwb,AMR wideband passthrough,Passthrough AMR wideband codec support.,)) +$(eval $(call Package/freeswitch/Module,av,AV,Video codec and format support via FFmpeg.,+libffmpeg-full @x86_64)) +$(eval $(call Package/freeswitch/Module,avmd,Voicemail detection,This module attempts to determine when a voicemail system has answered\nthe call.,)) +$(eval $(call Package/freeswitch/Module,b64,Base64,Transfers data Base64 encoded.,)) +$(eval $(call Package/freeswitch/Module,basic,BASIC,BASIC module for FreeSWITCH.,)) +$(eval $(call Package/freeswitch/Module,bert,BERT,Line testing tool.,)) +$(eval $(call Package/freeswitch/Module,blacklist,Blacklist helper,This module provides tools to blacklist callers.,)) +$(eval $(call Package/freeswitch/Module,callcenter,Call center,This module implements Automated Call Distribution queues.,)) +$(eval $(call Package/freeswitch/Module,cdr_csv,CSV CDR,CSV Call Detail Record handler.,)) +$(eval $(call Package/freeswitch/Module,cdr_mongodb,MongoDB CDR,MongoDB Call Detail Record handler.,)) +$(eval $(call Package/freeswitch/Module,cdr_pg_csv,PostgreSQL CDR,PostgreSQL Call Detail Record handler.,+libpq)) +$(eval $(call Package/freeswitch/Module,cdr_sqlite,SQLite CDR,SQLite Call Detail Record handler.,)) +$(eval $(call Package/freeswitch/Module,cidlookup,Caller ID lookup,This module provides an API for querying caller ID name and location\ndata.,)) +$(eval $(call Package/freeswitch/Module,clearmode,Clearmode,Clearmode codec passthrough support.,)) +$(eval $(call Package/freeswitch/Module,cluechoo,Clue Choo,This demo module renders a Clue Choo train on the FreeSWITCH console.,+libncurses)) +$(eval $(call Package/freeswitch/Module,commands,Commands,This module provides miscellaneous API commands.,)) +$(eval $(call Package/freeswitch/Module,conference,Conference,This module provides multi-party conferencing.,)) +$(eval $(call Package/freeswitch/Module,console,Console logger,Allows control over what messages get logged to the console.,)) +$(eval $(call Package/freeswitch/Module,curl,cURL,This module provides an API for making HTTP requests with cURL.,)) +$(eval $(call Package/freeswitch/Module,dahdi_codec,DAHDI codec,DAHDI codec module.,)) +$(eval $(call Package/freeswitch/Module,db,DB,This module implements a simple db API with group support. Also can be\nused as a limit db backend.,)) +$(eval $(call Package/freeswitch/Module,dialplan_asterisk,Asterisk dialplan,Asterisk extensions.conf style dialplan parser.,)) +$(eval $(call Package/freeswitch/Module,dialplan_directory,Directory dialplan,Directory dialplan support.,)) +$(eval $(call Package/freeswitch/Module,dialplan_xml,XML dialplan,Standard FreeSWITCH XML dialplan support.,)) +$(eval $(call Package/freeswitch/Module,directory,Dial-by-name directory,This module implements a dial-by-name directory IVR.,)) +$(eval $(call Package/freeswitch/Module,distributor,Load distributor,This module implements a mechanism for performing load balancing.,)) +$(eval $(call Package/freeswitch/Module,dptools,Dialplan tools,This module implements basic dialplan tools.,)) +$(eval $(call Package/freeswitch/Module,easyroute,DID routing,This module does destination lookup based on DID.,)) +$(eval $(call Package/freeswitch/Module,enum,ENUM routing,This module implements ENUM support.,+libldns)) +$(eval $(call Package/freeswitch/Module,erlang_event,Erlang event,Erlang event module.,+erlang)) +$(eval $(call Package/freeswitch/Module,esf,Multicast,This module adds multi-cast support.,)) +$(eval $(call Package/freeswitch/Module,esl,Single ESL,This module adds an API for generating one-off ESL requests.,)) +$(eval $(call Package/freeswitch/Module,event_multicast,Multicast Event,Multicast Event System for FreeSWITCH.,)) +$(eval $(call Package/freeswitch/Module,event_socket,Event socket,Sends events via a single socket. Needed for fs_cli.,)) +$(eval $(call Package/freeswitch/Module,event_test,Event test,Event demo module.,)) +$(eval $(call Package/freeswitch/Module,event_zmq,ZMQ event,ZMQ event module.,)) +$(eval $(call Package/freeswitch/Module,expr,Expr,This module adds expr support for expression evaluation.,)) +$(eval $(call Package/freeswitch/Module,fail2ban,Fail2ban logging,Provides support for Fail2ban logging.,)) +$(eval $(call Package/freeswitch/Module,fifo,FIFO,This module adds a first-in first-out queue system.,)) +$(eval $(call Package/freeswitch/Module,format_cdr,Multiformat CDR,A superset of mod_json_cdr and mod_xml_cdr.,)) +$(eval $(call Package/freeswitch/Module,fsk,FSK,This module adds frequency-shift keying support which can be used to\nsend and receive caller ID.,)) +$(eval $(call Package/freeswitch/Module,fsv,FSV,This module provides dialplan applications for recording and playing\nvideos.,)) +$(eval $(call Package/freeswitch/Module,g723_1,G.723.1 passthrough,G.723.1 codec passthrough.,)) +$(eval $(call Package/freeswitch/Module,g729,G.729 passthrough,G.729 codec passthrough.,)) +$(eval $(call Package/freeswitch/Module,graylog2,Graylog2 logger,GELF logger for Graylog2 and Logstash.,)) +$(eval $(call Package/freeswitch/Module,gsmopen,GSM endpoint,GSMopen is a channel driver that allows an SMS to be sent to and from\nFreeSWITCH as well as incoming and outgoing GSM voice calls.,+gsmlib +libctb +libjpeg-turbo +libtiff)) +$(eval $(call Package/freeswitch/Module,h26x,H.26x passthrough,H.26x video codec passthrough.,)) +$(eval $(call Package/freeswitch/Module,hash,Hash,This module provides a key-value in-memory datastore. Usable as a\nlimit backend.,)) +$(eval $(call Package/freeswitch/Module,hiredis,Redis client,This module provides a mechanism to use Redis as a datastore.,+libhiredis)) +$(eval $(call Package/freeswitch/Module,httapi,HT-TAPI,This module provides an API for controlling the switch by responding\nto HTTP requests.,)) +$(eval $(call Package/freeswitch/Module,http_cache,HTTP GET with caching,This module provides an API for making HTTP GET requests where the\nresult is cached.,)) +$(eval $(call Package/freeswitch/Module,isac,iSAC,iSAC codec support.,@arm||i386||mips||mips64||mips64el||mipsel||x86_64)) +$(eval $(call Package/freeswitch/Module,json_cdr,JSON CDR,JSON-based Call Detail Record handler.,)) +$(eval $(call Package/freeswitch/Module,kazoo,Kazoo,Kazoo module for FreeSWITCH.,+erlang)) +$(eval $(call Package/freeswitch/Module,lcr,LCR,This module adds a facility for least-cost routing.,)) +$(eval $(call Package/freeswitch/Module,ldap,LDAP,LDAP module for FreeSWITCH.,+libopenldap)) +$(eval $(call Package/freeswitch/Module,local_stream,Local stream,Connects multiple channels to a looped stream.,)) +$(eval $(call Package/freeswitch/Module,logfile,File logger,Logs FreeSWITCH output to a file.,)) +$(eval $(call Package/freeswitch/Module,loopback,Loopback,A loopback channel driver.,)) +$(eval $(call Package/freeswitch/Module,lua,Lua,Lua language interface for FreeSWITCH.,+liblua)) +$(eval $(call Package/freeswitch/Module,mariadb,MariaDB,Adds MariaDB support.,+libmariadb)) +$(eval $(call Package/freeswitch/Module,mp4v,MP4 video passthrough,MP4 video passthrough.,)) +$(eval $(call Package/freeswitch/Module,native_file,Native file,Plays files that are already encoded in the right format.,)) +$(eval $(call Package/freeswitch/Module,nibblebill,Nibblebill,This module allows for real-time accounting of a cash balance and\nusing that information for call routing.,)) +$(eval $(call Package/freeswitch/Module,odbc_cdr,ODBC CDR,ODBC Call Detail Record handler.,)) +$(eval $(call Package/freeswitch/Module,opus,Opus,Opus codec support.,+libopus)) +$(eval $(call Package/freeswitch/Module,opusfile,Opus file,Read and Write OGG/Opus files.,+libopusenc +libopusfile)) +$(eval $(call Package/freeswitch/Module,oreka,Oreka,This module provides media recording with the Oreka cross-platform\naudio stream recording and retrieval system.,)) +$(eval $(call Package/freeswitch/Module,perl,Perl,This package contains mod_perl for FreeSWITCH.,+libdb47 +libgdbm +perlbase-essential @PERL_THREADS)) +$(eval $(call Package/freeswitch/Module,pgsql,PostgreSQL,Adds PostgreSQL support.,+libpq)) +$(eval $(call Package/freeswitch/Module,png,PNG,Allows playback of video using PNG files.,@FS_WITH_PNG)) +$(eval $(call Package/freeswitch/Module,pocketsphinx,Pocketsphinx,This module allows speech recognition. You might want to install\nfreeswitch-misc-grammar as well.,+libsamplerate)) # When libsamplerate is found it'll be linked against, there is no switch to turn it off +$(eval $(call Package/freeswitch/Module,portaudio,Portaudio,Voice through a local soundcard.,+portaudio)) +$(eval $(call Package/freeswitch/Module,portaudio_stream,Portaudio streaming,Stream from an external audio source for Music on Hold.,+portaudio)) +$(eval $(call Package/freeswitch/Module,posix_timer,POSIX timer,Add POSIX timer support.,)) +$(eval $(call Package/freeswitch/Module,prefix,Prefix match,This module provides a data store with fast lookups by the longest\nprefix match rule.,)) +$(eval $(call Package/freeswitch/Module,python3,Python3,Python3 support module.,+python3-light)) +$(eval $(call Package/freeswitch/Module,radius_cdr,Radius CDR,Radius Call Detail Record handler.,)) +$(eval $(call Package/freeswitch/Module,random,Entropy,This module extracts entropy from FreeSWITCH and feeds it into\n/dev/random.,)) +$(eval $(call Package/freeswitch/Module,raven,Raven logging,Adds support for logging to Raven instances.,)) +$(eval $(call Package/freeswitch/Module,rayo,Rayo,Rayo/XMPP 3PCC server for FreeSWITCH.,+freeswitch-mod-ssml)) +$(eval $(call Package/freeswitch/Module,redis,Redis limit backend,This module provides a mechanism to use Redis as a limit backend data\nstore.,)) +$(eval $(call Package/freeswitch/Module,rss,RSS,Parses and reads XML based RSS feeds and reads the entries aloud via a TTS engine.,)) +$(eval $(call Package/freeswitch/Module,rtc,Media streaming,Media streaming as used by WebRTC and mod_verto.,)) +$(eval $(call Package/freeswitch/Module,rtmp,RTMP endpoint,RTMP endpoint support. Allows FreeSWITCH to be used from RTMP clients.,)) +$(eval $(call Package/freeswitch/Module,say_de,German Say,Uses prerecorded sounds to read or say various things.,)) +$(eval $(call Package/freeswitch/Module,say_en,English Say,Uses prerecorded sounds to read or say various things.,)) +$(eval $(call Package/freeswitch/Module,say_es,Spanish Say,Uses prerecorded sounds to read or say various things.,)) +$(eval $(call Package/freeswitch/Module,say_es_ar,Argentinian Spanish Say,Uses prerecorded sounds to read or say various things.,)) +$(eval $(call Package/freeswitch/Module,say_fa,Persian Say,Uses prerecorded sounds to read or say various things.,)) +$(eval $(call Package/freeswitch/Module,say_fr,French Say,Uses prerecorded sounds to read or say various things.,)) +$(eval $(call Package/freeswitch/Module,say_he,Hebrew Say,Uses prerecorded sounds to read or say various things.,)) +$(eval $(call Package/freeswitch/Module,say_hr,Croatian Say,Uses prerecorded sounds to read or say various things.,)) +$(eval $(call Package/freeswitch/Module,say_hu,Hungarian Say,Uses prerecorded sounds to read or say various things.,)) +$(eval $(call Package/freeswitch/Module,say_it,Italian Say,Uses prerecorded sounds to read or say various things.,)) +$(eval $(call Package/freeswitch/Module,say_ja,Japanese Say,Uses prerecorded sounds to read or say various things.,)) +$(eval $(call Package/freeswitch/Module,say_nl,Dutch Say,Uses prerecorded sounds to read or say various things.,)) +$(eval $(call Package/freeswitch/Module,say_pl,Polish Say,Uses prerecorded sounds to read or say various things.,)) +$(eval $(call Package/freeswitch/Module,say_pt,Portuguese Say,Uses prerecorded sounds to read or say various things.,)) +$(eval $(call Package/freeswitch/Module,say_ru,Russian Say,Uses prerecorded sounds to read or say various things.,)) +$(eval $(call Package/freeswitch/Module,say_sv,Swedish Say,Uses prerecorded sounds to read or say various things.,)) +$(eval $(call Package/freeswitch/Module,say_th,Thai Say,Uses prerecorded sounds to read or say various things.,)) +$(eval $(call Package/freeswitch/Module,say_zh,Chinese Say,Uses prerecorded sounds to read or say various things.,)) +$(eval $(call Package/freeswitch/Module,shell_stream,Shell stream,Allows to stream audio from an arbitrary shell command.,)) +$(eval $(call Package/freeswitch/Module,shout,Shout,Allows to stream audio from MP3s or Shoutcast streams.,+lame-lib +libmpg123 +libshout)) +$(eval $(call Package/freeswitch/Module,signalwire,SignalWire,SignalWire CLOUD - FreeSWITCH connector.,+signalwire-client-c)) +$(eval $(call Package/freeswitch/Module,skinny,Skinny,Skinny Call Control Protocol endpoint support.,)) +$(eval $(call Package/freeswitch/Module,sms,SMS,This module provides an abstract facility for interfacing with SMS\nsystems.,)) +$(eval $(call Package/freeswitch/Module,snapshot,Snapshot,This module can record a sliding window of audio and take snapshots\nto disk.,)) +$(eval $(call Package/freeswitch/Module,sndfile,Soundfile,Adds sound format support via libsndfile.,+libsndfile)) +$(eval $(call Package/freeswitch/Module,snmp,SNMP,An SNMP stats reporter.,+libnetsnmp)) +$(eval $(call Package/freeswitch/Module,snom,SNOM,This module implements features specific to SNOM phones.,)) +$(eval $(call Package/freeswitch/Module,sofia,Sofia SIP,SIP module.,)) +$(eval $(call Package/freeswitch/Module,sonar,Sonar,This module measures the latency on an audio link by sending audible\naudio sonar pings.,)) +$(eval $(call Package/freeswitch/Module,spandsp,SpanDSP,This module implements SpanDSP fax. It includes DSP and codec\nfunctionality.,+libjpeg-turbo +liblzma +libtiff)) +$(eval $(call Package/freeswitch/Module,spy,User Spy,This module adds the ability to monitor the audio of a channel.,)) +$(eval $(call Package/freeswitch/Module,ssml,SSML,mod_ssml is a FreeSWITCH module that renders SSML into audio. This\nmodule requires a text-to-speech module for speech synthesis.,)) +$(eval $(call Package/freeswitch/Module,stress,Stress,This module attempts to detect voice stress on an audio channel.,)) +$(eval $(call Package/freeswitch/Module,syslog,Syslog logger,Logs FreeSWITCH output to the syslog.,)) +$(eval $(call Package/freeswitch/Module,theora,Theora passthrough,Theora video codec passthrough.,)) +$(eval $(call Package/freeswitch/Module,tone_stream,Tone stream,Tone generation stream.,)) +$(eval $(call Package/freeswitch/Module,translate,Number translation,This module implements number translation.,)) +$(eval $(call Package/freeswitch/Module,tts_commandline,TTS command-line,Run a command-line and play the output file.,)) +$(eval $(call Package/freeswitch/Module,valet_parking,Valet parking,This module implements the valet call parking strategy.,)) +$(eval $(call Package/freeswitch/Module,verto,Verto,Verto signaling protocol.,+libks)) +$(eval $(call Package/freeswitch/Module,video_filter,Video filter chromakey,This module provides a media bug for chromakey functionality.,)) +$(eval $(call Package/freeswitch/Module,vmd,Voicemail detection,This module detects voicemail beeps.,)) +$(eval $(call Package/freeswitch/Module,voicemail,Voicemail,This module provides a voicemail system.,)) +$(eval $(call Package/freeswitch/Module,voicemail_ivr,Voicemail IVR,This module provides an extensible voicemail IVR system.,)) +$(eval $(call Package/freeswitch/Module,xml_cdr,XML CDR,XML Call Detail Record handler.,)) +$(eval $(call Package/freeswitch/Module,xml_curl,XML cURL,Provides an XML cURL interfaces to pull dynamic XML configuration for\nFreeSWITCH over HTTP.,)) +$(eval $(call Package/freeswitch/Module,xml_ldap,XML LDAP,LDAP XML gateway.,+libopenldap)) +$(eval $(call Package/freeswitch/Module,xml_rpc,XML RPC,Allows using the webapi to control FreeSWITCH.,)) +$(eval $(call Package/freeswitch/Module,xml_scgi,XML SCGI,SCGI XML Gateway.,)) +$(eval $(call Package/freeswitch/Module,yaml,YAML,YAML language module.,+libyaml)) +$(eval $(call Package/freeswitch/Module,yuv,Raw YUV,Raw YUV I420 video codec support.,@FS_WITH_LIBYUV)) + +################################ +# FreeSWITCH utilities +# Params: +# 1 - Package subname +# 2 - Package title +# 3 - Utility description +# 4 - Utility dependencies +# 5 - Utility is a script (y/n) +################################ + +$(eval $(call Package/freeswitch/Util,fs_cli,CLI,The fs_cli program is a Command-Line Interface that allows a user to\nconnect to a FreeSWITCH instance running on the local or a remote\nsystem.,,n)) +$(eval $(call Package/freeswitch/Util,fs_encode,Sound file conversion,Format conversion of sound files so the result can be used by\nmod_native_file.,+freeswitch-mod-native-file +freeswitch-mod-sndfile +freeswitch-mod-spandsp,n)) +$(eval $(call Package/freeswitch/Util,fs_ivrd,IVR daemon,The FreeSWITCH IVR daemon is an abstraction layer that sits on top of\nthe ESL. The basic idea is that the ivrd will allow the user to have\na STDIN/STDOUT interface for simple call control.,,n)) +$(eval $(call Package/freeswitch/Util,fs_tts,TTS to sound file,Use TTS to generate a sound file.,,n)) +$(eval $(call Package/freeswitch/Util,gentls_cert,TLS certificate,Can be used to create TLS certificates and setup CAs.,+openssl-util,y)) +$(eval $(call Package/freeswitch/Util,tone2wav,Sound file generation,Generates a sound file from a teletone script. The output can be in\nany format that is supported by libsndfile.,+freeswitch-mod-sndfile,n)) diff --git a/net/freeswitch/files/freeswitch.conf b/net/freeswitch/files/freeswitch.conf new file mode 100644 index 000000000..13a142de1 --- /dev/null +++ b/net/freeswitch/files/freeswitch.conf @@ -0,0 +1,22 @@ + +config freeswitch 'general' + option enabled '0' + option log_stderr '1' + option log_stdout '1' + option options '-nonat -np' + #option term_timeout '10' # seconds to wait after sending TERM signal + +config freeswitch 'directories' + option cache '/tmp/freeswitch/cache' + option db '/tmp/freeswitch/db' + option log '/tmp/freeswitch/log' + option recordings '/tmp/freeswitch/recordings' + option storage '/tmp/freeswitch/storage' + option temp '/tmp/freeswitch/temp' + +config freeswitch 'hotplug' + #option interface 'wan' + #option mount_point '/mnt/usb' + option ntpd '0' + option timeout '60' + diff --git a/net/freeswitch/files/freeswitch.hotplug b/net/freeswitch/files/freeswitch.hotplug new file mode 100644 index 000000000..93b5a20ee --- /dev/null +++ b/net/freeswitch/files/freeswitch.hotplug @@ -0,0 +1,142 @@ +#!/bin/sh + +NAME=freeswitch +COMMAND=/etc/init.d/$NAME + +LOGGER="/usr/bin/logger -t $NAME-hotplug" +LOG_ERR="$LOGGER -p daemon.err --" +LOG_INFO="$LOGGER -p daemon.info --" +LOG_WARN="$LOGGER -p daemon.warn --" + +[ "$ACTION" = ifup ] || exit 0 + +. /lib/functions.sh +config_load $NAME + +config_get interface hotplug interface + +[ "$INTERFACE" = "$interface" ] || exit 0 + +pidof $NAME &> /dev/null +if [ $? -eq 0 ]; then + $LOG_INFO stopping $NAME + $COMMAND stop &> /dev/null +fi + +config_get timeout hotplug timeout 60 + +[ "$timeout" -gt 0 ] 2> /dev/null || unset timeout +timeout="${timeout:-60}" + +config_get mount_point hotplug mount_point + +# Mount condition, idea lifted from OpenWrt Wiki +[ -n "$mount_point" ] && { + + if ! [ -d "$mount_point" ]; then + $LOG_ERR "$mount_point" not a valid mount point + exit 1 + fi + + mnt="$mount_point" + notReady=start + tmp_timeout=$timeout + + while [ -n "$notReady" -a $tmp_timeout -gt 0 ]; do + if [ "$notReady" != start ]; then + $LOG_INFO "$mnt" not yet mounted, timeout in $tmp_timeout s + sleep 5 + tmp_timeout=$(($tmp_timeout-5)) + fi + + notReady= + + result=$(cat /proc/mounts | awk '{print $2}' | grep "^$mnt\$") + if [ -z "$result" ]; then + notReady="$mnt not ready yet" + fi + done + + if [ -n "$notReady" ]; then + $LOG_ERR "$mnt" still not mounted + $LOG_ERR not starting $NAME + exit 1 + else + $LOG_INFO "$mnt" mounted + fi + +} + +config_get_bool ntpd hotplug ntpd 0 + +# ntpd condition +[ $ntpd -eq 1 ] && { + + type ntpq &> /dev/null + [ $? -eq 0 ] || { + $LOG_ERR ntpq utility not found + exit 1 + } + + pidof ntpd &> /dev/null || { + $LOG_ERR ntpd not running + exit 1 + } + + notReady=start + tmp_timeout=$timeout + + while [ -n "$notReady" -a $tmp_timeout -gt 0 ]; do + if [ "$notReady" != start ]; then + $LOG_INFO system time not in sync yet, timeout in $tmp_timeout s + sleep 5 + tmp_timeout=$(($tmp_timeout-5)) + fi + + notReady= + + result=$(ntpq -c 'timeout 300' -c 'rv 0 stratum' 2> /dev/null | \ + awk -F '=' '{print $2}' | grep -o -E '^[0-9]+') + if [ -z $result ]; then + $LOG_WARN failed to extract stratum from ntpd + notReady="unable to extract stratum" + else + $LOG_INFO ntpd stratum $result + if [ $result -lt 16 ] 2> /dev/null; then + result=$(ntpq -c 'timeout 300' -c 'rv 0 offset' 2> /dev/null \ + | awk -F '=' '{print $2}' | grep -o -E '^[-+]?[0-9]+') + if [ -z $result ]; then + $LOG_WARN failed to extract offset from ntpd + notReady="unable to extract offset" + else + # "-0" looks stupid, so remove "-" + result=$(echo $result | grep -o '[0-9]*') + $LOG_INFO ntpd to system time offset \+\/\- $result ms + # If offset < 100 ms consider system time in sync + [ $result -lt 100 ] || notReady="system time not in sync yet" + fi + else + notReady="ntpd not in sync yet" + fi + fi + done + + if [ -n "$notReady" ]; then + $LOG_ERR system time still not in sync + $LOG_ERR not starting $NAME + exit 1 + else + $LOG_INFO system time in sync + fi + +} + +$COMMAND start &> /dev/null +sleep 1 +pidof $NAME &>/dev/null +if [ $? -eq 0 ]; then + $LOG_INFO started $NAME due to \"ifup "$INTERFACE"\" event +else + $LOG_ERR start of $NAME due to \"ifup "$INTERFACE"\" event failed + exit 1 +fi diff --git a/net/freeswitch/files/freeswitch.init b/net/freeswitch/files/freeswitch.init new file mode 100644 index 000000000..f2b0c9c13 --- /dev/null +++ b/net/freeswitch/files/freeswitch.init @@ -0,0 +1,102 @@ +#!/bin/sh /etc/rc.common +# Copyright (C) 2017 - 2018 OpenWrt.org + +START=90 +STOP=10 + +USE_PROCD=1 + +#PROCD_DEBUG=1 + +NAME=freeswitch +COMMAND=/usr/bin/$NAME + +LOGGER="/usr/bin/logger -s -t $NAME" +LOG_ERR="$LOGGER -p daemon.err --" +LOG_WARN="$LOGGER -p daemon.warn --" +LOG_INFO="$LOGGER -p daemon.info --" + +start_service() { + dir_etc=/etc/$NAME + dir_localstate=/var/lib/$NAME + dir_run=/var/run/$NAME + + config_load $NAME + + config_get_bool enabled general enabled 0 + if [ $enabled -eq 0 ]; then + $LOG_ERR service not enabled in /etc/config/$NAME + return 1 + fi + + config_get_bool log_stderr general log_stderr 1 + config_get_bool log_stdout general log_stdout 1 + + config_get dir_cache directories cache /tmp/$NAME/cache + config_get dir_db directories db /tmp/$NAME/db + config_get dir_log directories log /tmp/$NAME/log + config_get dir_recordings directories recordings /tmp/$NAME/recordings + config_get dir_storage directories storage /tmp/$NAME/storage + config_get dir_temp directories temp /tmp/$NAME/temp + + config_get options general options + + config_get term_timeout general term_timeout default + if [ default = "$term_timeout" ]; then + $LOG_INFO using procd\'s default term_timeout + elif ! [ 0 -lt "$term_timeout" ] 2>/dev/null; then + $LOG_ERR invalid term_timeout in /etc/config/$NAME + return 1 + fi + + for i in "$dir_localstate" "$dir_run"; do + if ! [ -e "$i" ]; then + mkdir -m 0750 -p "$i" + [ -d "$i" ] && chown $NAME:$NAME "$i" + fi + done + + command -v su >/dev/null + ret=$? + if [ 0 != "$ret" ]; then + $LOG_WARN utility \"su\" not available + $LOG_WARN will not attempt to create directories + else + for i in "$dir_cache" \ + "$dir_db" \ + "$dir_log" \ + "$dir_recordings" \ + "$dir_storage" \ + "$dir_temp"; + do + if ! [ -e "$i" ]; then + su -s /bin/sh -c "mkdir -m 0750 -p \"$i\"" $NAME + fi + done + fi + + procd_open_instance + # starting with full path seems cleaner judging by 'ps' output + procd_set_param command $COMMAND + # need to specify all or none of -conf, -log, and -db + procd_append_param command \ + -cache "$dir_cache" \ + -conf "$dir_etc" \ + -db "$dir_db" \ + -log "$dir_log" \ + -recordings "$dir_recordings" \ + -run "$dir_run" \ + -storage "$dir_storage" \ + -temp "$dir_temp" \ + -u "$NAME" \ + $options \ + -c + # forward stderr to logd + procd_set_param stderr $log_stderr + # same for stdout + procd_set_param stdout $log_stdout + if ! [ default = "$term_timeout" ]; then + procd_set_param term_timeout "$term_timeout" + fi + procd_close_instance +} diff --git a/net/freeswitch/patches/003-modmake-fix.patch b/net/freeswitch/patches/003-modmake-fix.patch new file mode 100644 index 000000000..dbe524b34 --- /dev/null +++ b/net/freeswitch/patches/003-modmake-fix.patch @@ -0,0 +1,13 @@ +--- a/build/modmake.rulesam ++++ b/build/modmake.rulesam +@@ -1,8 +1,8 @@ + AUTOMAKE_OPTIONS = foreign subdir-objects + AM_CFLAGS = $(SWITCH_AM_CFLAGS) $(SWITCH_ANSI_CFLAGS) +-AM_CPPFLAGS = $(SWITCH_AM_CXXFLAGS) ++AM_CPPFLAGS = $(SWITCH_AM_CPPFLAGS) + AM_LDFLAGS = $(SWITCH_AM_LDFLAGS) +-DEFAULT_VARS = CFLAGS="$(CFLAGS)" CPPFLAGS="$(CXXFLAGS)" LDFLAGS="$(LDFLAGS)" CC="$(CC)" CXX="$(CXX)" ++DEFAULT_VARS = CFLAGS="$(CFLAGS)" CPPFLAGS="$(CPPFLAGS)" CXXFLAGS="$(CXXFLAGS)" LDFLAGS="$(LDFLAGS)" CC="$(CC)" CXX="$(CXX)" + DEFAULT_ARGS = --build=$(build) --host=$(host) --target=$(target) --prefix="$(prefix)" --exec_prefix="$(exec_prefix)" --libdir="$(libdir)" --disable-shared --with-pic + + moddir=@modulesdir@ diff --git a/net/freeswitch/patches/030-fix-configure-ac.patch b/net/freeswitch/patches/030-fix-configure-ac.patch new file mode 100644 index 000000000..9ac3a02d9 --- /dev/null +++ b/net/freeswitch/patches/030-fix-configure-ac.patch @@ -0,0 +1,57 @@ +--- a/configure.ac ++++ b/configure.ac +@@ -256,30 +256,6 @@ AX_COMPILER_VENDOR + # Set CC_FOR_BUILD + if test "x${cross_compiling}" = "xyes"; then + CC_FOR_BUILD=${CC_FOR_BUILD-gcc} +- case "$host" in +- arm*-linux-gnueabi*|arm*-*-linux-gnueabi*) +- # spandsp modem +- ac_cv_file__dev_ptmx=yes +- # libjs +- export ac_cv_va_copy=yes +- # srtp +- export ac_cv_file__dev_urandom=yes +- # rpl_malloc +- export ac_cv_func_realloc_0_nonnull=yes +- export ac_cv_func_malloc_0_nonnull=yes +- # apr +- export ac_cv_func_setpgrp_void=yes +- export ac_cv_file__dev_zero=yes +- export apr_cv_tcp_nodelay_with_cork=yes +- export ac_cv_file_dbd_apr_dbd_mysql_c=no +- export ac_cv_sizeof_ssize_t=4 +- export apr_cv_mutex_recursive=yes +- export ac_cv_func_pthread_rwlock_init=yes +- export apr_cv_type_rwlock_t=yes +- export apr_cv_process_shared_works=yes +- export apr_cv_mutex_robust_shared=yes +- ;; +- esac + else + CC_FOR_BUILD='$(CC)' + fi +@@ -650,7 +626,7 @@ path_push_unique () { + fi + } + +-AC_PATH_PROG([PG_CONFIG], [pg_config], [no]) ++AC_PATH_PROG([PG_CONFIG], [pg_config], [no], ["${STAGING_DIR}"/usr/bin]) + AC_PATH_PROG([PKG_CONFIG], [pkg-config], [no]) + + case $host in +@@ -1683,13 +1659,7 @@ AC_CHECK_PROG(PERL,perl,[ac_cv_have_perl + # -a "x$ac_cv_have_EXTERN_h" != "xno" + + if test "x$ac_cv_have_perl" != "xno"; then +- PERL=perl +- PERL_SITEDIR="`$PERL -MConfig -e 'print $Config{archlib}'`" +- PERL_LIBDIR="-L`$PERL -MConfig -e 'print $Config{archlib}'`/CORE" +- PERL_LIBS="`$PERL -MConfig -e 'print $Config{libs}'`" +- PERL_CFLAGS="-w -DMULTIPLICITY `$PERL -MExtUtils::Embed -e ccopts | sed -e 's|-arch x86_64 -arch i386||'` -DEMBED_PERL" +- PERL_LDFLAGS="`$PERL -MExtUtils::Embed -e ldopts| sed -e 's|-arch x86_64 -arch i386||'`" +- PERL_INC="`$PERL -MExtUtils::Embed -e perl_inc`" ++ PERL_CFLAGS="-w -DMULTIPLICITY ${PERL_CFLAGS} -DEMBED_PERL" + + save_CFLAGS="$CFLAGS" + CFLAGS="$PERL_CFLAGS" diff --git a/net/freeswitch/patches/050-c++.patch b/net/freeswitch/patches/050-c++.patch new file mode 100644 index 000000000..e8dbb62a4 --- /dev/null +++ b/net/freeswitch/patches/050-c++.patch @@ -0,0 +1,35 @@ +From 8cf93d9c15b7138c69ffbaba2681b32bc18cf5b2 Mon Sep 17 00:00:00 2001 +From: Sebastian Kemper +Date: Sun, 1 Aug 2021 11:32:50 +0200 +Subject: [PATCH] [mod_gsmopen]: Address gsmlib gcc-11 compat issue + +With gcc-11 mod_gsmopen fails to compile: + +In file included from /home/sk/tmp/openwrt/staging_dir/target-mips_24kc_musl/usr/include/gsmlib/gsm_sms.h:18, + from gsmopen_protocol.cpp:44: +/home/sk/tmp/openwrt/staging_dir/target-mips_24kc_musl/usr/include/gsmlib/gsm_error.h:84:58: error: ISO C++17 does not allow dynamic exception specifications + 84 | extern std::string getMEErrorText(const int errorCode) throw(GsmException); + | ^~~~~ +/home/sk/tmp/openwrt/staging_dir/target-mips_24kc_musl/usr/include/gsmlib/gsm_error.h:165:59: error: ISO C++17 does not allow dynamic exception specifications + 165 | extern std::string getSMSErrorText(const int errorCode) throw(GsmException); + | ^~~~~ + +gsmlib has seen no upstream activity in years, so as a workaround this +commit adds "--std=c++11" to mod_gsmopen's CXXFLAGS. + +Signed-off-by: Sebastian Kemper +--- + src/mod/endpoints/mod_gsmopen/Makefile.am | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/src/mod/endpoints/mod_gsmopen/Makefile.am ++++ b/src/mod/endpoints/mod_gsmopen/Makefile.am +@@ -3,7 +3,7 @@ MODNAME=mod_gsmopen + + mod_LTLIBRARIES = mod_gsmopen.la + mod_gsmopen_la_SOURCES = mod_gsmopen.cpp gsmopen_protocol.cpp +-mod_gsmopen_la_CXXFLAGS = $(SWITCH_AM_CXXFLAGS) ++mod_gsmopen_la_CXXFLAGS = $(SWITCH_AM_CXXFLAGS) --std=c++11 + mod_gsmopen_la_CPPFLAGS = $(SPANDSP_CFLAGS) -I. + mod_gsmopen_la_LIBADD = $(switch_builddir)/libfreeswitch.la $(SPANDSP_LIBS) + mod_gsmopen_la_LDFLAGS = -avoid-version -module -no-undefined -lctb-0.16 -lgsmme diff --git a/net/freeswitch/patches/110-apr-add-cache-for-strerror_r.patch b/net/freeswitch/patches/110-apr-add-cache-for-strerror_r.patch new file mode 100644 index 000000000..2aa7f937e --- /dev/null +++ b/net/freeswitch/patches/110-apr-add-cache-for-strerror_r.patch @@ -0,0 +1,30 @@ +--- a/libs/apr/build/apr_common.m4 ++++ b/libs/apr/build/apr_common.m4 +@@ -514,8 +514,9 @@ dnl string. + dnl + dnl + AC_DEFUN([APR_CHECK_STRERROR_R_RC],[ +-AC_MSG_CHECKING(for type of return code from strerror_r) +-AC_TRY_RUN([ ++AC_CACHE_CHECK([whether return code from strerror_r has type int], ++[ac_cv_strerror_r_rc_int], ++[AC_TRY_RUN([ + #include + #include + #include +@@ -534,14 +535,10 @@ int main(void) + }], [ + ac_cv_strerror_r_rc_int=yes ], [ + ac_cv_strerror_r_rc_int=no ], [ +- ac_cv_strerror_r_rc_int=no ] ) ++ ac_cv_strerror_r_rc_int=no ] ) ] ) + if test "x$ac_cv_strerror_r_rc_int" = xyes; then + AC_DEFINE(STRERROR_R_RC_INT, 1, [Define if strerror returns int]) +- msg="int" +-else +- msg="pointer" + fi +-AC_MSG_RESULT([$msg]) + ] ) + + dnl diff --git a/net/freeswitch/patches/120-fix-copts.patch b/net/freeswitch/patches/120-fix-copts.patch new file mode 100644 index 000000000..e56ae6448 --- /dev/null +++ b/net/freeswitch/patches/120-fix-copts.patch @@ -0,0 +1,68 @@ +--- a/configure.ac ++++ b/configure.ac +@@ -2300,7 +2300,12 @@ AC_SUBST(OUR_DISABLED_INSTALL_MODS) + AC_SUBST(OUR_DISABLED_UNINSTALL_MODS) + AC_SUBST(AM_MAKEFLAGS) + +-ac_configure_args="$ac_configure_args --with-modinstdir=${modulesdir} CONFIGURE_CFLAGS='$CFLAGS $CPPFLAGS' CONFIGURE_CXXFLAGS='$CXXFLAGS $CPPFLAGS' CONFIGURE_LDFLAGS='$LDFLAGS' " ++APR_ADDTO(CONFIGURE_CFLAGS, [$CFLAGS]) ++APR_ADDTO(CONFIGURE_CPPFLAGS, [$CPPFLAGS]) ++APR_ADDTO(CONFIGURE_CXXFLAGS, [$CXXFLAGS]) ++APR_ADDTO(CONFIGURE_LDFLAGS, [$LDFLAGS]) ++ ++ac_configure_args="$ac_configure_args --with-modinstdir=${modulesdir} CONFIGURE_CFLAGS='$CONFIGURE_CFLAGS' CONFIGURE_CPPFLAGS='$CONFIGURE_CPPFLAGS' CONFIGURE_CXXFLAGS='$CONFIGURE_CXXFLAGS' CONFIGURE_LDFLAGS='$CONFIGURE_LDFLAGS' " + + # --prefix='$prefix' --exec_prefix='$exec_prefix' --libdir='$libdir' --libexecdir='$libexecdir' --bindir='$bindir' --sbindir='$sbindir' \ + # --localstatedir='$localstatedir' --datadir='$datadir'" +--- a/libs/apr/configure.ac ++++ b/libs/apr/configure.ac +@@ -20,9 +20,10 @@ sinclude(build/apr_hints.m4) + sinclude(build/libtool.m4) + sinclude(build/ltsugar.m4) + +-CFLAGS="$CFLAGS $CONFIGURE_CFLAGS" +-CXXFLAGS="$CXXFLAGS $CONFIGURE_CXXFLAGS" +-LDFLAGS="$LDFLAGS $CONFIGURE_LDFLAGS" ++APR_ADDTO(CFLAGS, [$CONFIGURE_CFLAGS]) ++APR_ADDTO(CPPFLAGS, [$CONFIGURE_CPPFLAGS]) ++APR_ADDTO(CXXFLAGS, [$CONFIGURE_CXXFLAGS]) ++APR_ADDTO(LDFLAGS, [$CONFIGURE_LDFLAGS]) + + dnl Hard-coded inclusion at the tail end of fspr_private.h: + AH_BOTTOM([ +--- a/libs/iksemel/configure.ac ++++ b/libs/iksemel/configure.ac +@@ -6,9 +6,12 @@ AC_CONFIG_SRCDIR([configure.ac]) + AM_INIT_AUTOMAKE + AC_CONFIG_HEADERS(include/config.h) + +-CFLAGS="$CFLAGS $CONFIGURE_CFLAGS" +-CXXFLAGS="$CXXFLAGS $CONFIGURE_CXXFLAGS" +-LDFLAGS="$LDFLAGS $CONFIGURE_LDFLAGS" ++m4_include(../apr/build/apr_common.m4) ++ ++APR_ADDTO(CFLAGS, [$CONFIGURE_CFLAGS]) ++APR_ADDTO(CPPFLAGS, [$CONFIGURE_CPPFLAGS]) ++APR_ADDTO(CXXFLAGS, [$CONFIGURE_CXXFLAGS]) ++APR_ADDTO(LDFLAGS, [$CONFIGURE_LDFLAGS]) + + AC_CANONICAL_HOST + +--- a/libs/srtp/configure.ac ++++ b/libs/srtp/configure.ac +@@ -3,9 +3,12 @@ AC_INIT(srtp, 2.4.0, mcgrew@cisco.com) + AC_CONFIG_AUX_DIR(build) + AM_INIT_AUTOMAKE + +-CFLAGS="$CFLAGS $CONFIGURE_CFLAGS" +-CXXFLAGS="$CXXFLAGS $CONFIGURE_CXXFLAGS" +-LDFLAGS="$LDFLAGS $CONFIGURE_LDFLAGS" ++m4_include(../apr/build/apr_common.m4) ++ ++APR_ADDTO(CFLAGS, [$CONFIGURE_CFLAGS]) ++APR_ADDTO(CPPFLAGS, [$CONFIGURE_CPPFLAGS]) ++APR_ADDTO(CXXFLAGS, [$CONFIGURE_CXXFLAGS]) ++APR_ADDTO(LDFLAGS, [$CONFIGURE_LDFLAGS]) + + #Set default language + AC_LANG_C diff --git a/net/freeswitch/patches/130-fix-iksemel-copts.patch b/net/freeswitch/patches/130-fix-iksemel-copts.patch new file mode 100644 index 000000000..005b7a49d --- /dev/null +++ b/net/freeswitch/patches/130-fix-iksemel-copts.patch @@ -0,0 +1,9 @@ +--- a/libs/iksemel/src/Makefile.am ++++ b/libs/iksemel/src/Makefile.am +@@ -25,5 +25,5 @@ libiksemel_la_SOURCES = \ + base64.c + + libiksemel_la_LDFLAGS = -version-info 4:0:1 -no-undefined +-libiksemel_la_CFLAGS = $(CFLAGS) $(LIBGNUTLS_CFLAGS) ++libiksemel_la_CFLAGS = $(LIBGNUTLS_CFLAGS) + libiksemel_la_LIBADD = $(LIBGNUTLS_LIBS) diff --git a/net/freeswitch/patches/140-libvpx-cross.patch b/net/freeswitch/patches/140-libvpx-cross.patch new file mode 100644 index 000000000..6c7a4a9f3 --- /dev/null +++ b/net/freeswitch/patches/140-libvpx-cross.patch @@ -0,0 +1,19 @@ +--- a/Makefile.am ++++ b/Makefile.am +@@ -557,8 +557,15 @@ src/include/switch_version.h: src/includ + libs/libedit/src/.libs/libedit.a: + cd libs/libedit && $(MAKE) + ++# !!! OpenWrt was here !!! ++# - added CROSS and set target to generic-gnu for cross-compile ++# - added CPPFLAGS to CFLAGS, otherwise they would be ignored ++# - disabled optimizations that would override OpenWrt's CFLAGS ++# - disabled the building of tools (because they fail to build and we ++# don't need them anyway) ++ + libs/libvpx/Makefile: libs/libvpx/.update +- cd libs/libvpx && CC="$(CC)" CXX="$(CXX)" CFLAGS="$(CFLAGS) $(VISIBILITY_FLAG)" CXXFLAGS="$(CXXFLAGS)" LDFLAGS="$(LDFLAGS)" ./configure --enable-pic --disable-docs --disable-examples --disable-install-bins --disable-install-srcs --disable-unit-tests --size-limit=16384x16384 ++ cd libs/libvpx && CROSS="$(CROSS)" CC="$(CC)" CXX="$(CXX)" CFLAGS="$(CFLAGS) $(CPPFLAGS) $(VISIBILITY_FLAG)" CXXFLAGS="$(CXXFLAGS)" LDFLAGS="$(LDFLAGS)" ./configure --target=generic-gnu --disable-optimizations --enable-pic --disable-docs --disable-examples --disable-install-bins --disable-install-srcs --disable-tools --disable-unit-tests --size-limit=16384x16384 + + libs/libvpx/libvpx.a: libs/libvpx/Makefile libs/libvpx/.update + @cd libs/libvpx && $(MAKE) diff --git a/net/freeswitch/patches/150-erlang-m4.patch b/net/freeswitch/patches/150-erlang-m4.patch new file mode 100644 index 000000000..893af8632 --- /dev/null +++ b/net/freeswitch/patches/150-erlang-m4.patch @@ -0,0 +1,23 @@ +--- a/build/config/erlang.m4 ++++ b/build/config/erlang.m4 +@@ -43,9 +43,20 @@ then + ERLANG_LDFLAGS="-L$ERLANG_LIBDIR $ERLANG_LDFLAGS" + LIBS="-L$ERLANG_LIBDIR $LIBS" + fi ++ ++ # ++ # Don't use the above ERLANG_LDFLAGS ++ # ++ ERLANG_LIBDIR="$STAGING_DIR/usr/lib" ++ ERLANG_LDFLAGS="-L$ERLANG_LIBDIR" ++ LIBS="-L$ERLANG_LIBDIR $LIBS" + AC_MSG_RESULT([$ERLANG_LIBDIR]) + + ERLANG_INCDIR=`$ERLANG -noshell -eval 'io:format("~n~s/include~n", [[code:lib_dir("erl_interface")]]).' -s erlang halt | tail -n 1` ++ # ++ # Don't use the above ERLANG_INCDIR ++ # ++ ERLANG_INCDIR="$STAGING_DIR/usr/include" + AC_MSG_CHECKING([erlang incdir]) + if test -z "`echo $ERLANG_INCDIR`" ; then + AC_MSG_ERROR([failed]) diff --git a/net/freeswitch/patches/170-mod_random.patch b/net/freeswitch/patches/170-mod_random.patch new file mode 100644 index 000000000..ea8596521 --- /dev/null +++ b/net/freeswitch/patches/170-mod_random.patch @@ -0,0 +1,10 @@ +--- a/src/mod/applications/mod_random/Makefile.am ++++ b/src/mod/applications/mod_random/Makefile.am +@@ -3,6 +3,6 @@ MODNAME=mod_random + + mod_LTLIBRARIES = mod_random.la + mod_random_la_SOURCES = mod_random.c +-mod_random_la_CFLAGS = $(AM_CFLAGS) ++mod_random_la_CFLAGS = $(AM_CFLAGS) -Wno-cpp + mod_random_la_LIBADD = $(switch_builddir)/libfreeswitch.la + mod_random_la_LDFLAGS = -avoid-version -module -no-undefined -shared diff --git a/net/freeswitch/patches/180-mod_perl.patch b/net/freeswitch/patches/180-mod_perl.patch new file mode 100644 index 000000000..cc036ea23 --- /dev/null +++ b/net/freeswitch/patches/180-mod_perl.patch @@ -0,0 +1,37 @@ +--- a/src/mod/languages/mod_perl/Makefile.am ++++ b/src/mod/languages/mod_perl/Makefile.am +@@ -1,8 +1,5 @@ + include $(top_srcdir)/build/modmake.rulesam + MODNAME=mod_perl +-PERL = perl +-PERL_LIBDIR =-L`perl -MConfig -e 'print $$Config{archlib}'`/CORE +-PERL_LIBS =`perl -MConfig -e 'print $$Config{libs}'` + + perldir=$(prefix)/perl + mod_LTLIBRARIES = mod_perl.la +@@ -10,13 +7,13 @@ perl_LTLIBRARIES = freeswitch.la + mod_perl_la_SOURCES = mod_perl.c freeswitch_perl.cpp mod_perl_wrap.cpp perlxsi.c + mod_perl_la_CFLAGS = $(SWITCH_AM_CFLAGS) + mod_perl_la_CXXFLAGS = $(SWITCH_AM_CXXFLAGS) +-mod_perl_la_CPPFLAGS = -w -DMULTIPLICITY `$(PERL) -MExtUtils::Embed -e ccopts` -DEMBED_PERL -I$(switch_srcdir)/libs/libteletone/src/ ++mod_perl_la_CPPFLAGS = @PERL_CFLAGS@ -I$(switch_srcdir)/libs/libteletone/src/ + mod_perl_la_LIBADD = $(switch_builddir)/libfreeswitch.la +-mod_perl_la_LDFLAGS = -avoid-version -module -no-undefined -shared `$(PERL) -MExtUtils::Embed -e ldopts` `$(PERL) -MConfig -e 'print $$Config{libs}'` ++mod_perl_la_LDFLAGS = -avoid-version -module -no-undefined -shared @PERL_LDFLAGS@ @PERL_LIBS@ + + freeswitch_la_SOURCES = freeswitch_perl.cpp mod_perl_wrap.cpp perlxsi.c + freeswitch_la_LDFLAGS = -avoid-version -module -no-undefined -shared $(LDFLAGS) +-freeswitch_la_CPPFLAGS = $(SWITCH_AM_CPPFLAGS) -w -DMULTIPLICITY `$(PERL) -MExtUtils::Embed -e ccopts` -DEMBED_PERL -I$(switch_srcdir)/libs/libteletone/src/ ++freeswitch_la_CPPFLAGS = $(SWITCH_AM_CPPFLAGS) @PERL_CFLAGS@ -I$(switch_srcdir)/libs/libteletone/src/ + reswig: swigclean mod_perl_wrap.cpp + + swigclean: clean +@@ -31,7 +28,7 @@ orig: mod_perl_wrap.cpp + patch -R -s -p0 -i hack.diff + + .perlok: +- @(${PERL} -V | grep -i usemultiplicity=define >/dev/null && echo Phew, You have the right perl.) \ ++ @(@PERL@ -V | grep -i usemultiplicity=define >/dev/null && echo Phew, You have the right perl.) \ + || ((echo Sorry, you need to compile perl with threads and multiplicity.&& exit 1)) + @touch .perlok + diff --git a/net/freeswitch/patches/190-mod_pocketsphinx.patch b/net/freeswitch/patches/190-mod_pocketsphinx.patch new file mode 100644 index 000000000..55731c62d --- /dev/null +++ b/net/freeswitch/patches/190-mod_pocketsphinx.patch @@ -0,0 +1,20 @@ +--- a/src/mod/asr_tts/mod_pocketsphinx/Makefile.am ++++ b/src/mod/asr_tts/mod_pocketsphinx/Makefile.am +@@ -27,7 +27,7 @@ $(SPHINXBASE_DIR): + + $(SPHINXBASE_BUILDDIR)/Makefile: $(SPHINXBASE_DIR) + mkdir -p $(SPHINXBASE_BUILDDIR) +- (cd $(SPHINXBASE_BUILDDIR) && $(DEFAULT_VARS) $(SPHINXBASE_DIR)/configure $(DEFAULT_ARGS) --srcdir=$(SPHINXBASE_DIR) --without-python CFLAGS=) ++ (cd $(SPHINXBASE_BUILDDIR) && sed -i 's|$$(srcdir)/||g' test/regression/Makefile.am && autoreconf -v -f -i -s && $(DEFAULT_VARS) ac_cv_header_alsa_asoundlib_h=no ac_cv_header_jack_jack_h=no ac_cv_header_pulse_pulseaudio_h=no $(SPHINXBASE_DIR)/configure $(DEFAULT_ARGS) --srcdir=$(SPHINXBASE_DIR) --without-python $(FS_USE_FIXED_POINT)) + $(TOUCH_TARGET) + + $(SPHINXBASE_BUILDDIR)/buildstamp: $(SPHINXBASE_BUILDDIR)/Makefile +@@ -45,7 +45,7 @@ $(POCKETSPHINX_DIR): + + $(POCKETSPHINX_BUILDDIR)/Makefile: $(POCKETSPHINX_DIR) $(SPHINXBASE_LA) $(SPHINXBASE_LA2) + mkdir -p $(POCKETSPHINX_BUILDDIR) +- (cd $(POCKETSPHINX_BUILDDIR) && $(DEFAULT_VARS) $(POCKETSPHINX_DIR)/configure $(DEFAULT_ARGS) --srcdir=$(POCKETSPHINX_DIR) --without-python --with-sphinxbase=$(SPHINXBASE_DIR) --with-sphinxbase-build=$(SPHINXBASE_BUILDDIR) CFLAGS=-Wno-return-type) ++ (cd $(POCKETSPHINX_BUILDDIR) && autoreconf -v -f -i -s && $(DEFAULT_VARS) $(POCKETSPHINX_DIR)/configure $(DEFAULT_ARGS) --srcdir=$(POCKETSPHINX_DIR) --without-python --with-sphinxbase=$(SPHINXBASE_DIR) --with-sphinxbase-build=$(SPHINXBASE_BUILDDIR)) + $(TOUCH_TARGET) + + $(POCKETSPHINX_BUILDDIR)/buildstamp: $(POCKETSPHINX_BUILDDIR)/Makefile diff --git a/net/freeswitch/patches/200-mod_verto-fix-copts.patch b/net/freeswitch/patches/200-mod_verto-fix-copts.patch new file mode 100644 index 000000000..44549ec8d --- /dev/null +++ b/net/freeswitch/patches/200-mod_verto-fix-copts.patch @@ -0,0 +1,13 @@ +--- a/src/mod/endpoints/mod_verto/Makefile.am ++++ b/src/mod/endpoints/mod_verto/Makefile.am +@@ -13,8 +13,8 @@ if HAVE_PERL + #perldir = $(PERL_SITEDIR) + noinst_LTLIBRARIES = MCAST.la + MCAST_la_SOURCES = mcast/mcast_wrap.cpp mcast/perlxsi.c mcast/mcast.c mcast/mcast_cpp.cpp +-MCAST_la_CFLAGS = $(CC_CFLAGS) $(CFLAGS) $(SWITCH_AM_CFLAGS) $(PERL_CFLAGS) +-MCAST_la_CXXFLAGS = $(SWITCH_AM_CXXFLAGS) $(CXXFLAGS) -w $(PERL_INC) ++MCAST_la_CFLAGS = $(CC_CFLAGS) $(SWITCH_AM_CFLAGS) $(PERL_CFLAGS) ++MCAST_la_CXXFLAGS = $(SWITCH_AM_CXXFLAGS) $(PERL_CFLAGS) -w $(PERL_INC) + MCAST_la_CPPFLAGS = -I$(switch_srcdir)/src/mod/endpoints/mod_verto/mcast + MCAST_la_LDFLAGS = -avoid-version -module -no-undefined -shared $(PERL_LDFLAGS) + diff --git a/net/freeswitch/patches/210-esl-perl-fix-copts.patch b/net/freeswitch/patches/210-esl-perl-fix-copts.patch new file mode 100644 index 000000000..4b03ea33f --- /dev/null +++ b/net/freeswitch/patches/210-esl-perl-fix-copts.patch @@ -0,0 +1,13 @@ +--- a/libs/esl/perl/Makefile.am ++++ b/libs/esl/perl/Makefile.am +@@ -2,8 +2,8 @@ if HAVE_PERL + perldir = $(PERL_SITEDIR) + perl_LTLIBRARIES = ESL.la + ESL_la_SOURCES = esl_wrap.cpp perlxsi.c +-ESL_la_CFLAGS = $(CC_CFLAGS) $(CFLAGS) -I$(switch_srcdir)/libs/esl/src/include $(SWITCH_AM_CFLAGS) $(PERL_CFLAGS) +-ESL_la_CXXFLAGS = -I$(switch_srcdir)/libs/esl/src/include $(SWITCH_AM_CXXFLAGS) $(CXXFLAGS) -w $(PERL_INC) ++ESL_la_CFLAGS = $(CC_CFLAGS) -I$(switch_srcdir)/libs/esl/src/include $(SWITCH_AM_CFLAGS) $(PERL_CFLAGS) ++ESL_la_CXXFLAGS = -I$(switch_srcdir)/libs/esl/src/include $(SWITCH_AM_CXXFLAGS) $(PERL_CFLAGS) -w $(PERL_INC) + ESL_la_LDFLAGS = -avoid-version -module -no-undefined -shared $(PERL_LDFLAGS) + ESL_la_LIBADD = ../libesl.la + diff --git a/net/freeswitch/patches/230-mod_radius_cdr.patch b/net/freeswitch/patches/230-mod_radius_cdr.patch new file mode 100644 index 000000000..b6645d409 --- /dev/null +++ b/net/freeswitch/patches/230-mod_radius_cdr.patch @@ -0,0 +1,35 @@ +--- a/src/mod/event_handlers/mod_radius_cdr/Makefile.am ++++ b/src/mod/event_handlers/mod_radius_cdr/Makefile.am +@@ -20,7 +20,7 @@ $(RADCLIENT_DIR): + + $(RADCLIENT_BUILDDIR)/Makefile: $(RADCLIENT_DIR) + mkdir -p $(RADCLIENT_BUILDDIR) +- cd $(RADCLIENT_BUILDDIR) && $(DEFAULT_VARS) $(RADCLIENT_DIR)/configure $(DEFAULT_ARGS) --srcdir=$(RADCLIENT_DIR) ++ cd $(RADCLIENT_BUILDDIR) && patch -N -p1 < ../../src/mod/event_handlers/mod_radius_cdr/freeradius-client-1.1.6-configure-in.diff || echo "Assuming patch was applied previously" && autoreconf -v -f -i -s && $(DEFAULT_VARS) CFLAGS="${CFLAGS} -Wno-cpp" $(RADCLIENT_DIR)/configure $(DEFAULT_ARGS) --srcdir=$(RADCLIENT_DIR) + $(TOUCH_TARGET) + + $(RADCLIENT_LA): $(RADCLIENT_BUILDDIR)/Makefile +--- /dev/null ++++ b/src/mod/event_handlers/mod_radius_cdr/freeradius-client-1.1.6-configure-in.diff +@@ -0,0 +1,21 @@ ++--- a/configure.in +++++ b/configure.in ++@@ -234,13 +234,11 @@ AC_LINK_IFELSE([AC_LANG_PROGRAM([ ++ enable_getrandom=getentropy], ++ [AC_MSG_RESULT(no)]) ++ ++-AC_MSG_CHECKING([for /dev/urandom]) ++-if test -c /dev/urandom ++-then ++- AC_MSG_RESULT(yes) ++- AC_DEFINE(HAVE_DEV_URANDOM) ++-else ++- AC_MSG_RESULT(no) +++AC_CACHE_CHECK([/dev/urandom], [ac_cv_dev_urandom], +++ [ac_cv_dev_urandom=no +++ if test -c /dev/urandom; then ac_cv_dev_urandom=yes; fi]) +++if test $ac_cv_dev_urandom = yes; then +++ AC_DEFINE(HAVE_DEV_URANDOM) ++ fi ++ ++ AC_ARG_WITH([nettle], [AS_HELP_STRING([--with-nettle], diff --git a/net/freeswitch/patches/260-mod_event_zmq-fix-build-with-fortify-headers.patch b/net/freeswitch/patches/260-mod_event_zmq-fix-build-with-fortify-headers.patch new file mode 100644 index 000000000..a2df8e71a --- /dev/null +++ b/net/freeswitch/patches/260-mod_event_zmq-fix-build-with-fortify-headers.patch @@ -0,0 +1,10 @@ +--- a/src/mod/event_handlers/mod_event_zmq/Makefile.am ++++ b/src/mod/event_handlers/mod_event_zmq/Makefile.am +@@ -22,6 +22,7 @@ $(ZMQ_DIR): + $(GETLIB) $(ZMQ_BASEURL) $(ZMQ).tar.gz || $(GETLIB) $(ZMQ_BASEURL_ALT) $(ZMQ).tar.gz + sed -e 's:AM_CONFIG_HEADER:AC_CONFIG_HEADERS:' $(ZMQ_DIR)/configure.in > $(ZMQ_DIR)/configure.in.tmp && \ + mv $(ZMQ_DIR)/configure.in.tmp $(ZMQ_DIR)/configure.in ++ sed -i '/^libzmq_pedantic="yes"/s/yes/no/' $(ZMQ_DIR)/configure.in + cd $(ZMQ_DIR) && ./autogen.sh + + $(ZMQ_BUILDDIR)/Makefile: $(ZMQ_DIR) diff --git a/net/freeswitch/patches/320-workaround-format-truncation-error-in-mod_cdr_mongodb.patch b/net/freeswitch/patches/320-workaround-format-truncation-error-in-mod_cdr_mongodb.patch new file mode 100644 index 000000000..2a9382182 --- /dev/null +++ b/net/freeswitch/patches/320-workaround-format-truncation-error-in-mod_cdr_mongodb.patch @@ -0,0 +1,29 @@ +--- a/configure.ac ++++ b/configure.ac +@@ -363,6 +363,16 @@ if test "$ax_cv_c_compiler_vendor" = "gn + [ac_cv_gcc_supports_w_no_misleading_indentation=no])]) + CFLAGS="$saved_CFLAGS" + AC_MSG_RESULT($ac_cv_gcc_supports_w_no_misleading_indentation) ++ ++ saved_CFLAGS="$CFLAGS" ++ AC_CACHE_CHECK([whether compiler supports -Wno-error=format-truncation], ++ [ac_cv_gcc_supports_w_no_err_format_truncation], [ ++ CFLAGS="$CFLAGS -Wno-error=format-truncation" ++ AC_TRY_COMPILE([],[return 0;], ++ [ac_cv_gcc_supports_w_no_err_format_truncation=yes], ++ [ac_cv_gcc_supports_w_no_err_format_truncation=no])]) ++ CFLAGS="$saved_CFLAGS" ++ AC_MSG_RESULT($ac_cv_gcc_supports_w_no_err_format_truncation) + fi + + # tweak compiler specific flags +@@ -402,6 +412,9 @@ elif test "x${ax_cv_c_compiler_vendor}" + if test "$ac_cv_gcc_supports_w_no_misleading_indentation" = yes; then + APR_ADDTO(SWITCH_AM_CFLAGS, -Wno-misleading-indentation) + fi ++ if test "$ac_cv_gcc_supports_w_no_err_format_truncation" = yes; then ++ APR_ADDTO(SWITCH_AM_CFLAGS, -Wno-error=format-truncation) ++ fi + if test "${enable_64}" = "yes"; then + case "$host" in + *darwin*) diff --git a/net/freeswitch/patches/360-fix-APR_TRY_COMPILE_NO_WARNING.patch b/net/freeswitch/patches/360-fix-APR_TRY_COMPILE_NO_WARNING.patch new file mode 100644 index 000000000..403e87bf3 --- /dev/null +++ b/net/freeswitch/patches/360-fix-APR_TRY_COMPILE_NO_WARNING.patch @@ -0,0 +1,25 @@ +--- a/libs/apr/build/apr_common.m4 ++++ b/libs/apr/build/apr_common.m4 +@@ -493,13 +493,15 @@ AC_DEFUN([APR_TRY_COMPILE_NO_WARNING], + if test "$ac_cv_prog_gcc" = "yes"; then + CFLAGS="$CFLAGS -Werror" + fi +- AC_COMPILE_IFELSE([AC_LANG_SOURCE([ +- [#include "confdefs.h" +- ] +- [[$1]] +- [int main(int argc, const char *const *argv) {] +- [[$2]] +- [ return 0; }]])], ++ AC_COMPILE_IFELSE( ++ [AC_LANG_SOURCE( ++ [#include "confdefs.h" ++ ] ++ [[$1]] ++ [int main(int argc, const char *const *argv) {] ++ [[$2]] ++ [ return 0; }] ++ )], + [$3], [$4]) + CFLAGS=$apr_save_CFLAGS + ]) diff --git a/net/freeswitch/patches/370-procd-compat.patch b/net/freeswitch/patches/370-procd-compat.patch new file mode 100644 index 000000000..bdc212bfa --- /dev/null +++ b/net/freeswitch/patches/370-procd-compat.patch @@ -0,0 +1,19 @@ +--- a/src/switch_console.c ++++ b/src/switch_console.c +@@ -1052,10 +1052,12 @@ static void *SWITCH_THREAD_FUNC console_ + while (running) { + int32_t arg = 0; + +- if (getppid() == 1) { +- switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "We've become an orphan, no more console for us.\n"); +- break; +- } ++ // Parent PID is 1 when started by procd - so FS is not an orphan. ++ // Plus we still want the output. ++ //if (getppid() == 1) { ++ // switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "We've become an orphan, no more console for us.\n"); ++ // break; ++ //} + + switch_core_session_ctl(SCSC_CHECK_RUNNING, &arg); + if (!arg) { diff --git a/net/freeswitch/patches/380-disable-luajit.patch b/net/freeswitch/patches/380-disable-luajit.patch new file mode 100644 index 000000000..37ecd16f5 --- /dev/null +++ b/net/freeswitch/patches/380-disable-luajit.patch @@ -0,0 +1,11 @@ +--- a/configure.ac ++++ b/configure.ac +@@ -571,7 +571,7 @@ AC_SUBST(SYS_XMLRPC_CFLAGS) + AC_SUBST(SYS_XMLRPC_LDFLAGS) + AM_CONDITIONAL([SYSTEM_XMLRPCC],[test "${enable_xmlrpcc}" = "yes"]) + +-for luaversion in luajit lua5.3 lua-5.3 lua53 lua5.2 lua-5.2 lua52 lua5.1 lua-5.1 lua; do ++for luaversion in lua5.3 lua-5.3 lua53 lua5.2 lua-5.2 lua52 lua5.1 lua-5.1 lua; do + PKG_CHECK_MODULES([LUA],[${luaversion}],[have_lua=yes],[have_lua=no]) + if test ${have_lua} = yes; then + break diff --git a/net/freeswitch/patches/390-spandsp3-pkg-config.patch b/net/freeswitch/patches/390-spandsp3-pkg-config.patch new file mode 100644 index 000000000..5cb61d469 --- /dev/null +++ b/net/freeswitch/patches/390-spandsp3-pkg-config.patch @@ -0,0 +1,11 @@ +--- a/configure.ac ++++ b/configure.ac +@@ -700,7 +700,7 @@ PKG_CHECK_MODULES([MARIADB], [libmariadb + ]) + ]) + +-PKG_CHECK_MODULES([SPANDSP], [spandsp >= 3.0],[ ++PKG_CHECK_MODULES([SPANDSP], [spandsp3 >= 3.0],[ + AM_CONDITIONAL([HAVE_SPANDSP],[true])],[ + AC_MSG_ERROR([no usable spandsp; please install spandsp3 devel package or equivalent]) + ]) diff --git a/net/freeswitch/patches/400-fix-pc-file.patch b/net/freeswitch/patches/400-fix-pc-file.patch new file mode 100644 index 000000000..d0ba2e284 --- /dev/null +++ b/net/freeswitch/patches/400-fix-pc-file.patch @@ -0,0 +1,13 @@ +--- a/build/freeswitch.pc.in ++++ b/build/freeswitch.pc.in +@@ -1,8 +1,8 @@ + prefix=@prefix@ + exec_prefix=@exec_prefix@ +-libdir=@libdir@ ++libdir=${exec_prefix}/lib + libexecdir=@libexecdir@ +-includedir=@includedir@ ++includedir=${prefix}/include/freeswitch + modulesdir=@modulesdir@ + runtimedir=@runtimedir@ + logfiledir=@logfiledir@ diff --git a/net/freeswitch/patches/460-remove-python-configure-checks.patch b/net/freeswitch/patches/460-remove-python-configure-checks.patch new file mode 100644 index 000000000..1a577a526 --- /dev/null +++ b/net/freeswitch/patches/460-remove-python-configure-checks.patch @@ -0,0 +1,46 @@ +--- a/configure.ac ++++ b/configure.ac +@@ -1876,36 +1876,24 @@ then + fi + AC_MSG_RESULT([$PYTHON3_VER]) + +- AC_MSG_CHECKING([for python3 distutils]) +- python3_result="`$PYTHON3 -c 'import distutils;' 2>&1`" +- if test -z "$python3_result" ; then ++ #AC_MSG_CHECKING([for python3 distutils]) ++ #python3_result="`$PYTHON3 -c 'import distutils;' 2>&1`" ++ #if test -z "$python3_result" ; then + python3_has_distutils="yes" +- else +- python3_has_distutils="no" +- fi +- AC_MSG_RESULT([$python3_has_distutils]) ++ #else ++ # python3_has_distutils="no" ++ #fi ++ #AC_MSG_RESULT([$python3_has_distutils]) + + if test "$python3_has_distutils" != "no" ; then + AC_MSG_CHECKING([location of python3 site-packages]) + +- PYTHON3_SITE_DIR="`$PYTHON3 -c 'from distutils import sysconfig; print(sysconfig.get_python_lib(0));'`" +- + if test -z "$PYTHON3_SITE_DIR" ; then + AC_MSG_ERROR([Unable to detect python3 site-packages path]) +- elif test ! -d "$PYTHON3_SITE_DIR" ; then +- AC_MSG_ERROR([Path $PYTHON3_SITE_DIR returned by python3 does not exist!]) + fi + AC_MSG_RESULT([$PYTHON3_SITE_DIR]) + AC_SUBST([PYTHON3_SITE_DIR], [$PYTHON3_SITE_DIR]) + +- # +- # python3 distutils found, get settings from python3 directly +- # +- PYTHON3_CFLAGS="`$PYTHON3 -c 'from distutils import sysconfig; flags = [[\"-I\" + sysconfig.get_python_inc(0), \"-I\" + sysconfig.get_python_inc(1), \" \".join(sysconfig.get_config_var(\"CFLAGS\").split())]]; print(\" \".join(flags));' | sed -e 's/-arch i386//g;s/-arch x86_64//g'`" +- PYTHON3_LDFLAGS="`$PYTHON3 -c 'from distutils import sysconfig; ldver = sysconfig.get_config_var(\"LDVERSION\"); libs = sysconfig.get_config_var(\"LIBS\").split() + sysconfig.get_config_var(\"SYSLIBS\").split(); libs.append(\"-lpython\" + [[ldver,sysconfig.get_config_var(\"VERSION\")]][[ldver==None]]); print(\" \".join(libs));'`" +- PYTHON3_LIB="`$PYTHON3 -c 'from distutils import sysconfig; ldver = sysconfig.get_config_var(\"LDVERSION\"); print(\"python\" + [[ldver,sysconfig.get_config_var(\"VERSION\")]][[ldver==None]]);'`" +- PYTHON3_LIBDIR="`$PYTHON3 -c 'from distutils import sysconfig; print(sysconfig.get_config_var(\"LIBDIR\"));'`" +- + # handle python3 being installed into /usr/local + AC_MSG_CHECKING([python3 libdir]) + if test -z "`echo $PYTHON3_LIBDIR | grep "/usr/lib"`" ; then diff --git a/net/freeswitch/patches/470-esl-python.patch b/net/freeswitch/patches/470-esl-python.patch new file mode 100644 index 000000000..a02dc09b0 --- /dev/null +++ b/net/freeswitch/patches/470-esl-python.patch @@ -0,0 +1,43 @@ +--- a/libs/esl/Makefile.am ++++ b/libs/esl/Makefile.am +@@ -82,7 +82,7 @@ pymod: $(MYLIB) + $(MAKE) PYTHON=$(PYTHON) MYLIB="../$(MYLIB)" SOLINK="$(SOLINK)" CFLAGS="-I$(switch_srcdir)/libs/esl/src/include $(SWITCH_AM_CFLAGS)" CXXFLAGS="-I$(switch_srcdir)/libs/esl/src/include $(SWITCH_AM_CXXFLAGS)" CXX_CFLAGS="$(CXX_CFLAGS)" -C python + + py3mod: $(MYLIB) +- $(MAKE) PYTHON3=$(PYTHON3) MYLIB="../$(MYLIB)" SOLINK="$(SOLINK)" CFLAGS="-I$(switch_srcdir)/libs/esl/src/include $(SWITCH_AM_CFLAGS)" CXXFLAGS="-I$(switch_srcdir)/libs/esl/src/include $(SWITCH_AM_CXXFLAGS)" CXX_CFLAGS="$(CXX_CFLAGS)" -C python3 ++ $(MAKE) PYTHON3=$(PYTHON3) MYLIB="../$(MYLIB)" SOLINK="$(SOLINK)" CFLAGS="-I$(switch_srcdir)/libs/esl/src/include $(SWITCH_AM_CFLAGS)" CXXFLAGS="-I$(switch_srcdir)/libs/esl/src/include $(SWITCH_AM_CXXFLAGS)" CXX_CFLAGS="$(CXX_CFLAGS)" PYTHON3_CFLAGS="$(PYTHON3_CFLAGS)" PYTHON3_LDFLAGS="$(PYTHON3_LDFLAGS)" -C python3 + + tclmod: $(MYLIB) + $(MAKE) MYLIB="../$(MYLIB)" SOLINK="$(SOLINK)" CFLAGS="-I$(switch_srcdir)/libs/esl/src/include $(SWITCH_AM_CFLAGS)" CXXFLAGS="-I$(switch_srcdir)/libs/esl/src/include $(SWITCH_AM_CXXFLAGS)" CXX_CFLAGS="$(CXX_CFLAGS)" -C tcl +@@ -106,7 +106,7 @@ pymod-install: pymod + $(MAKE) PYTHON=$(PYTHON) -C python install + + py3mod-install: py3mod +- $(MAKE) PYTHON3=$(PYTHON3) -C python3 install ++ $(MAKE) PYTHON3=$(PYTHON3) PYTHON3_SITE_DIR="$(PYTHON3_SITE_DIR)" -C python3 install + + rubymod-install: rubymod + $(MAKE) -C ruby install +--- a/libs/esl/python3/Makefile ++++ b/libs/esl/python3/Makefile +@@ -1,6 +1,4 @@ +-LOCAL_CFLAGS=`$(PYTHON3) ./python-config --includes` +-LOCAL_LDFLAGS=`$(PYTHON3) ./python-config --ldflags` +-SITE_DIR=$(DESTDIR)/`$(PYTHON3) -c "from distutils.sysconfig import get_python_lib; print (get_python_lib(1))"` ++SITE_DIR=$(DESTDIR)/$(PYTHON3_SITE_DIR) + + all: _ESL.so + +@@ -8,10 +6,10 @@ esl_wrap.cpp: + swig3.0 -module ESL -classic -python -c++ -DMULTIPLICITY -threads -I../src/include -o esl_wrap.cpp ../ESL.i + + esl_wrap.o: esl_wrap.cpp +- $(CXX) $(CXX_CFLAGS) $(CXXFLAGS) $(LOCAL_CFLAGS) -c esl_wrap.cpp -o esl_wrap.o ++ $(CXX) $(CXX_CFLAGS) $(CXXFLAGS) $(PYTHON3_CFLAGS) -c esl_wrap.cpp -o esl_wrap.o + + _ESL.so: esl_wrap.o +- $(CXX) $(SOLINK) esl_wrap.o $(MYLIB) $(LOCAL_LDFLAGS) -o _ESL.so -L. $(LIBS) ++ $(CXX) $(SOLINK) esl_wrap.o $(MYLIB) $(PYTHON3_LDFLAGS) -o _ESL.so -L. $(LIBS) + + install: _ESL.so + mkdir -p $(SITE_DIR) diff --git a/net/freeswitch/patches/490-build-properly-fix-time_t-issues.patch b/net/freeswitch/patches/490-build-properly-fix-time_t-issues.patch new file mode 100644 index 000000000..9ead97ff8 --- /dev/null +++ b/net/freeswitch/patches/490-build-properly-fix-time_t-issues.patch @@ -0,0 +1,177 @@ +From 80492dcd5a6a859cf4bfc7d22ba594c64e94e3fd Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?=C3=89rico=20Nogueira?= +Date: Wed, 27 Oct 2021 20:38:28 -0300 +Subject: [PATCH] [build] properly fix time_t issues + +aa71d87528643fd1b3897a64ecec8c11e92b5b55 tried fixing the issue by +adding yet another case to the TIME_T_FMT definition, but hardcoding +values as hinted at by internal variables or by platform is not future +proof or allows for improvements. + +The most portable fix for time_t handling is to always cast it to +(long long) for printing and use "lld" for formatting. +--- + src/include/switch_platform.h | 20 +++----------------- + src/mod/applications/mod_httapi/mod_httapi.c | 2 +- + src/mod/endpoints/mod_sofia/sofia_presence.c | 3 ++- + src/switch_channel.c | 20 ++++++++++---------- + src/switch_ivr_originate.c | 2 +- + 5 files changed, 17 insertions(+), 30 deletions(-) + +--- a/src/include/switch_platform.h ++++ b/src/include/switch_platform.h +@@ -245,10 +245,6 @@ typedef intptr_t switch_ssize_t; + #define SWITCH_INT64_T_FMT "lld" + #define SWITCH_UINT64_T_FMT "llu" + +-#ifndef TIME_T_FMT +-#define TIME_T_FMT SWITCH_INT64_T_FMT +-#endif +- + #else + #ifndef SWITCH_SSIZE_T_FMT + #define SWITCH_SSIZE_T_FMT (sizeof (switch_ssize_t) == sizeof (long) ? "ld" : sizeof (switch_ssize_t) == sizeof (int) ? "d" : "lld") +@@ -266,25 +262,15 @@ typedef intptr_t switch_ssize_t; + #define SWITCH_UINT64_T_FMT (sizeof (long) == 8 ? "lu" : "llu") + #endif + +-#ifndef TIME_T_FMT +-#if defined(__FreeBSD__) && SIZEOF_VOIDP == 4 +-#define TIME_T_FMT "d" +-#else +-#if __USE_TIME_BITS64 +-#define TIME_T_FMT SWITCH_INT64_T_FMT +-#else +-#define TIME_T_FMT "ld" +-#endif +-#endif +-#endif +- +- + #if UINTPTR_MAX == 0xffffffffffffffff + #define FS_64BIT 1 + #endif + + #endif + ++#define TIME_T_FMT "lld" ++#define TIME_T_CAST(x) ((long long)(x)) ++ + #if defined(__sun__) && (defined(__x86_64) || defined(__arch64__)) + #define SWITCH_TIME_T_FMT SWITCH_SIZE_T_FMT + #else +--- a/src/mod/applications/mod_httapi/mod_httapi.c ++++ b/src/mod/applications/mod_httapi/mod_httapi.c +@@ -2742,7 +2742,7 @@ static switch_status_t write_meta_file(h + + switch_snprintf(write_data, sizeof(write_data), + "%" TIME_T_FMT ":%s", +- switch_epoch_time_now(NULL) + ttl, ++ TIME_T_CAST(switch_epoch_time_now(NULL) + ttl), + data); + + +--- a/src/mod/endpoints/mod_sofia/sofia_presence.c ++++ b/src/mod/endpoints/mod_sofia/sofia_presence.c +@@ -4198,7 +4198,8 @@ void sofia_presence_handle_sip_i_subscri + sql = switch_mprintf("insert into sip_dialogs (sip_from_user,sip_from_host,call_info,call_info_state,hostname,expires,rcd,profile_name) " + "values ('%q','%q','%q','seized','%q',%"TIME_T_FMT",%ld,'%q')", + to_user, to_host, switch_str_nil(p), mod_sofia_globals.hostname, +- switch_epoch_time_now(NULL) + exp_delta, (long)now, profile->name); ++ TIME_T_CAST(switch_epoch_time_now(NULL) + exp_delta), (long)now, ++ profile->name); + + if (mod_sofia_globals.debug_sla > 1) { + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "SEIZE SQL %s\n", sql); +--- a/src/switch_channel.c ++++ b/src/switch_channel.c +@@ -4662,39 +4662,39 @@ SWITCH_DECLARE(switch_status_t) switch_c + + tt_created = (time_t) (caller_profile->times->created / 1000000); + mtt_created = (time_t) (caller_profile->times->created / 1000); +- switch_snprintf(tmp, sizeof(tmp), "%" TIME_T_FMT, tt_created); ++ switch_snprintf(tmp, sizeof(tmp), "%" TIME_T_FMT, TIME_T_CAST(tt_created)); + switch_channel_set_variable(channel, "start_epoch", tmp); + switch_snprintf(tmp, sizeof(tmp), "%" SWITCH_TIME_T_FMT, caller_profile->times->created); + switch_channel_set_variable(channel, "start_uepoch", tmp); + + tt_prof_created = (time_t) (caller_profile->times->profile_created / 1000000); +- switch_snprintf(tmp, sizeof(tmp), "%" TIME_T_FMT, tt_prof_created); ++ switch_snprintf(tmp, sizeof(tmp), "%" TIME_T_FMT, TIME_T_CAST(tt_prof_created)); + switch_channel_set_variable(channel, "profile_start_epoch", tmp); + switch_snprintf(tmp, sizeof(tmp), "%" SWITCH_TIME_T_FMT, caller_profile->times->profile_created); + switch_channel_set_variable(channel, "profile_start_uepoch", tmp); + + tt_answered = (time_t) (caller_profile->times->answered / 1000000); + mtt_answered = (time_t) (caller_profile->times->answered / 1000); +- switch_snprintf(tmp, sizeof(tmp), "%" TIME_T_FMT, tt_answered); ++ switch_snprintf(tmp, sizeof(tmp), "%" TIME_T_FMT, TIME_T_CAST(tt_answered)); + switch_channel_set_variable(channel, "answer_epoch", tmp); + switch_snprintf(tmp, sizeof(tmp), "%" SWITCH_TIME_T_FMT, caller_profile->times->answered); + switch_channel_set_variable(channel, "answer_uepoch", tmp); + + tt_bridged = (time_t) (caller_profile->times->bridged / 1000000); + mtt_bridged = (time_t) (caller_profile->times->bridged / 1000); +- switch_snprintf(tmp, sizeof(tmp), "%" TIME_T_FMT, tt_bridged); ++ switch_snprintf(tmp, sizeof(tmp), "%" TIME_T_FMT, TIME_T_CAST(tt_bridged)); + switch_channel_set_variable(channel, "bridge_epoch", tmp); + switch_snprintf(tmp, sizeof(tmp), "%" SWITCH_TIME_T_FMT, caller_profile->times->bridged); + switch_channel_set_variable(channel, "bridge_uepoch", tmp); + + tt_last_hold = (time_t) (caller_profile->times->last_hold / 1000000); +- switch_snprintf(tmp, sizeof(tmp), "%" TIME_T_FMT, tt_last_hold); ++ switch_snprintf(tmp, sizeof(tmp), "%" TIME_T_FMT, TIME_T_CAST(tt_last_hold)); + switch_channel_set_variable(channel, "last_hold_epoch", tmp); + switch_snprintf(tmp, sizeof(tmp), "%" SWITCH_TIME_T_FMT, caller_profile->times->last_hold); + switch_channel_set_variable(channel, "last_hold_uepoch", tmp); + + tt_hold_accum = (time_t) (caller_profile->times->hold_accum / 1000000); +- switch_snprintf(tmp, sizeof(tmp), "%" TIME_T_FMT, tt_hold_accum); ++ switch_snprintf(tmp, sizeof(tmp), "%" TIME_T_FMT, TIME_T_CAST(tt_hold_accum)); + switch_channel_set_variable(channel, "hold_accum_seconds", tmp); + switch_snprintf(tmp, sizeof(tmp), "%" SWITCH_TIME_T_FMT, caller_profile->times->hold_accum); + switch_channel_set_variable(channel, "hold_accum_usec", tmp); +@@ -4702,28 +4702,28 @@ SWITCH_DECLARE(switch_status_t) switch_c + switch_channel_set_variable(channel, "hold_accum_ms", tmp); + + tt_resurrected = (time_t) (caller_profile->times->resurrected / 1000000); +- switch_snprintf(tmp, sizeof(tmp), "%" TIME_T_FMT, tt_resurrected); ++ switch_snprintf(tmp, sizeof(tmp), "%" TIME_T_FMT, TIME_T_CAST(tt_resurrected)); + switch_channel_set_variable(channel, "resurrect_epoch", tmp); + switch_snprintf(tmp, sizeof(tmp), "%" SWITCH_TIME_T_FMT, caller_profile->times->resurrected); + switch_channel_set_variable(channel, "resurrect_uepoch", tmp); + + tt_progress = (time_t) (caller_profile->times->progress / 1000000); + mtt_progress = (time_t) (caller_profile->times->progress / 1000); +- switch_snprintf(tmp, sizeof(tmp), "%" TIME_T_FMT, tt_progress); ++ switch_snprintf(tmp, sizeof(tmp), "%" TIME_T_FMT, TIME_T_CAST(tt_progress)); + switch_channel_set_variable(channel, "progress_epoch", tmp); + switch_snprintf(tmp, sizeof(tmp), "%" SWITCH_TIME_T_FMT, caller_profile->times->progress); + switch_channel_set_variable(channel, "progress_uepoch", tmp); + + tt_progress_media = (time_t) (caller_profile->times->progress_media / 1000000); + mtt_progress_media = (time_t) (caller_profile->times->progress_media / 1000); +- switch_snprintf(tmp, sizeof(tmp), "%" TIME_T_FMT, tt_progress_media); ++ switch_snprintf(tmp, sizeof(tmp), "%" TIME_T_FMT, TIME_T_CAST(tt_progress_media)); + switch_channel_set_variable(channel, "progress_media_epoch", tmp); + switch_snprintf(tmp, sizeof(tmp), "%" SWITCH_TIME_T_FMT, caller_profile->times->progress_media); + switch_channel_set_variable(channel, "progress_media_uepoch", tmp); + + tt_hungup = (time_t) (caller_profile->times->hungup / 1000000); + mtt_hungup = (time_t) (caller_profile->times->hungup / 1000); +- switch_snprintf(tmp, sizeof(tmp), "%" TIME_T_FMT, tt_hungup); ++ switch_snprintf(tmp, sizeof(tmp), "%" TIME_T_FMT, TIME_T_CAST(tt_hungup)); + switch_channel_set_variable(channel, "end_epoch", tmp); + switch_snprintf(tmp, sizeof(tmp), "%" SWITCH_TIME_T_FMT, caller_profile->times->hungup); + switch_channel_set_variable(channel, "end_uepoch", tmp); +--- a/src/switch_ivr_originate.c ++++ b/src/switch_ivr_originate.c +@@ -804,7 +804,7 @@ static uint8_t check_channel_status(orig + time_t elapsed = switch_epoch_time_now(NULL) - start; + oglobals->originate_status[i].per_channel_progress_timelimit_sec = elapsed + extend_timeout; + oglobals->originate_status[i].per_channel_timelimit_sec = elapsed + extend_timeout; +- switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "elapsed %" TIME_T_FMT ", timelimit extended to %u\n", elapsed, oglobals->originate_status[i].per_channel_timelimit_sec); ++ switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "elapsed %" TIME_T_FMT ", timelimit extended to %u\n", TIME_T_CAST(elapsed), oglobals->originate_status[i].per_channel_timelimit_sec); + } else if (oglobals->cancel_timeout || cancel_timeout) { + /* cancel timeout for this leg only */ + oglobals->originate_status[i].per_channel_progress_timelimit_sec = 0; diff --git a/net/freeswitch/patches/491-mod-gsmopen-time64.patch b/net/freeswitch/patches/491-mod-gsmopen-time64.patch new file mode 100644 index 000000000..6019b62ee --- /dev/null +++ b/net/freeswitch/patches/491-mod-gsmopen-time64.patch @@ -0,0 +1,51 @@ +--- a/src/mod/endpoints/mod_gsmopen/gsmopen_protocol.cpp ++++ b/src/mod/endpoints/mod_gsmopen/gsmopen_protocol.cpp +@@ -853,7 +853,7 @@ int gsmopen_serial_read_AT(private_t *te + + if (tech_pvt->interface_state != GSMOPEN_STATE_RING) { + gettimeofday(&(tech_pvt->call_incoming_time), NULL); +- DEBUGA_GSMOPEN("GSMOPEN_STATE_RING call_incoming_time.tv_sec=%ld\n", GSMOPEN_P_LOG, tech_pvt->call_incoming_time.tv_sec); ++ DEBUGA_GSMOPEN("GSMOPEN_STATE_RING call_incoming_time.tv_sec=%" TIME_T_FMT "\n", GSMOPEN_P_LOG, TIME_T_CAST(tech_pvt->call_incoming_time.tv_sec)); + + } + +@@ -1177,7 +1177,7 @@ int gsmopen_serial_read_AT(private_t *te + //mark the time of CALLFLOW_CALL_INCOMING + gettimeofday(&(tech_pvt->call_incoming_time), NULL); + tech_pvt->phone_callflow = CALLFLOW_CALL_INCOMING; +- DEBUGA_GSMOPEN("CALLFLOW_CALL_INCOMING call_incoming_time.tv_sec=%ld\n", GSMOPEN_P_LOG, tech_pvt->call_incoming_time.tv_sec); ++ DEBUGA_GSMOPEN("CALLFLOW_CALL_INCOMING call_incoming_time.tv_sec=%" TIME_T_FMT "\n", GSMOPEN_P_LOG, TIME_T_CAST(tech_pvt->call_incoming_time.tv_sec)); + + } + } +@@ -1946,15 +1946,15 @@ int gsmopen_serial_read_AT(private_t *te + gettimeofday(&call_incoming_timeout, NULL); + call_incoming_timeout.tv_sec -= 3; + DEBUGA_GSMOPEN +- ("CALLFLOW_CALL_INCOMING call_incoming_time.tv_sec=%ld, call_incoming_timeout.tv_sec=%ld\n", +- GSMOPEN_P_LOG, tech_pvt->call_incoming_time.tv_sec, call_incoming_timeout.tv_sec); ++ ("CALLFLOW_CALL_INCOMING call_incoming_time.tv_sec=%" TIME_T_FMT ", call_incoming_timeout.tv_sec=%" TIME_T_FMT "\n", ++ GSMOPEN_P_LOG, TIME_T_CAST(tech_pvt->call_incoming_time.tv_sec), TIME_T_CAST(call_incoming_timeout.tv_sec)); + if (call_incoming_timeout.tv_sec > tech_pvt->call_incoming_time.tv_sec) { + + tech_pvt->call_incoming_time.tv_sec = 0; + tech_pvt->call_incoming_time.tv_usec = 0; + DEBUGA_GSMOPEN +- ("CALLFLOW_CALL_INCOMING call_incoming_time.tv_sec=%ld, call_incoming_timeout.tv_sec=%ld\n", +- GSMOPEN_P_LOG, tech_pvt->call_incoming_time.tv_sec, call_incoming_timeout.tv_sec); ++ ("CALLFLOW_CALL_INCOMING call_incoming_time.tv_sec=%" TIME_T_FMT ", call_incoming_timeout.tv_sec=%" TIME_T_FMT "\n", ++ GSMOPEN_P_LOG, TIME_T_CAST(tech_pvt->call_incoming_time.tv_sec), TIME_T_CAST(call_incoming_timeout.tv_sec)); + int res = gsmopen_serial_write_AT_ack(tech_pvt, "AT+CPBS=RC"); + if (res) { + ERRORA("AT+CPBS=RC (select memory of received calls) was not answered by the phone\n", GSMOPEN_P_LOG); +@@ -1983,8 +1983,8 @@ int gsmopen_serial_read_AT(private_t *te + if (call_incoming_timeout.tv_sec > tech_pvt->ringtime.tv_sec) { + ERRORA("Ringing stopped and I have not answered. Why?\n", GSMOPEN_P_LOG); + DEBUGA_GSMOPEN +- ("CALLFLOW_CALL_INCOMING call_incoming_time.tv_sec=%ld, call_incoming_timeout.tv_sec=%ld\n", +- GSMOPEN_P_LOG, tech_pvt->call_incoming_time.tv_sec, call_incoming_timeout.tv_sec); ++ ("CALLFLOW_CALL_INCOMING call_incoming_time.tv_sec=%" TIME_T_FMT ", call_incoming_timeout.tv_sec=%" TIME_T_FMT "\n", ++ GSMOPEN_P_LOG, TIME_T_CAST(tech_pvt->call_incoming_time.tv_sec), TIME_T_CAST(call_incoming_timeout.tv_sec)); + if (tech_pvt->owner) { + gsmopen_queue_control(tech_pvt->owner, GSMOPEN_CONTROL_HANGUP); + tech_pvt->owner->hangupcause = GSMOPEN_CAUSE_FAILURE; diff --git a/net/freeswitch/patches/492-mod_verto_time64.patch b/net/freeswitch/patches/492-mod_verto_time64.patch new file mode 100644 index 000000000..dfddff2aa --- /dev/null +++ b/net/freeswitch/patches/492-mod_verto_time64.patch @@ -0,0 +1,20 @@ +--- a/src/mod/endpoints/mod_verto/mod_verto.c ++++ b/src/mod/endpoints/mod_verto/mod_verto.c +@@ -1121,7 +1121,7 @@ static switch_bool_t check_auth(jsock_t + + if (tmp > now) { + jsock->exptime = tmp; +- switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Login expire time for %s set to %ld seconds [%ld] [%ld]\n", jsock->uid, tmp - now, jsock->exptime, now); ++ switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Login expire time for %s set to %" TIME_T_FMT " seconds [%" TIME_T_FMT "] [%" TIME_T_FMT "]\n", jsock->uid, TIME_T_CAST(tmp - now), TIME_T_CAST(jsock->exptime), TIME_T_CAST(now)); + } else { + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "Invalid expire time for %s. Defaulting to 300 sec\n", jsock->uid); + jsock->exptime = now + 300; +@@ -2003,7 +2003,7 @@ static void client_run(jsock_t *jsock) + + if (now >= jsock->exptime) { + switch_set_flag(jsock, JPFLAG_AUTH_EXPIRED); +- die("%s Authentication Expired [%ld] >= [%ld]\n", jsock->uid, now, jsock->exptime); ++ die("%s Authentication Expired [%" TIME_T_FMT "] >= [%" TIME_T_FMT "]\n", jsock->uid, TIME_T_CAST(now), TIME_T_CAST(jsock->exptime)); + } + + } diff --git a/net/freeswitch/patches/493-core-fix-switch_mprintf-format-string.patch b/net/freeswitch/patches/493-core-fix-switch_mprintf-format-string.patch new file mode 100644 index 000000000..74549772b --- /dev/null +++ b/net/freeswitch/patches/493-core-fix-switch_mprintf-format-string.patch @@ -0,0 +1,23 @@ +From ec0c59a798ff1124295e7d5d82c2e30f1226cc07 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?=C3=89rico=20Nogueira?= +Date: Fri, 29 Oct 2021 00:17:05 -0300 +Subject: [PATCH] [core] fix switch_mprintf format string + +Segfaults on 32-bit platforms running musl 1.2.x. + +Reported-by: Sebastian Kemper +--- + src/switch_core_sqldb.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/src/switch_core_sqldb.c ++++ b/src/switch_core_sqldb.c +@@ -3553,7 +3553,7 @@ SWITCH_DECLARE(switch_status_t) switch_c + if (force) { + sql = switch_mprintf("delete from registrations where hostname='%q'", switch_core_get_switchname()); + } else { +- sql = switch_mprintf("delete from registrations where expires > 0 and expires <= %ld and hostname='%q'", now, switch_core_get_switchname()); ++ sql = switch_mprintf("delete from registrations where expires > 0 and expires <= %" TIME_T_FMT " and hostname='%q'", TIME_T_CAST(now), switch_core_get_switchname()); + } + + switch_sql_queue_manager_push(sql_manager.qm, sql, 0, SWITCH_FALSE); diff --git a/net/kamailio/Makefile b/net/kamailio/Makefile new file mode 100644 index 000000000..070f7b709 --- /dev/null +++ b/net/kamailio/Makefile @@ -0,0 +1,681 @@ +# +# Copyright (C) 2017 OpenWrt.org +# Copyright (C) 2017 Jiri Slachta +# +# This is free software, licensed under the GNU General Public License v2. +# See /LICENSE for more information. +# + +include $(TOPDIR)/rules.mk + +PKG_NAME:=kamailio +PKG_VERSION:=5.7.2 +PKG_RELEASE:=2 + +PKG_SOURCE_URL:=https://www.kamailio.org/pub/kamailio/$(PKG_VERSION)/src +PKG_SOURCE:=kamailio-$(PKG_VERSION)_src.tar.gz +PKG_HASH:=72c9a067da8d6fa920d3737d98cd7f66c321f80cbe1076e2d5a392b422503122 +PKG_BUILD_FLAGS:=no-mips16 + +PKG_LICENSE:=GPL-2.0+ +PKG_LICENSE_FILES:=COPYING +PKG_MAINTAINER:=Jiri Slachta + +PKG_INSTALL:=1 + +PKG_BUILD_PARALLEL:=1 + +MODULES_AVAILABLE:= \ + acc \ + acc_diameter \ + acc_json \ + alias_db \ + app_jsdt \ + app_lua \ + app_lua_sr \ + app_python3 \ + app_ruby \ + app_sqlang \ + async \ + auth \ + auth_db \ + auth_diameter \ + auth_ephemeral \ + auth_identity \ + auth_xkeys \ + avp \ + avpops \ + benchmark \ + blst \ + call_control \ + call_obj \ + carrierroute \ + cdp \ + cdp_avp \ + cfgutils \ + cfg_db \ + cfg_rpc \ + cfgt \ + cnxcc \ + corex \ + counters \ + cplc \ + crypto \ + ctl \ + db2_ldap \ + db2_ops \ + db_berkeley \ + db_cluster \ + db_flatstore \ + db_mysql \ + db_postgres \ + db_redis \ + db_sqlite \ + db_text \ + db_unixodbc \ + debugger \ + dialog \ + dialplan \ + dispatcher \ + diversion \ + dlgs \ + dmq \ + dmq_usrloc \ + domain \ + domainpolicy \ + drouting \ + enum \ + erlang \ + evapi \ + evrexec \ + exec \ + group \ + gzcompress \ + h350 \ + htable \ + http_client \ + imc \ + ims_auth \ + ims_charging \ + ims_dialog \ + ims_diameter_server \ + ims_icscf \ + ims_ipsec_pcscf \ + ims_isc \ + ims_ocs \ + ims_qos \ + ims_registrar_pcscf \ + ims_registrar_scscf \ + ims_usrloc_pcscf \ + ims_usrloc_scscf \ + ipops \ + jansson \ + janssonrpcc \ + json \ + jsonrpcs \ + keepalive \ + kemix \ + kex \ + lcr \ + ldap \ + log_custom \ + lost \ + lrkproxy \ + mangler \ + matrix \ + maxfwd \ + mediaproxy \ + misctest \ + mohqueue \ + mqueue \ + msilo \ + msrp \ + mtree \ + nathelper \ + nat_traversal \ + ndb_redis \ + nosip \ + outbound \ + p_usrloc \ + path \ + pdb \ + pdt \ + permissions \ + pike \ + pipelimit \ + posops \ + prefix_route \ + presence \ + presence_conference \ + presence_dialoginfo \ + presence_mwi \ + presence_profile \ + presence_reginfo \ + presence_xml \ + pua \ + pua_bla \ + pua_dialoginfo \ + pua_json \ + pua_reginfo \ + pua_rpc \ + pua_usrloc \ + pua_xmpp \ + pv \ + pv_headers \ + qos \ + ratelimit \ + regex \ + registrar \ + rls \ + rr \ + rtimer \ + rtjson \ + rtpengine \ + rtpproxy \ + sanity \ + sca \ + sctp \ + sdpops \ + seas \ + secfilter \ + sipcapture \ + sipdump \ + siprepo \ + sipt \ + siptrace \ + siputils \ + sl \ + slack \ + sms \ + smsops \ + snmpstats \ + speeddial \ + sqlops \ + ss7ops \ + statistics \ + statsc \ + statsd \ + stun \ + sst \ + tcpops \ + textops \ + textopsx \ + timer \ + tls \ + tmrec \ + topoh \ + topos \ + topos_redis \ + tm \ + tmx \ + tsilo \ + uac \ + uac_redirect \ + uid_auth_db \ + uid_avp_db \ + uid_domain \ + uid_gflags \ + uid_uri_db \ + uri_db \ + userblocklist \ + usrloc \ + utils \ + uuid \ + websocket \ + xcap_client \ + xcap_server \ + xhttp \ + xhttp_pi \ + xhttp_prom \ + xhttp_rpc \ + xlog \ + xmlops \ + xmlrpc \ + xmpp \ + xprint + +PKG_CONFIG_DEPENDS:= \ + $(patsubst %,CONFIG_PACKAGE_kamailio-mod-%,$(subst _,-,$(MODULES_AVAILABLE))) + +include $(INCLUDE_DIR)/nls.mk +include $(INCLUDE_DIR)/package.mk +include $(INCLUDE_DIR)/kernel.mk +include $(TOPDIR)/feeds/packages/lang/python/python3-version.mk + +# Build reproducibly +TARGET_CFLAGS += -DVERSION_NODATE=1 + +PREBUILT_STAMP=$(STAGING_DIR)/stamp/.kamailio_prebuilt +TAR_CMD:=$(HOST_TAR) -C $(PKG_BUILD_DIR) --strip-components 1 $(TAR_OPTIONS) + +INCL_MODULES:= + +define Package/kamailio/Default + SECTION:=net + CATEGORY:=Network + SUBMENU:=Telephony + URL:=http://www.kamailio.org/ + DEPENDS:=$(ICONV_DEPENDS) +libncurses +libpthread +libreadline +libxml2 +endef + +define Package/kamailio +$(call Package/kamailio/Default) + TITLE:=Mature and flexible open source SIP server, v$(PKG_VERSION) + USERID:=kamailio=380:kamailio=380 + MENU:=1 +endef + +define Package/kamailio/conffiles +/etc/config/kamailio +/etc/init.d/kamailio +/etc/kamailio/kamailio.cfg +/etc/kamailio/kamctlrc +endef + +define Package/kamailio/install +$(foreach c,kamailio.cfg kamctlrc,$(call Package/kamailio/install/conffile,$(1),$(c));) + $(INSTALL_DIR) $(1)/usr/sbin + $(INSTALL_BIN) \ + $(PKG_INSTALL_DIR)/usr/sbin/kam{ailio,cmd,ctl,dbctl} \ + $(1)/usr/sbin/ + $(INSTALL_DIR) $(1)/usr/lib/kamailio/modules + $(CP) \ + $(PKG_INSTALL_DIR)/usr/lib/kamailio/lib{srdb1,srdb2}.so* \ + $(1)/usr/lib/kamailio/ + $(INSTALL_DIR) $(1)/etc/config + $(INSTALL_CONF) \ + ./files/kamailio.conf \ + $(1)/etc/config/kamailio + $(INSTALL_DIR) $(1)/etc/init.d + $(INSTALL_BIN) \ + ./files/kamailio.init \ + $(1)/etc/init.d/kamailio + $(INSTALL_DIR) $(1)/etc/hotplug.d/iface + $(INSTALL_BIN) \ + ./files/kamailio.hotplug \ + $(1)/etc/hotplug.d/iface/99-kamailio + $(CP) \ + $(PKG_INSTALL_DIR)/usr/lib/kamailio/kamctl \ + $(1)/usr/lib/kamailio/ +endef + +define Package/kamailio/postinst +#!/bin/sh +if [ -z "$${IPKG_INSTROOT}" ]; then + echo + echo "o-------------------------------------------------------------------o" + echo "| Kamailio note |" + echo "o-------------------------------------------------------------------o" + echo "| Edit /etc/config/kamailio to change basic init configuration. |" + echo "o-------------------------------------------------------------=^_^=-o" + echo +fi +exit 0 +endef + +define Package/kamailio/install/conffile + $(INSTALL_DIR) $(1)/etc/kamailio + $(INSTALL_DATA) $(PKG_INSTALL_DIR)/etc/kamailio/$(2) $(1)/etc/kamailio +endef + +define Package/kamailio/install/dbfiles + $(INSTALL_DIR) $(1)/usr/share/kamailio/$(2) + $(CP) $(PKG_INSTALL_DIR)/usr/share/kamailio/$(2)/* $(1)/usr/share/kamailio/$(2)/ +endef + +define Package/kamailio/install/module + $(INSTALL_DIR) $(1)/usr/lib/kamailio/modules + $(INSTALL_BIN) $(PKG_INSTALL_DIR)/usr/lib/kamailio/modules/$(2).so* $(1)/usr/lib/kamailio/modules/ +endef + +define Package/kamailio-lib-libkamailio-ims +$(call Package/kamailio/Default) + TITLE:=Kamailio IMS library + DEPENDS:=kamailio +endef + +define Package/kamailio-lib-libkamailio-ims/install + $(INSTALL_DIR) $(1)/usr/lib/kamailio + $(CP) $(PKG_INSTALL_DIR)/usr/lib/kamailio/libkamailio_ims.so* \ + $(1)/usr/lib/kamailio +endef + +define Package/kamailio-lib-libtrie +$(call Package/kamailio/Default) + TITLE:=Kamailio digital tree library + DEPENDS:=kamailio +endef + +define Package/kamailio-lib-libtrie/install + $(INSTALL_DIR) $(1)/usr/lib/kamailio + $(CP) $(PKG_INSTALL_DIR)/usr/lib/kamailio/libtrie.so* \ + $(1)/usr/lib/kamailio +endef + +define Package/kamailio-util-kambdb-recover +$(call Package/kamailio/Default) + TITLE:=Kamailio Berkeley DB recovery utility + DEPENDS:=kamailio +PACKAGE_kamailio-util-kambdb-recover:kamailio-mod-db-berkeley +endef + +define Package/kamailio-util-kambdb-recover/install + $(INSTALL_DIR) $(1)/usr/sbin + $(INSTALL_BIN) $(PKG_INSTALL_DIR)/usr/sbin/kambdb_recover $(1)/usr/sbin +endef + +define BuildKamailioModule + define Package/kamailio-mod-$(subst _,-,$(1)) + $$(call Package/kamailio/Default) + TITLE:=$(2) for Kamailio + DEPENDS:=kamailio $(patsubst +%,+PACKAGE_kamailio-mod-$(subst _,-,$(1)):%,$(4)) + ifneq ($$(CONFIG_PACKAGE_kamailio-mod-$(subst _,-,$(1))),) + INCL_MODULES+=$(1) + endif + endef + define Package/kamailio-mod-$(subst _,-,$(1))/conffiles +$(subst $(space),$(newline),$(foreach c,$(6),/etc/kamailio/$(c))) + endef + define Package/kamailio-mod-$(subst _,-,$(1))/description +$(subst \n,$(newline),$(3)) + endef + define Package/kamailio-mod-$(subst _,-,$(1))/install +$(call Package/kamailio/install/module,$$(1),$(1)) +$(foreach c,$(6),$(call Package/kamailio/install/conffile,$$(1),$(c));) +$(foreach d,$(5),$(call Package/kamailio/install/dbfiles,$$(1),$(d));) + ifeq ($(1),snmpstats) + $(INSTALL_DIR) $$(1)/usr/share/snmp/mibs + $(INSTALL_DATA) $(PKG_INSTALL_DIR)/usr/share/snmp/mibs/* \ + $$(1)/usr/share/snmp/mibs + endif + endef +$$(eval $$(call BuildPackage,kamailio-mod-$(subst _,-,$(1)))) +endef + +# Kamailio always builds a baseline of packages. The "standard" group is +# the lightest baseline. + +# "uid_gflags" is added to the list of modules to have at least one +# module that kicks off the build of the internal libsrdb2. The module +# has no other extra dependencies. +# +# The same is done with: +# "ims_diameter_server" -> libkamailio_ims +# "carrierroute" -> libtrie + +EXTRA_MODULES:= \ + $(if $(CONFIG_PACKAGE_kamailio-mod-carrierroute),,carrierroute) \ + $(if $(CONFIG_PACKAGE_kamailio-mod-ims-diameter-server),,ims_diameter_server) \ + $(if $(CONFIG_PACKAGE_kamailio-mod-uid-gflags),,uid_gflags) + +# MIPS tweak: +# +# Kamailio enables use of fast inline assembly locks when ARCH is set to +# "mips2". When ARCH is set to "mips" instead, Kamailio assumes it is dealing +# with an old 32-bit MIPS CPU without hardware locking support (like R3000). +# +# When CONFIG_CPU_TYPE matches one of the identifiers in the list below, set +# ARCH to "mips2" to get FAST_LOCK support. +ifeq ($(call qstrip,$(CONFIG_ARCH)),mips) +CPU_MIPS2:=mips32 24kc 34kc 4kec 74kc +endif + +MAKE_FLAGS += \ + OS=linux \ + OSREL=$(LINUX_UNAME_VERSION) \ + $(if $(findstring $(call qstrip,$(CONFIG_CPU_TYPE)),$(CPU_MIPS2)),ARCH="mips2",ARCH="$(ARCH)") \ + CC_EXTRA_OPTS="$(TARGET_CFLAGS) $(TARGET_CPPFLAGS)" \ + LD="$(TARGET_CC)" \ + LD_EXTRA_OPTS="$(TARGET_LDFLAGS)" \ + LIBDIR=lib \ + PREFIX=/usr \ + cfg_prefix="$(PKG_INSTALL_DIR)" \ + cfg_target=/etc/kamailio \ + group_include="standard" \ + include_modules="$$(INCL_MODULES) $(EXTRA_MODULES)" \ + quiet=verbose \ + run_prefix="" + +MAKE_VARS += \ + PYTHON3=python$(PYTHON3_VERSION) + +define Build/Prepare + $(call Build/Prepare/Default) + # Upstream adds "-funroll-loops" to compiler flags, which increases + # binary size significantly. Remove this flag. + $(SED) 's/[ ]*-funroll-loops//' $(PKG_BUILD_DIR)/src/Makefile.defs + # Also remove -march=arm... flags as they can clash with + # CONFIG_TARGET_OPTIMIZATION. + $(SED) 's/-march=armv[0-7a-z-]*[ ]*//' $(PKG_BUILD_DIR)/src/Makefile.defs +endef + +define Build/Configure +endef + +define Build/Compile + $(call Build/Compile/Default,cfg) + $(call Build/Compile/Default,all) +endef + +$(eval $(call BuildPackage,kamailio)) +$(eval $(call BuildPackage,kamailio-lib-libkamailio-ims)) +$(eval $(call BuildPackage,kamailio-lib-libtrie)) +$(eval $(call BuildPackage,kamailio-util-kambdb-recover)) + +################################ +# Kamailio module parameters +# Params: +# 1 - Module name +# 2 - Module title +# 3 - Module description +# 4 - Dependencies +# 5 - Kamailio DB files +# 6 - Configuration files +################################ + +$(eval $(call BuildKamailioModule,acc,Accounting,,+kamailio-mod-tm)) +$(eval $(call BuildKamailioModule,acc_diameter,Accounting for DIAMETER backend,,+kamailio-mod-acc)) +$(eval $(call BuildKamailioModule,acc_json,Accounting with records exported in JSON format,,+jansson +kamailio-mod-acc)) +$(eval $(call BuildKamailioModule,alias_db,Database-backend aliases,,)) +$(eval $(call BuildKamailioModule,app_jsdt,Execute JavaScript scripts,,)) +$(eval $(call BuildKamailioModule,app_lua,Execute embedded Lua scripts,,+liblua)) +$(eval $(call BuildKamailioModule,app_lua_sr,Old Lua API,,+kamailio-mod-app-lua,)) +$(eval $(call BuildKamailioModule,app_python3,Python3 scripting interpreter,,+python3-light)) +$(eval $(call BuildKamailioModule,app_ruby,Ruby scripting interpreter,,+libruby)) +$(eval $(call BuildKamailioModule,app_sqlang,Execute Squirrel language scripts,,+libstdcpp)) +$(eval $(call BuildKamailioModule,async,Asynchronous SIP handling functions,,+kamailio-mod-tm +kamailio-mod-tmx)) +$(eval $(call BuildKamailioModule,auth,Authentication Framework,,)) +$(eval $(call BuildKamailioModule,auth_db,Database-backend authentication,,+kamailio-mod-auth)) +$(eval $(call BuildKamailioModule,auth_diameter,Diameter authentication,,+kamailio-mod-sl)) +$(eval $(call BuildKamailioModule,auth_ephemeral,Ephemeral credentials,,+libopenssl)) +$(eval $(call BuildKamailioModule,auth_identity,Identity authentication,,+libopenssl +libcurl)) +$(eval $(call BuildKamailioModule,auth_xkeys,Shared-key authentication,,+kamailio-mod-auth)) +$(eval $(call BuildKamailioModule,avp,Functions for handling AVPs,,)) +$(eval $(call BuildKamailioModule,avpops,AVP operation,,)) +$(eval $(call BuildKamailioModule,benchmark,Config benchmark,,)) +$(eval $(call BuildKamailioModule,blst,Blacklisting API for config,,)) +$(eval $(call BuildKamailioModule,call_control,Call Control,,+kamailio-mod-dialog +kamailio-mod-pv)) +$(eval $(call BuildKamailioModule,call_obj,Call identification support,,)) +$(eval $(call BuildKamailioModule,carrierroute,Carrier Route,,+kamailio-lib-libtrie)) +$(eval $(call BuildKamailioModule,cdp,C Diameter Peer,,)) +$(eval $(call BuildKamailioModule,cdp_avp,CDP AVP helper module,,+kamailio-mod-cdp)) +$(eval $(call BuildKamailioModule,cfgutils,Config utilities,,)) +$(eval $(call BuildKamailioModule,cfg_db,Load parameters from database,,)) +$(eval $(call BuildKamailioModule,cfg_rpc,Update parameters via RPC,,)) +$(eval $(call BuildKamailioModule,cfgt,Unit test reporting,,)) +$(eval $(call BuildKamailioModule,cnxcc,Limit call duration,,+kamailio-mod-dialog +libhiredis +libevent2)) +$(eval $(call BuildKamailioModule,corex,Legacy functions,,)) +$(eval $(call BuildKamailioModule,counters,Functions for counter manipulation,,)) +$(eval $(call BuildKamailioModule,cplc,Call Processing Language interpreter,,+kamailio-mod-sl +kamailio-mod-tm +kamailio-mod-usrloc)) +$(eval $(call BuildKamailioModule,crypto,Various cryptography tools,,+libopenssl)) +$(eval $(call BuildKamailioModule,ctl,BINRPC transport interface,,)) +$(eval $(call BuildKamailioModule,db2_ldap,DBv2 LDAP module,,+libopenldap)) +$(eval $(call BuildKamailioModule,db2_ops,Run SQL queries from script,,)) +$(eval $(call BuildKamailioModule,db_berkeley,Berkeley DB backend,,+libdb47)) +$(eval $(call BuildKamailioModule,db_cluster,Database clustering system,,)) +$(eval $(call BuildKamailioModule,db_flatstore,fast write-only text DB-backend,,)) +$(eval $(call BuildKamailioModule,db_mysql,MySQL DB-backend,,+libmysqlclient,mysql)) +$(eval $(call BuildKamailioModule,db_postgres,PostgreSQL DB-backend,,+libpq,postgres)) +$(eval $(call BuildKamailioModule,db_redis,Database backend with Redis server,,+libhiredis,db_redis)) +$(eval $(call BuildKamailioModule,db_sqlite,SQLite DB-backend,,+libsqlite3,db_sqlite)) +$(eval $(call BuildKamailioModule,db_text,Text DB-backend,,,dbtext/kamailio)) +$(eval $(call BuildKamailioModule,db_unixodbc,UnixODBC DB-backend,,+unixodbc)) +$(eval $(call BuildKamailioModule,debugger,Interactive config file debugger,,)) +$(eval $(call BuildKamailioModule,dialog,Dialog support,,+kamailio-mod-rr +kamailio-mod-tm)) +$(eval $(call BuildKamailioModule,dialplan,Dialplan management,,+libpcre2)) +$(eval $(call BuildKamailioModule,dispatcher,Dispatcher,,)) +$(eval $(call BuildKamailioModule,diversion,Diversion header insertion,,)) +$(eval $(call BuildKamailioModule,dlgs,Track active calls in stateless mode,,)) +$(eval $(call BuildKamailioModule,dmq,Distributed Message Queue,,+kamailio-mod-sl +kamailio-mod-tm)) +$(eval $(call BuildKamailioModule,dmq_usrloc,DMQ USRLOC replication,,+kamailio-mod-dmq +kamailio-mod-usrloc)) +$(eval $(call BuildKamailioModule,domain,Multi-domain support,,)) +$(eval $(call BuildKamailioModule,domainpolicy,Domain policy,,)) +$(eval $(call BuildKamailioModule,drouting,Dynamic routing module,,)) +$(eval $(call BuildKamailioModule,enum,ENUM lookup,,)) +$(eval $(call BuildKamailioModule,erlang,Erlang node connector module,,@!USE_MUSL +erlang)) +$(eval $(call BuildKamailioModule,evapi,push event details via tcp,,+libev)) +$(eval $(call BuildKamailioModule,evrexec,Execut event routes at startup,,)) +$(eval $(call BuildKamailioModule,exec,External exec,,)) +$(eval $(call BuildKamailioModule,group,Database-backend user-groups,,)) +$(eval $(call BuildKamailioModule,gzcompress,Compress SIP messages,,+zlib)) +$(eval $(call BuildKamailioModule,h350,H.350,,+kamailio-mod-ldap +libopenldap)) +$(eval $(call BuildKamailioModule,htable,Hash Table,,)) +$(eval $(call BuildKamailioModule,http_client,HTTP client using CURL,,+libcurl)) +$(eval $(call BuildKamailioModule,imc,IM conferencing,,+kamailio-mod-db-mysql +kamailio-mod-tm)) +$(eval $(call BuildKamailioModule,ims_auth,IMS authentication module,,+kamailio-lib-libkamailio-ims +kamailio-mod-cdp +kamailio-mod-cdp-avp +kamailio-mod-tm)) +$(eval $(call BuildKamailioModule,ims_charging,IMS charging component module,,+kamailio-lib-libkamailio-ims +kamailio-mod-cdp +kamailio-mod-cdp-avp +kamailio-mod-tm)) +$(eval $(call BuildKamailioModule,ims_dialog,IMS dialog tracking module,,+kamailio-mod-rr +kamailio-mod-tm)) +$(eval $(call BuildKamailioModule,ims_diameter_server,IMS DIAMETER server module,,+kamailio-lib-libkamailio-ims +kamailio-mod-cdp +kamailio-mod-cdp-avp)) +$(eval $(call BuildKamailioModule,ims_icscf,IMS ICSCF component module,,+kamailio-lib-libkamailio-ims +kamailio-mod-cdp +kamailio-mod-cdp-avp +kamailio-mod-sl +kamailio-mod-tm)) +$(eval $(call BuildKamailioModule,ims_ipsec_pcscf,Diameter server implementation,,+kamailio-lib-libkamailio-ims +kamailio-mod-ims-usrloc-pcscf +kamailio-mod-tm +libmnl)) +$(eval $(call BuildKamailioModule,ims_isc,IMS ISC component module,,+kamailio-lib-libkamailio-ims +kamailio-mod-ims-usrloc-scscf +kamailio-mod-tm)) +$(eval $(call BuildKamailioModule,ims_ocs,MS OCS component module,,+kamailio-lib-libkamailio-ims +kamailio-mod-cdp +kamailio-mod-cdp-avp)) +$(eval $(call BuildKamailioModule,ims_qos,IMS Diameter Rx interface between PCSCF and PCRF functions,,+kamailio-lib-libkamailio-ims +kamailio-mod-cdp +kamailio-mod-cdp-avp +kamailio-mod-ims-dialog +kamailio-mod-ims-usrloc-pcscf +kamailio-mod-tm)) +$(eval $(call BuildKamailioModule,ims_registrar_pcscf,MS PCSCF registrar module,,+kamailio-lib-libkamailio-ims +kamailio-mod-ims-usrloc-pcscf)) +$(eval $(call BuildKamailioModule,ims_registrar_scscf,IMS SCSCF registrar module,,+kamailio-lib-libkamailio-ims +kamailio-mod-cdp +kamailio-mod-cdp-avp +kamailio-mod-ims-usrloc-scscf +kamailio-mod-tm)) +$(eval $(call BuildKamailioModule,ims_usrloc_pcscf,IMS PCSCF usrloc module,,)) +$(eval $(call BuildKamailioModule,ims_usrloc_scscf,IMS SCSCF usrloc module,,)) +$(eval $(call BuildKamailioModule,ipops,IP and IPv6 operations,,)) +$(eval $(call BuildKamailioModule,jansson,Access to JSON attributes,,+jansson)) +$(eval $(call BuildKamailioModule,janssonrpcc,Alternative JSONRPC server,,+kamailio-mod-jansson +libevent2)) +$(eval $(call BuildKamailioModule,json,Access to JSON document attributes,,+libjson-c)) +$(eval $(call BuildKamailioModule,jsonrpcs,JSONRPC server over HTTP,,+libevent2)) +$(eval $(call BuildKamailioModule,keepalive,SIP keepalive monitoring,,+kamailio-mod-tm,,)) +$(eval $(call BuildKamailioModule,kemix,KEMI extensions,,,)) +$(eval $(call BuildKamailioModule,kex,Core extensions,,)) +$(eval $(call BuildKamailioModule,lcr,Least Cost Routing,,+kamailio-mod-tm +libpcre2)) +$(eval $(call BuildKamailioModule,ldap,LDAP connector,,+libopenldap)) +$(eval $(call BuildKamailioModule,log_custom,Logging to custom backends,,)) +$(eval $(call BuildKamailioModule,lost,HELD and LOST routing,,+kamailio-mod-http-client,)) +$(eval $(call BuildKamailioModule,lrkproxy,pylrkproxy media stream relay,,,)) +$(eval $(call BuildKamailioModule,mangler,SDP mangling,,)) +$(eval $(call BuildKamailioModule,matrix,Matrix operations,,)) +$(eval $(call BuildKamailioModule,maxfwd,Max-Forward processor,,)) +$(eval $(call BuildKamailioModule,mediaproxy,Automatic NAT traversal,,+kamailio-mod-dialog)) +$(eval $(call BuildKamailioModule,misctest,Debugging/testing,This is a debugging/test module. It implements functions (both script\nand rpcs) that can be used to stress the memory allocator or force\nmemory leaks.\n\nWarning: This module should never be used in a production environment.,,,)) +$(eval $(call BuildKamailioModule,mohqueue,Music on hold queuing system,,+kamailio-mod-rtpproxy +kamailio-mod-sl +kamailio-mod-tm)) +$(eval $(call BuildKamailioModule,mqueue,Generic message queue system,,)) +$(eval $(call BuildKamailioModule,msilo,SIP message silo,,+kamailio-mod-tm)) +$(eval $(call BuildKamailioModule,msrp,MSRP routing engine,,+kamailio-mod-tls)) +$(eval $(call BuildKamailioModule,mtree,Memory caching system,,)) +$(eval $(call BuildKamailioModule,nathelper,NAT helper,,+kamailio-mod-usrloc)) +$(eval $(call BuildKamailioModule,nat_traversal,NAT traversal,,+kamailio-mod-dialog +kamailio-mod-sl +kamailio-mod-tm)) +$(eval $(call BuildKamailioModule,ndb_redis,Connect to REDIS NoSQL,,+libhiredis)) +$(eval $(call BuildKamailioModule,nosip,non-sip package handling,,+kamailio-mod-rr)) +$(eval $(call BuildKamailioModule,outbound,SIP Outbound implementation,,+kamailio-mod-stun +libopenssl)) +$(eval $(call BuildKamailioModule,p_usrloc,Partitioned USRLOC services,,)) +$(eval $(call BuildKamailioModule,path,SIP path insertion,,+kamailio-mod-rr)) +$(eval $(call BuildKamailioModule,pdb,Number portability module,,)) +$(eval $(call BuildKamailioModule,pdt,Prefix-to-Domain translator,,)) +$(eval $(call BuildKamailioModule,permissions,Permissions control,,)) +$(eval $(call BuildKamailioModule,pike,Flood detector,,)) +$(eval $(call BuildKamailioModule,pipelimit,Traffic shaping policies,,+kamailio-mod-sl)) +$(eval $(call BuildKamailioModule,posops,Position SIP message buffer ops,The module exports utility functions to work with the position inside the SIP\nmessage buffer. Among them are function to add or remove content at\na specific position.,,,)) +$(eval $(call BuildKamailioModule,prefix_route,Execute based on prefix,,)) +$(eval $(call BuildKamailioModule,presence,Presence server,,+kamailio-mod-sl +kamailio-mod-tm,)) +$(eval $(call BuildKamailioModule,presence_conference,Conference events,,+kamailio-mod-presence)) +$(eval $(call BuildKamailioModule,presence_dialoginfo,Dialog Event presence,,+kamailio-mod-presence)) +$(eval $(call BuildKamailioModule,presence_mwi,MWI presence,,+kamailio-mod-presence)) +$(eval $(call BuildKamailioModule,presence_profile,User profile extensions,,+kamailio-mod-presence)) +$(eval $(call BuildKamailioModule,presence_reginfo,Registration info,,+kamailio-mod-presence)) +$(eval $(call BuildKamailioModule,presence_xml,XCAP presence,,+kamailio-mod-presence +kamailio-mod-xcap-client)) +$(eval $(call BuildKamailioModule,pua,Presence User Agent,,+kamailio-mod-tm,)) +$(eval $(call BuildKamailioModule,pua_bla,Bridged Line Appearence PUA,,+kamailio-mod-presence +kamailio-mod-pua +kamailio-mod-usrloc)) +$(eval $(call BuildKamailioModule,pua_dialoginfo,Dialog Event PUA,,+kamailio-mod-dialog +kamailio-mod-pua)) +$(eval $(call BuildKamailioModule,pua_json,Presence user agent implementation with JSON messages,,+libjson-c)) +$(eval $(call BuildKamailioModule,pua_reginfo,PUA registration info,,+kamailio-mod-pua +kamailio-mod-usrloc)) +$(eval $(call BuildKamailioModule,pua_rpc,RPC extensions for PUA,,+kamailio-mod-pua)) +$(eval $(call BuildKamailioModule,pua_usrloc,PUA User Location,,+kamailio-mod-pua +kamailio-mod-usrloc)) +$(eval $(call BuildKamailioModule,pua_xmpp,PUA XMPP,,+kamailio-mod-presence +kamailio-mod-pua +kamailio-mod-xmpp)) +$(eval $(call BuildKamailioModule,pv,Pseudo-Variables,,)) +$(eval $(call BuildKamailioModule,pv_headers,Flexible SIP header management,,)) +$(eval $(call BuildKamailioModule,qos,QoS control,,+kamailio-mod-dialog)) +$(eval $(call BuildKamailioModule,ratelimit,Traffic shapping,,)) +$(eval $(call BuildKamailioModule,regex,Regular Expression,,+libpcre2)) +$(eval $(call BuildKamailioModule,registrar,SIP Registrar,,+kamailio-mod-usrloc)) +$(eval $(call BuildKamailioModule,rls,Resource List Server,,+kamailio-mod-presence +kamailio-mod-pua +kamailio-mod-tm,)) +$(eval $(call BuildKamailioModule,rr,Record-Route and Route,,)) +$(eval $(call BuildKamailioModule,rtimer,Routing Timer,,)) +$(eval $(call BuildKamailioModule,rtjson,SIP routing based on JSON API,,)) +$(eval $(call BuildKamailioModule,rtpengine,RTP engine,,+kamailio-mod-tm)) +$(eval $(call BuildKamailioModule,rtpproxy,RTP proxy,,+kamailio-mod-tm)) +$(eval $(call BuildKamailioModule,sanity,SIP sanity checks,,+kamailio-mod-sl)) +$(eval $(call BuildKamailioModule,sca,Shared Call Appearances,,+kamailio-mod-sl +kamailio-mod-tm)) +$(eval $(call BuildKamailioModule,sctp,SCTP support,,+libsctp)) +$(eval $(call BuildKamailioModule,sdpops,Managing SDP payloads,,)) +$(eval $(call BuildKamailioModule,seas,Sip Express Application Server,,+kamailio-mod-tm)) +$(eval $(call BuildKamailioModule,secfilter,Allow/block filters,,,)) +$(eval $(call BuildKamailioModule,sipcapture,SIP capture,,)) +$(eval $(call BuildKamailioModule,sipdump,Save SIP traffic,,)) +$(eval $(call BuildKamailioModule,siprepo,SIP Repo,This module can store and fetch SIP message content in an in-memory hash\ntable.,,,)) +$(eval $(call BuildKamailioModule,sipt,SIP-T and SIP-I operations,,)) +$(eval $(call BuildKamailioModule,siptrace,SIP trace,,)) +$(eval $(call BuildKamailioModule,siputils,SIP utilities,,+kamailio-mod-sl)) +$(eval $(call BuildKamailioModule,sl,Stateless replier,,)) +$(eval $(call BuildKamailioModule,slack,Slack integration,This module provides integration with Slack over webhooks.,+libcurl,,)) +$(eval $(call BuildKamailioModule,sms,SIP-to-SMS IM gateway,,+kamailio-mod-tm)) +$(eval $(call BuildKamailioModule,smsops,Handle SMS packets in SIP,,)) +$(eval $(call BuildKamailioModule,snmpstats,SNMP interface for statistics,,+libnetsnmp)) +$(eval $(call BuildKamailioModule,speeddial,Per-user speed-dial controller,,)) +$(eval $(call BuildKamailioModule,sqlops,SQL operations,,)) +$(eval $(call BuildKamailioModule,ss7ops,JSON Operations for SS7 over HEP,,)) +$(eval $(call BuildKamailioModule,statistics,Script statistics,,)) +$(eval $(call BuildKamailioModule,statsc,Statistics collector,,)) +$(eval $(call BuildKamailioModule,statsd,Connector for statsd application,,)) +$(eval $(call BuildKamailioModule,stun,STUN server support,,)) +$(eval $(call BuildKamailioModule,sst,SIP Session Timer,,+kamailio-mod-dialog +kamailio-mod-sl)) +$(eval $(call BuildKamailioModule,tcpops,TCP options tweaking operations,,)) +$(eval $(call BuildKamailioModule,textops,Text operations,,)) +$(eval $(call BuildKamailioModule,textopsx,Extra text operations,,)) +$(eval $(call BuildKamailioModule,timer,Execute routing blocks on core timers,,)) +$(eval $(call BuildKamailioModule,tls,TLS operations,,+libopenssl,,tls.cfg)) +$(eval $(call BuildKamailioModule,tmrec,Match time recurrences,,)) +$(eval $(call BuildKamailioModule,topoh,Topology hiding,,+kamailio-mod-rr)) +$(eval $(call BuildKamailioModule,topos,Topology stripping module,,+kamailio-mod-rr)) +$(eval $(call BuildKamailioModule,topos_redis,Redis backend for topos module,,+kamailio-mod-ndb-redis +kamailio-mod-topos)) +$(eval $(call BuildKamailioModule,tm,Transaction,,)) +$(eval $(call BuildKamailioModule,tmx,Transaction module extensions,,)) +$(eval $(call BuildKamailioModule,tsilo,Transaction storage,,+kamailio-mod-registrar +kamailio-mod-sl +kamailio-mod-tm)) +$(eval $(call BuildKamailioModule,uac,User Agent Client,,+kamailio-mod-tm)) +$(eval $(call BuildKamailioModule,uac_redirect,User Agent Client redirection,,+kamailio-mod-tm)) +$(eval $(call BuildKamailioModule,uid_auth_db,Authentication module,,+kamailio-mod-auth)) +$(eval $(call BuildKamailioModule,uid_avp_db,AVP database operations,,)) +$(eval $(call BuildKamailioModule,uid_domain,Domains management,,)) +$(eval $(call BuildKamailioModule,uid_gflags,Global attributes and flags,,)) +$(eval $(call BuildKamailioModule,uid_uri_db,Database URI operations,,)) +$(eval $(call BuildKamailioModule,uri_db,Database-backend SIP URI checking,,)) +$(eval $(call BuildKamailioModule,userblocklist,User blocklists,,+kamailio-lib-libtrie)) +$(eval $(call BuildKamailioModule,usrloc,User location,,)) +$(eval $(call BuildKamailioModule,utils,Misc utilities,,+libcurl,)) +$(eval $(call BuildKamailioModule,uuid,UUID utilities,,+libuuid)) +$(eval $(call BuildKamailioModule,websocket,WebSocket transport layer,,+kamailio-mod-sl +kamailio-mod-tm +libopenssl +libunistring)) +$(eval $(call BuildKamailioModule,xcap_client,XCAP Client,,+libcurl)) +$(eval $(call BuildKamailioModule,xcap_server,XCAP server implementation,,+kamailio-mod-xhttp +kamailio-mod-sl)) +$(eval $(call BuildKamailioModule,xhttp,Basic HTTP request handling server,,+kamailio-mod-sl)) +$(eval $(call BuildKamailioModule,xhttp_pi,HTTP provisioning interface,,+kamailio-mod-xhttp,xhttp_pi,pi_framework.xml)) +$(eval $(call BuildKamailioModule,xhttp_prom,Prometheus metrics,,+kamailio-mod-xhttp,)) +$(eval $(call BuildKamailioModule,xhttp_rpc,RPC commands handling over HTTP,,+kamailio-mod-xhttp)) +$(eval $(call BuildKamailioModule,xlog,Advanced logger,,)) +$(eval $(call BuildKamailioModule,xmlops,XML operations,,)) +$(eval $(call BuildKamailioModule,xmlrpc,XML RPC module,,,)) +$(eval $(call BuildKamailioModule,xmpp,SIP-to-XMPP Gateway,,+kamailio-mod-tm +libexpat)) +$(eval $(call BuildKamailioModule,xprint,Print messages with specifiers,,)) diff --git a/net/kamailio/files/kamailio.conf b/net/kamailio/files/kamailio.conf new file mode 100644 index 000000000..f1a9c36a4 --- /dev/null +++ b/net/kamailio/files/kamailio.conf @@ -0,0 +1,25 @@ + +config kamailio 'general' + option enabled 0 + option user kamailio + option group kamailio + # Amount of shared and private memory to allocate in MByte: + option shm_memory 8 + option pkg_memory 2 + option cfg_file /etc/kamailio/kamailio.cfg + # The lists "listen" and "listen6" basically have the same + # effect - each list entry will be added to the Kamailio command + # line ("-l address"). However, the init script will try to + # resolve any interface specifier into an IPv4 ("listen") or + # IPv6 ("listen6") address before starting Kamailio. These lists + # may be helpful when using dynamic IPs. + #list listen udp:wan:5060 + #list listen udp:192.168.1.1:5060 + #list listen6 udp:wan:5060 + # Any other option can be put between the quotes below: + #option options "" + +config kamailio 'hotplug' + # Uncomment to enable hotplug: + #option interface 'wan' + diff --git a/net/kamailio/files/kamailio.hotplug b/net/kamailio/files/kamailio.hotplug new file mode 100644 index 000000000..0dec974d8 --- /dev/null +++ b/net/kamailio/files/kamailio.hotplug @@ -0,0 +1,24 @@ +#!/bin/sh + +[ "$ACTION" = ifup ] || exit 0 + +NAME=kamailio +COMMAND=/etc/init.d/$NAME +LOGGER="/usr/bin/logger -t hotplug" + +$COMMAND enabled || exit 0 + +. /lib/functions.sh + +config_load $NAME + +config_get_bool enabled general enabled 0 +[ $enabled -eq 0 ] && exit 0 + +config_get hotplug_iface hotplug interface + +[ "$INTERFACE" = "$hotplug_iface" ] && { + $LOGGER "Restarting $NAME due to \"$ACTION\" of \"$INTERFACE\"" + $COMMAND restart +} + diff --git a/net/kamailio/files/kamailio.init b/net/kamailio/files/kamailio.init new file mode 100644 index 000000000..bf3650723 --- /dev/null +++ b/net/kamailio/files/kamailio.init @@ -0,0 +1,131 @@ +#!/bin/sh /etc/rc.common +# Copyright (C) 2014 - 2018 OpenWrt.org + +START=99 + +NAME=kamailio +COMMAND=/usr/sbin/$NAME + +RUNDIR=/var/run/$NAME +PIDFILE=$RUNDIR/$NAME.pid + +LOG_ERR="/usr/bin/logger -p user.err -s -t $NAME" + +USE_PROCD=1 + +#PROCD_DEBUG=1 + +check_listen() { + local value="$1" + local type="$2" + + local address + local has_proto=0 + local one two three + local tmp + + [ -z "$value" ] && { + $LOG_ERR empty $type entry + return 1 + } + + # IPv6 addresses need to be enclosed in square brackets. If there are + # square brackets in the listen entry, just copy it. + echo "$value" | grep "\[[0-9:A-Fa-f]*\]" &> /dev/null && { + options=$options" -l $value" + return + } + + # Bail if more than 2 colons. + [ $(echo "$value" | awk -F ":" '{print NF-1}') -gt 2 ] && { + $LOG_ERR init script does not understand $type entry \""$value"\" + return 1 + } + + IFS=":" read one two three << EOF +$value +EOF + + case "$one" in + udp|tcp|tls|sctp) + tmp="$two" + has_proto=1 + ;; + *) + tmp="$one" + ;; + esac + + if [ "$type" = "listen" ]; then + network_get_ipaddr address "$tmp" || address="$tmp" + else + network_get_ipaddr6 address "$tmp" && address="[$address]" || \ + address="$tmp" + fi + + if [ -n "$three" ]; then + tmp="$one:$address:$three" + elif [ -n "$two" ]; then + if [ $has_proto = 1 ]; then + tmp="$one:$address" + else + tmp="$address:$two" + fi + else + tmp="$address" + fi + + options=$options" -l $tmp" +} + +start_service() { + local enabled + local user + local group + local shm_memory + local pkg_memory + local cfg_file + local options + + config_load $NAME + + config_get_bool enabled general enabled 0 + + if [ $enabled -eq 0 ]; then + $LOG_ERR service not enabled in /etc/config/$NAME + return 1 + fi + + config_get user general user $NAME + config_get group general group $NAME + config_get shm_memory general shm_memory 8 + config_get pkg_memory general pkg_memory 2 + config_get cfg_file general cfg_file /etc/$NAME/$NAME.cfg + config_get options general options + + . /lib/functions/network.sh + + config_list_foreach general listen check_listen listen + config_list_foreach general listen6 check_listen listen6 + + if [ ! -d $RUNDIR ]; then + mkdir -p $RUNDIR + chown "$user":"$group" $RUNDIR + fi + + procd_open_instance + procd_set_param command $COMMAND + procd_append_param command \ + -P $PIDFILE \ + -f "$cfg_file" \ + -m "$shm_memory" \ + -M "$pkg_memory" \ + $options \ + -u "$user" \ + -g "$group" \ + -DD -E + # forward stderr to logd + procd_set_param stderr 1 + procd_close_instance +} + diff --git a/net/kamailio/patches/010-dialplan-clang-format-for-coherent-indentation-and-c.patch b/net/kamailio/patches/010-dialplan-clang-format-for-coherent-indentation-and-c.patch new file mode 100644 index 000000000..3fa8a95b2 --- /dev/null +++ b/net/kamailio/patches/010-dialplan-clang-format-for-coherent-indentation-and-c.patch @@ -0,0 +1,2821 @@ +From 01d0d1de2c82db189c288a157932f4a3ba98970a Mon Sep 17 00:00:00 2001 +From: Victor Seva +Date: Wed, 17 May 2023 16:36:04 +0200 +Subject: [PATCH] dialplan: clang-format for coherent indentation and coding + style + +--- + src/modules/dialplan/dialplan.c | 522 +++++++++++++++----------------- + src/modules/dialplan/dialplan.h | 89 +++--- + src/modules/dialplan/dp_db.c | 364 +++++++++++----------- + src/modules/dialplan/dp_db.h | 38 +-- + src/modules/dialplan/dp_repl.c | 387 +++++++++++------------ + 5 files changed, 701 insertions(+), 699 deletions(-) + +--- a/src/modules/dialplan/dialplan.c ++++ b/src/modules/dialplan/dialplan.c +@@ -35,8 +35,6 @@ + */ + + +- +- + #include + #include + #include +@@ -67,18 +65,19 @@ static void mod_destroy(); + + static int dialplan_init_rpc(void); + +-static int dp_translate_f(struct sip_msg* msg, char* str1, char* str2); +-static int dp_trans_fixup(void ** param, int param_no); +-static int dp_reload_f(struct sip_msg* msg); +-static int w_dp_replace(sip_msg_t* msg, char* pid, char* psrc, char* pdst); +-static int w_dp_match(sip_msg_t* msg, char* pid, char* psrc); +- +-static int ki_dp_translate(sip_msg_t* msg, int id, str *input, str *output); +-static int ki_dp_translate_id(sip_msg_t* msg, int id); +-static int ki_dp_translate_vars(sip_msg_t* msg, int id, str *input, str *output); ++static int dp_translate_f(struct sip_msg *msg, char *str1, char *str2); ++static int dp_trans_fixup(void **param, int param_no); ++static int dp_reload_f(struct sip_msg *msg); ++static int w_dp_replace(sip_msg_t *msg, char *pid, char *psrc, char *pdst); ++static int w_dp_match(sip_msg_t *msg, char *pid, char *psrc); ++ ++static int ki_dp_translate(sip_msg_t *msg, int id, str *input, str *output); ++static int ki_dp_translate_id(sip_msg_t *msg, int id); ++static int ki_dp_translate_vars( ++ sip_msg_t *msg, int id, str *input, str *output); + +-int dp_replace_fixup(void** param, int param_no); +-int dp_replace_fixup_free(void** param, int param_no); ++int dp_replace_fixup(void **param, int param_no); ++int dp_replace_fixup_free(void **param, int param_no); + + str dp_attr_pvar_s = STR_NULL; + pv_spec_t *dp_attr_pvar = NULL; +@@ -93,76 +92,69 @@ int dp_reload_delta = 5; + + static time_t *dp_rpc_reload_time = NULL; + +-static param_export_t mod_params[]={ +- { "db_url", PARAM_STR, &dp_db_url }, +- { "table_name", PARAM_STR, &dp_table_name }, +- { "dpid_col", PARAM_STR, &dpid_column }, +- { "pr_col", PARAM_STR, &pr_column }, +- { "match_op_col", PARAM_STR, &match_op_column }, +- { "match_exp_col", PARAM_STR, &match_exp_column }, +- { "match_len_col", PARAM_STR, &match_len_column }, +- { "subst_exp_col", PARAM_STR, &subst_exp_column }, +- { "repl_exp_col", PARAM_STR, &repl_exp_column }, +- { "attrs_col", PARAM_STR, &attrs_column }, +- { "attrs_pvar", PARAM_STR, &dp_attr_pvar_s }, +- { "fetch_rows", PARAM_INT, &dp_fetch_rows }, +- { "match_dynamic", PARAM_INT, &dp_match_dynamic }, +- { "append_branch", PARAM_INT, &dp_append_branch }, +- { "reload_delta", PARAM_INT, &dp_reload_delta }, +- {0,0,0} +-}; +- +-static cmd_export_t cmds[]={ +- {"dp_translate",(cmd_function)dp_translate_f, 2, dp_trans_fixup, 0, +- ANY_ROUTE}, +- {"dp_translate",(cmd_function)dp_translate_f, 1, dp_trans_fixup, 0, +- ANY_ROUTE}, +- {"dp_reload",(cmd_function)dp_reload_f, 0, 0, 0, +- ANY_ROUTE}, +- {"dp_match",(cmd_function)w_dp_match, 2, fixup_igp_spve, +- fixup_free_igp_spve, ANY_ROUTE}, +- {"dp_replace",(cmd_function)w_dp_replace, 3, dp_replace_fixup, +- dp_replace_fixup_free, ANY_ROUTE}, +- {0,0,0,0,0,0} +-}; +- +-struct module_exports exports= { +- "dialplan", /* module's name */ +- DEFAULT_DLFLAGS, /* dlopen flags */ +- cmds, /* exported functions */ +- mod_params, /* param exports */ +- 0, /* exported RPC functions */ +- 0, /* exported pseudo-variables */ +- 0, /* reply processing function */ +- mod_init, /* module initialization function */ +- child_init, /* per-child init function */ +- mod_destroy /* module destroy function */ ++static param_export_t mod_params[] = {{"db_url", PARAM_STR, &dp_db_url}, ++ {"table_name", PARAM_STR, &dp_table_name}, ++ {"dpid_col", PARAM_STR, &dpid_column}, ++ {"pr_col", PARAM_STR, &pr_column}, ++ {"match_op_col", PARAM_STR, &match_op_column}, ++ {"match_exp_col", PARAM_STR, &match_exp_column}, ++ {"match_len_col", PARAM_STR, &match_len_column}, ++ {"subst_exp_col", PARAM_STR, &subst_exp_column}, ++ {"repl_exp_col", PARAM_STR, &repl_exp_column}, ++ {"attrs_col", PARAM_STR, &attrs_column}, ++ {"attrs_pvar", PARAM_STR, &dp_attr_pvar_s}, ++ {"fetch_rows", PARAM_INT, &dp_fetch_rows}, ++ {"match_dynamic", PARAM_INT, &dp_match_dynamic}, ++ {"append_branch", PARAM_INT, &dp_append_branch}, ++ {"reload_delta", PARAM_INT, &dp_reload_delta}, {0, 0, 0}}; ++ ++static cmd_export_t cmds[] = {{"dp_translate", (cmd_function)dp_translate_f, 2, ++ dp_trans_fixup, 0, ANY_ROUTE}, ++ {"dp_translate", (cmd_function)dp_translate_f, 1, dp_trans_fixup, 0, ++ ANY_ROUTE}, ++ {"dp_reload", (cmd_function)dp_reload_f, 0, 0, 0, ANY_ROUTE}, ++ {"dp_match", (cmd_function)w_dp_match, 2, fixup_igp_spve, ++ fixup_free_igp_spve, ANY_ROUTE}, ++ {"dp_replace", (cmd_function)w_dp_replace, 3, dp_replace_fixup, ++ dp_replace_fixup_free, ANY_ROUTE}, ++ {0, 0, 0, 0, 0, 0}}; ++ ++struct module_exports exports = { ++ "dialplan", /* module's name */ ++ DEFAULT_DLFLAGS, /* dlopen flags */ ++ cmds, /* exported functions */ ++ mod_params, /* param exports */ ++ 0, /* exported RPC functions */ ++ 0, /* exported pseudo-variables */ ++ 0, /* reply processing function */ ++ mod_init, /* module initialization function */ ++ child_init, /* per-child init function */ ++ mod_destroy /* module destroy function */ + }; + + + static int mod_init(void) + { +- if(dialplan_init_rpc()!=0) +- { ++ if(dialplan_init_rpc() != 0) { + LM_ERR("failed to register RPC commands\n"); + return -1; + } + +- LM_DBG("db_url=%s/%d/%p\n", ZSW(dp_db_url.s), dp_db_url.len,dp_db_url.s); ++ LM_DBG("db_url=%s/%d/%p\n", ZSW(dp_db_url.s), dp_db_url.len, dp_db_url.s); + +- if(dp_attr_pvar_s.s && dp_attr_pvar_s.len>0) { ++ if(dp_attr_pvar_s.s && dp_attr_pvar_s.len > 0) { + dp_attr_pvar = pv_cache_get(&dp_attr_pvar_s); +- if( (dp_attr_pvar==NULL) || +- ((dp_attr_pvar->type != PVT_AVP) && +- (dp_attr_pvar->type != PVT_XAVP) && +- (dp_attr_pvar->type != PVT_SCRIPTVAR))) { ++ if((dp_attr_pvar == NULL) ++ || ((dp_attr_pvar->type != PVT_AVP) ++ && (dp_attr_pvar->type != PVT_XAVP) ++ && (dp_attr_pvar->type != PVT_SCRIPTVAR))) { + LM_ERR("invalid pvar name\n"); + return -1; + } + } + + dp_default_par2 = (dp_param_p)shm_malloc(sizeof(dp_param_t)); +- if(dp_default_par2 == NULL){ ++ if(dp_default_par2 == NULL) { + LM_ERR("no shm more memory\n"); + return -1; + } +@@ -171,22 +163,22 @@ static int mod_init(void) + /* emulate "$rU/$rU" as second parameter for dp_translate() */ + dp_default_param_s.len = strlen(dp_default_param_s.s); + dp_default_par2->v.sp[0] = pv_cache_get(&dp_default_param_s); +- if (dp_default_par2->v.sp[0]==NULL) { ++ if(dp_default_par2->v.sp[0] == NULL) { + LM_ERR("input pv is invalid\n"); + return -1; + } + + dp_default_param_s.len = strlen(dp_default_param_s.s); + dp_default_par2->v.sp[1] = pv_cache_get(&dp_default_param_s); +- if (dp_default_par2->v.sp[1]==NULL) { ++ if(dp_default_par2->v.sp[1] == NULL) { + LM_ERR("output pv is invalid\n"); + return -1; + } + +- if(dp_fetch_rows<=0) ++ if(dp_fetch_rows <= 0) + dp_fetch_rows = 1000; + +- if(dp_reload_delta<0) ++ if(dp_reload_delta < 0) + dp_reload_delta = 5; + + if(init_data() != 0) { +@@ -214,11 +206,11 @@ static int child_init(int rank) + static void mod_destroy(void) + { + /*destroy shared memory*/ +- if(dp_default_par2){ ++ if(dp_default_par2) { + shm_free(dp_default_par2); + dp_default_par2 = NULL; + } +- if(dp_rpc_reload_time!=NULL) { ++ if(dp_rpc_reload_time != NULL) { + shm_free(dp_rpc_reload_time); + dp_rpc_reload_time = 0; + } +@@ -226,20 +218,21 @@ static void mod_destroy(void) + } + + +-static int dp_get_ivalue(struct sip_msg* msg, dp_param_p dp, int *val) ++static int dp_get_ivalue(struct sip_msg *msg, dp_param_p dp, int *val) + { + pv_value_t value; + +- if(dp->type==DP_VAL_INT) { ++ if(dp->type == DP_VAL_INT) { + *val = dp->v.id; + LM_DBG("dpid is %d from constant argument\n", *val); + return 0; + } + +- LM_DBG("searching %d\n",dp->v.sp[0]->type); ++ LM_DBG("searching %d\n", dp->v.sp[0]->type); + +- if( pv_get_spec_value( msg, dp->v.sp[0], &value)!=0 +- || value.flags&(PV_VAL_NULL|PV_VAL_EMPTY) || !(value.flags&PV_VAL_INT)) { ++ if(pv_get_spec_value(msg, dp->v.sp[0], &value) != 0 ++ || value.flags & (PV_VAL_NULL | PV_VAL_EMPTY) ++ || !(value.flags & PV_VAL_INT)) { + LM_ERR("no AVP, XAVP or SCRIPTVAR found (error in scripts)\n"); + return -1; + } +@@ -249,14 +242,14 @@ static int dp_get_ivalue(struct sip_msg* + } + + +-static int dp_get_svalue(struct sip_msg * msg, pv_spec_t *spec, str* val) ++static int dp_get_svalue(struct sip_msg *msg, pv_spec_t *spec, str *val) + { + pv_value_t value; + + LM_DBG("searching %d \n", spec->type); + +- if ( pv_get_spec_value(msg,spec,&value)!=0 || value.flags&PV_VAL_NULL +- || value.flags&PV_VAL_EMPTY || !(value.flags&PV_VAL_STR)){ ++ if(pv_get_spec_value(msg, spec, &value) != 0 || value.flags & PV_VAL_NULL ++ || value.flags & PV_VAL_EMPTY || !(value.flags & PV_VAL_STR)) { + LM_ERR("no AVP, XAVP or SCRIPTVAR found (error in scripts)\n"); + return -1; + } +@@ -266,8 +259,8 @@ static int dp_get_svalue(struct sip_msg + } + + +-static int dp_update(struct sip_msg * msg, pv_spec_t * dest, +- str * repl, str * attrs) ++static int dp_update( ++ struct sip_msg *msg, pv_spec_t *dest, str *repl, str *attrs) + { + int no_change; + pv_value_t val; +@@ -275,16 +268,16 @@ static int dp_update(struct sip_msg * ms + memset(&val, 0, sizeof(pv_value_t)); + val.flags = PV_VAL_STR; + +- no_change = (dest==NULL) || (dest->type == PVT_NONE) +- || (!repl->s) || (!repl->len); ++ no_change = (dest == NULL) || (dest->type == PVT_NONE) || (!repl->s) ++ || (!repl->len); + +- if (no_change) ++ if(no_change) + goto set_attr_pvar; + + val.rs = *repl; + + if(dest->setf) { +- if(dest->setf(msg, &dest->pvp, (int)EQ_T, &val)<0) { ++ if(dest->setf(msg, &dest->pvp, (int)EQ_T, &val) < 0) { + LM_ERR("setting dst pseudo-variable failed\n"); + return -1; + } +@@ -292,7 +285,7 @@ static int dp_update(struct sip_msg * ms + LM_WARN("target variable is read only - skipping setting its value\n"); + } + +- if(dp_append_branch!=0) { ++ if(dp_append_branch != 0) { + if(is_route_type(FAILURE_ROUTE) + && (dest->type == PVT_RURI + || dest->type == PVT_RURI_USERNAME)) { +@@ -306,12 +299,11 @@ static int dp_update(struct sip_msg * ms + + set_attr_pvar: + +- if(dp_attr_pvar==NULL || attrs==NULL) ++ if(dp_attr_pvar == NULL || attrs == NULL) + return 0; + + val.rs = *attrs; +- if(dp_attr_pvar->setf(msg, &dp_attr_pvar->pvp, (int)EQ_T, &val)<0) +- { ++ if(dp_attr_pvar->setf(msg, &dp_attr_pvar->pvp, (int)EQ_T, &val) < 0) { + LM_ERR("setting attr pseudo-variable failed\n"); + return -1; + } +@@ -320,7 +312,7 @@ set_attr_pvar: + } + + +-static int dp_translate_f(struct sip_msg* msg, char* str1, char* str2) ++static int dp_translate_f(struct sip_msg *msg, char *str1, char *str2) + { + int dpid; + str input, output; +@@ -332,59 +324,60 @@ static int dp_translate_f(struct sip_msg + return -1; + + /*verify first param's value*/ +- id_par = (dp_param_p) str1; +- if (dp_get_ivalue(msg, id_par, &dpid) != 0){ ++ id_par = (dp_param_p)str1; ++ if(dp_get_ivalue(msg, id_par, &dpid) != 0) { + LM_ERR("no dpid value\n"); + return -1; + } + +- if ((idp = select_dpid(dpid)) ==0 ){ ++ if((idp = select_dpid(dpid)) == 0) { + LM_DBG("no information available for dpid %i\n", dpid); + return -2; + } + +- repl_par = (str2!=NULL)? ((dp_param_p)str2):dp_default_par2; +- if (dp_get_svalue(msg, repl_par->v.sp[0], &input)!=0){ ++ repl_par = (str2 != NULL) ? ((dp_param_p)str2) : dp_default_par2; ++ if(dp_get_svalue(msg, repl_par->v.sp[0], &input) != 0) { + LM_ERR("invalid param 2\n"); + return -1; + } + + LM_DBG("input is %.*s\n", input.len, input.s); + +- outattrs = (!dp_attr_pvar)?NULL:&attrs; +- if (dp_translate_helper(msg, &input, &output, idp, outattrs)!=0) { ++ outattrs = (!dp_attr_pvar) ? NULL : &attrs; ++ if(dp_translate_helper(msg, &input, &output, idp, outattrs) != 0) { + LM_DBG("could not translate %.*s " +- "with dpid %i\n", input.len, input.s, idp->dp_id); ++ "with dpid %i\n", ++ input.len, input.s, idp->dp_id); + return -1; + } +- LM_DBG("input %.*s with dpid %i => output %.*s\n", +- input.len, input.s, idp->dp_id, output.len, output.s); ++ LM_DBG("input %.*s with dpid %i => output %.*s\n", input.len, input.s, ++ idp->dp_id, output.len, output.s); + + /* set the output */ +- if (dp_update(msg, repl_par->v.sp[1], &output, outattrs) !=0){ ++ if(dp_update(msg, repl_par->v.sp[1], &output, outattrs) != 0) { + LM_ERR("cannot set the output\n"); + return -1; + } + + return 1; +- + } + +-#define verify_par_type(_par_no, _spec, _ret) \ +- do{\ +- if( ((_par_no == 1) \ +- && (_spec->type != PVT_AVP) && (_spec->type != PVT_XAVP) && \ +- (_spec->type!=PVT_SCRIPTVAR) )\ +- ||((_par_no == 2) \ +- && (_spec->type != PVT_AVP) && (_spec->type != PVT_XAVP) && \ +- (_spec->type!=PVT_SCRIPTVAR) \ +- && (_spec->type!=PVT_RURI) && (_spec->type!=PVT_RURI_USERNAME))){\ +- \ +- LM_ERR("Unsupported Parameter TYPE[%d]\n", _spec->type);\ +- _ret = E_UNSPEC; \ +- goto error; \ +- }\ +- }while(0); ++#define verify_par_type(_par_no, _spec, _ret) \ ++ do { \ ++ if(((_par_no == 1) && (_spec->type != PVT_AVP) \ ++ && (_spec->type != PVT_XAVP) \ ++ && (_spec->type != PVT_SCRIPTVAR)) \ ++ || ((_par_no == 2) && (_spec->type != PVT_AVP) \ ++ && (_spec->type != PVT_XAVP) \ ++ && (_spec->type != PVT_SCRIPTVAR) \ ++ && (_spec->type != PVT_RURI) \ ++ && (_spec->type != PVT_RURI_USERNAME))) { \ ++ \ ++ LM_ERR("Unsupported Parameter TYPE[%d]\n", _spec->type); \ ++ _ret = E_UNSPEC; \ ++ goto error; \ ++ } \ ++ } while(0); + + + /* first param: DPID: type: INT, AVP, XAVP, SVAR +@@ -392,19 +385,20 @@ static int dp_translate_f(struct sip_msg + * second param: DST type: RURI, RURI_USERNAME, AVP, XAVP, SVAR, N/A + * default value for the second param: $ru.user/$ru.user + */ +-static int dp_trans_fixup(void ** param, int param_no){ ++static int dp_trans_fixup(void **param, int param_no) ++{ + + int dpid; +- dp_param_p dp_par= NULL; +- char *p, *s=NULL; ++ dp_param_p dp_par = NULL; ++ char *p, *s = NULL; + str lstr; + int ret = E_INVALID_PARAMS; + +- if(param_no!=1 && param_no!=2) ++ if(param_no != 1 && param_no != 2) + return 0; + +- p = (char*)*param; +- if(!p || (*p == '\0')){ ++ p = (char *)*param; ++ if(!p || (*p == '\0')) { + LM_DBG("null param %i\n", param_no); + return E_CFG; + } +@@ -412,7 +406,7 @@ static int dp_trans_fixup(void ** param, + LM_DBG("param_no is %i\n", param_no); + + dp_par = (dp_param_p)pkg_malloc(sizeof(dp_param_t)); +- if(dp_par == NULL){ ++ if(dp_par == NULL) { + LM_ERR("no more pkg memory\n"); + return E_OUT_OF_MEM; + } +@@ -421,19 +415,21 @@ static int dp_trans_fixup(void ** param, + if(param_no == 1) { + if(*p != '$') { + dp_par->type = DP_VAL_INT; +- lstr.s = *param; lstr.len = strlen(*param); ++ lstr.s = *param; ++ lstr.len = strlen(*param); + if(str2sint(&lstr, &dpid) != 0) { +- LM_ERR("bad number <%s>\n",(char *)(*param)); ++ LM_ERR("bad number <%s>\n", (char *)(*param)); + ret = E_CFG; + goto error; + } + + dp_par->type = DP_VAL_INT; + dp_par->v.id = dpid; +- }else{ +- lstr.s = p; lstr.len = strlen(p); ++ } else { ++ lstr.s = p; ++ lstr.len = strlen(p); + dp_par->v.sp[0] = pv_cache_get(&lstr); +- if (dp_par->v.sp[0]==NULL) { ++ if(dp_par->v.sp[0] == NULL) { + goto error; + } + +@@ -442,30 +438,32 @@ static int dp_trans_fixup(void ** param, + } + } else { + +- if (((s = strchr(p, '/')) != 0) && (*(s+1)=='\0')) ++ if(((s = strchr(p, '/')) != 0) && (*(s + 1) == '\0')) + goto error; + +- if (s != 0) { +- *s = '\0'; s++; ++ if(s != 0) { ++ *s = '\0'; ++ s++; + } + +- lstr.s = p; lstr.len = strlen(p); ++ lstr.s = p; ++ lstr.len = strlen(p); + dp_par->v.sp[0] = pv_cache_get(&lstr); +- if(dp_par->v.sp[0]==NULL) { ++ if(dp_par->v.sp[0] == NULL) { + goto error; + } + +- if (s != 0) { +- lstr.s = s; lstr.len = strlen(s); ++ if(s != 0) { ++ lstr.s = s; ++ lstr.len = strlen(s); + dp_par->v.sp[1] = pv_cache_get(&lstr); +- if (dp_par->v.sp[1]==NULL) { ++ if(dp_par->v.sp[1] == NULL) { + goto error; + } + verify_par_type(param_no, dp_par->v.sp[1], ret); + } + + dp_par->type = DP_VAL_SPEC; +- + } + + *param = (void *)dp_par; +@@ -474,13 +472,14 @@ static int dp_trans_fixup(void ** param, + + error: + LM_ERR("failed to parse param %i\n", param_no); +- if(dp_par) pkg_free(dp_par); ++ if(dp_par) ++ pkg_free(dp_par); + + return ret; + } + +-static int dp_replace_helper(sip_msg_t *msg, int dpid, str *input, +- pv_spec_t *pvd) ++static int dp_replace_helper( ++ sip_msg_t *msg, int dpid, str *input, pv_spec_t *pvd) + { + dpl_id_p idp; + str tmp = STR_NULL; +@@ -488,25 +487,26 @@ static int dp_replace_helper(sip_msg_t * + str *output = NULL; + str *outattrs = NULL; + +- if ((idp = select_dpid(dpid)) ==0) { ++ if((idp = select_dpid(dpid)) == 0) { + LM_DBG("no information available for dpid %i\n", dpid); + return -2; + } + +- outattrs = (!dp_attr_pvar)?NULL:&attrs; +- output = (!pvd)?NULL:&tmp; +- if (dp_translate_helper(msg, input, output, idp, outattrs)!=0) { ++ outattrs = (!dp_attr_pvar) ? NULL : &attrs; ++ output = (!pvd) ? NULL : &tmp; ++ if(dp_translate_helper(msg, input, output, idp, outattrs) != 0) { + LM_DBG("could not translate %.*s " +- "with dpid %i\n", input->len, input->s, idp->dp_id); ++ "with dpid %i\n", ++ input->len, input->s, idp->dp_id); + return -1; + } +- if (output) { +- LM_DBG("input %.*s with dpid %i => output %.*s\n", +- input->len, input->s, idp->dp_id, output->len, output->s); ++ if(output) { ++ LM_DBG("input %.*s with dpid %i => output %.*s\n", input->len, input->s, ++ idp->dp_id, output->len, output->s); + } + + /* set the output */ +- if (dp_update(msg, pvd, output, outattrs) !=0){ ++ if(dp_update(msg, pvd, output, outattrs) != 0) { + LM_ERR("cannot set the output\n"); + return -1; + } +@@ -514,31 +514,31 @@ static int dp_replace_helper(sip_msg_t * + return 1; + } + +-static int w_dp_replace(sip_msg_t* msg, char* pid, char* psrc, char* pdst) ++static int w_dp_replace(sip_msg_t *msg, char *pid, char *psrc, char *pdst) + { + int dpid = 1; + str src = STR_NULL; + pv_spec_t *pvd = NULL; + +- if(fixup_get_ivalue(msg, (gparam_t*)pid, &dpid)<0) { ++ if(fixup_get_ivalue(msg, (gparam_t *)pid, &dpid) < 0) { + LM_ERR("failed to get dialplan id value\n"); + return -1; + } +- if(fixup_get_svalue(msg, (gparam_t*)psrc, &src)<0) { ++ if(fixup_get_svalue(msg, (gparam_t *)psrc, &src) < 0) { + LM_ERR("failed to get src value\n"); + return -1; + } +- pvd = (pv_spec_t*)pdst; ++ pvd = (pv_spec_t *)pdst; + + return dp_replace_helper(msg, dpid, &src, pvd); + } + +-static int ki_dp_replace(sip_msg_t* msg, int dpid, str* src, str* dst) ++static int ki_dp_replace(sip_msg_t *msg, int dpid, str *src, str *dst) + { + pv_spec_t *pvd = NULL; + + pvd = pv_cache_get(dst); +- if(pvd==NULL) { ++ if(pvd == NULL) { + LM_ERR("cannot get pv spec for [%.*s]\n", dst->len, dst->s); + return -1; + } +@@ -546,16 +546,16 @@ static int ki_dp_replace(sip_msg_t* msg, + return dp_replace_helper(msg, dpid, src, pvd); + } + +-static int w_dp_match(sip_msg_t* msg, char* pid, char* psrc) ++static int w_dp_match(sip_msg_t *msg, char *pid, char *psrc) + { + int dpid = 1; + str src = STR_NULL; + +- if(fixup_get_ivalue(msg, (gparam_t*)pid, &dpid)<0) { ++ if(fixup_get_ivalue(msg, (gparam_t *)pid, &dpid) < 0) { + LM_ERR("failed to get dialplan id value\n"); + return -1; + } +- if(fixup_get_svalue(msg, (gparam_t*)psrc, &src)<0) { ++ if(fixup_get_svalue(msg, (gparam_t *)psrc, &src) < 0) { + LM_ERR("failed to get src value\n"); + return -1; + } +@@ -563,30 +563,30 @@ static int w_dp_match(sip_msg_t* msg, ch + return dp_replace_helper(msg, dpid, &src, NULL); + } + +-static int ki_dp_match(sip_msg_t* msg, int dpid, str* src) ++static int ki_dp_match(sip_msg_t *msg, int dpid, str *src) + { + return dp_replace_helper(msg, dpid, src, NULL); + } + +-int dp_replace_fixup(void** param, int param_no) ++int dp_replace_fixup(void **param, int param_no) + { +- if (param_no == 1) ++ if(param_no == 1) + return fixup_igp_null(param, param_no); +- else if (param_no == 2) ++ else if(param_no == 2) + return fixup_spve_all(param, param_no); +- else if (param_no == 3) ++ else if(param_no == 3) + return fixup_pvar_all(param, param_no); + return E_UNSPEC; + } + + +-int dp_replace_fixup_free(void** param, int param_no) ++int dp_replace_fixup_free(void **param, int param_no) + { +- if (param_no == 1) ++ if(param_no == 1) + return fixup_free_igp_null(param, param_no); +- else if (param_no == 2) ++ else if(param_no == 2) + return fixup_free_spve_all(param, param_no); +- else if (param_no == 3) ++ else if(param_no == 3) + return fixup_free_pvar_all(param, param_no); + return E_UNSPEC; + } +@@ -594,14 +594,14 @@ int dp_replace_fixup_free(void** param, + /** + * trigger reload of dialplan db records from config file + */ +-static int dp_reload_f(struct sip_msg* msg) ++static int dp_reload_f(struct sip_msg *msg) + { +- if (dp_connect_db() < 0) { ++ if(dp_connect_db() < 0) { + LM_ERR("failed to reload rules fron database (db connect)\n"); + return -1; + } + +- if(dp_load_db() != 0){ ++ if(dp_load_db() != 0) { + LM_ERR("failed to reload rules fron database (db load)\n"); + dp_disconnect_db(); + return -1; +@@ -614,35 +614,34 @@ static int dp_reload_f(struct sip_msg* m + } + + +-static const char* dialplan_rpc_reload_doc[2] = { +- "Reload dialplan table from database", +- 0 +-}; ++static const char *dialplan_rpc_reload_doc[2] = { ++ "Reload dialplan table from database", 0}; + + + /* + * RPC command to reload dialplan table + */ +-static void dialplan_rpc_reload(rpc_t* rpc, void* ctx) ++static void dialplan_rpc_reload(rpc_t *rpc, void *ctx) + { +- if(dp_rpc_reload_time==NULL) { ++ if(dp_rpc_reload_time == NULL) { + LM_ERR("not ready for reload\n"); + rpc->fault(ctx, 500, "Not ready for reload"); + return; + } +- if(*dp_rpc_reload_time!=0 && *dp_rpc_reload_time > time(NULL) - dp_reload_delta) { ++ if(*dp_rpc_reload_time != 0 ++ && *dp_rpc_reload_time > time(NULL) - dp_reload_delta) { + LM_ERR("ongoing reload\n"); + rpc->fault(ctx, 500, "ongoing reload"); + return; + } + *dp_rpc_reload_time = time(NULL); +- if (dp_connect_db() < 0) { ++ if(dp_connect_db() < 0) { + LM_ERR("failed to reload rules fron database (db connect)\n"); + rpc->fault(ctx, 500, "DB Connection Error"); + return; + } + +- if(dp_load_db() != 0){ ++ if(dp_load_db() != 0) { + LM_ERR("failed to reload rules fron database (db load)\n"); + dp_disconnect_db(); + rpc->fault(ctx, 500, "Dialplan Reload Failed"); +@@ -654,63 +653,55 @@ static void dialplan_rpc_reload(rpc_t* r + } + + +- +-static const char* dialplan_rpc_translate_doc[2] = { +- "Perform dialplan translation", +- 0 +-}; ++static const char *dialplan_rpc_translate_doc[2] = { ++ "Perform dialplan translation", 0}; + + + /* + * RPC command to perform dialplan translation + */ +-static void dialplan_rpc_translate(rpc_t* rpc, void* ctx) ++static void dialplan_rpc_translate(rpc_t *rpc, void *ctx) + { + dpl_id_p idp; + str input; + int dpid; +- str attrs = {"", 0}; ++ str attrs = {"", 0}; + str output = {0, 0}; +- void* th; ++ void *th; + +- if (rpc->scan(ctx, "dS", &dpid, &input) < 2) +- { ++ if(rpc->scan(ctx, "dS", &dpid, &input) < 2) { + rpc->fault(ctx, 500, "Invalid parameters"); + return; + } + +- if ((idp = select_dpid(dpid)) == 0 ){ ++ if((idp = select_dpid(dpid)) == 0) { + LM_ERR("no information available for dpid %i\n", dpid); + rpc->fault(ctx, 500, "Dialplan ID not matched"); + return; + } + +- if(input.s == NULL || input.len== 0) { ++ if(input.s == NULL || input.len == 0) { + LM_ERR("empty input parameter\n"); + rpc->fault(ctx, 500, "Empty input parameter"); + return; + } + +- LM_DBG("trying to translate %.*s with dpid %i\n", +- input.len, input.s, idp->dp_id); +- if (dp_translate_helper(NULL, &input, &output, idp, &attrs)!=0){ +- LM_DBG("could not translate %.*s with dpid %i\n", +- input.len, input.s, idp->dp_id); ++ LM_DBG("trying to translate %.*s with dpid %i\n", input.len, input.s, ++ idp->dp_id); ++ if(dp_translate_helper(NULL, &input, &output, idp, &attrs) != 0) { ++ LM_DBG("could not translate %.*s with dpid %i\n", input.len, input.s, ++ idp->dp_id); + rpc->fault(ctx, 500, "No translation"); + return; + } +- LM_DBG("input %.*s with dpid %i => output %.*s\n", +- input.len, input.s, idp->dp_id, output.len, output.s); ++ LM_DBG("input %.*s with dpid %i => output %.*s\n", input.len, input.s, ++ idp->dp_id, output.len, output.s); + +- if (rpc->add(ctx, "{", &th) < 0) +- { ++ if(rpc->add(ctx, "{", &th) < 0) { + rpc->fault(ctx, 500, "Internal error creating rpc"); + return; + } +- if(rpc->struct_add(th, "SS", +- "Output", &output, +- "Attributes", &attrs)<0) +- { ++ if(rpc->struct_add(th, "SS", "Output", &output, "Attributes", &attrs) < 0) { + rpc->fault(ctx, 500, "Internal error creating rpc"); + return; + } +@@ -721,23 +712,22 @@ static void dialplan_rpc_translate(rpc_t + /* + * RPC command to dump dialplan + */ +-static void dialplan_rpc_dump(rpc_t* rpc, void* ctx) ++static void dialplan_rpc_dump(rpc_t *rpc, void *ctx) + { + dpl_id_p idp; + dpl_index_p indexp; + dpl_node_p rulep; + int dpid; +- void* th; +- void* ih; +- void* sh; ++ void *th; ++ void *ih; ++ void *sh; + +- if (rpc->scan(ctx, "d", &dpid) < 1) +- { ++ if(rpc->scan(ctx, "d", &dpid) < 1) { + rpc->fault(ctx, 500, "Missing parameter"); + return; + } + +- if ((idp = select_dpid(dpid)) == 0 ) { ++ if((idp = select_dpid(dpid)) == 0) { + LM_ERR("no information available for dpid %i\n", dpid); + rpc->fault(ctx, 500, "Dialplan ID not matched"); + return; +@@ -746,58 +736,49 @@ static void dialplan_rpc_dump(rpc_t* rpc + LM_DBG("trying to dump dpid %i\n", idp->dp_id); + + /* add entry node */ +- if (rpc->add(ctx, "{", &th) < 0) +- { ++ if(rpc->add(ctx, "{", &th) < 0) { + rpc->fault(ctx, 500, "Internal error root reply"); + return; + } + +- if(rpc->struct_add(th, "d[", +- "DPID", dpid, +- "ENTRIES", &ih)<0) +- { ++ if(rpc->struct_add(th, "d[", "DPID", dpid, "ENTRIES", &ih) < 0) { + rpc->fault(ctx, 500, "Internal error sets structure"); + return; + } + +- for(indexp=idp->first_index; indexp!=NULL;indexp=indexp->next) { ++ for(indexp = idp->first_index; indexp != NULL; indexp = indexp->next) { + LM_DBG("INDEX LEN: %i\n", indexp->len); +- for(rulep = indexp->first_rule; rulep!= NULL;rulep = rulep->next) { ++ for(rulep = indexp->first_rule; rulep != NULL; rulep = rulep->next) { + LM_DBG("DPID: %i PRIO : %i\n", rulep->dpid, rulep->pr); +- if (rpc->struct_add(ih, "{","ENTRY", &sh) < 0) +- { ++ if(rpc->struct_add(ih, "{", "ENTRY", &sh) < 0) { + rpc->fault(ctx, 500, "Internal error root reply"); + return; + } + +- if (rpc->struct_add(sh, "dd", "PRIO", rulep->pr, +- "MATCHOP", rulep->matchop)<0) +- { ++ if(rpc->struct_add( ++ sh, "dd", "PRIO", rulep->pr, "MATCHOP", rulep->matchop) ++ < 0) { + rpc->fault(ctx, 500, "Internal error adding prio"); + return; + } +- if (rpc->struct_add(sh, "s", "MATCHEXP", rulep->match_exp) < 0 ) +- { ++ if(rpc->struct_add(sh, "s", "MATCHEXP", rulep->match_exp) < 0) { + rpc->fault(ctx, 500, "Internal error adding match exp"); + return; + } +- if (rpc->struct_add(sh, "d", "MATCHLEN", rulep->matchlen) < 0 ) +- { +- rpc->fault(ctx, 500, "Internal error adding expression data and attribute"); ++ if(rpc->struct_add(sh, "d", "MATCHLEN", rulep->matchlen) < 0) { ++ rpc->fault(ctx, 500, ++ "Internal error adding expression data and attribute"); + return; + } +- if (rpc->struct_add(sh, "s", "SUBSTEXP", rulep->subst_exp) < 0 ) +- { ++ if(rpc->struct_add(sh, "s", "SUBSTEXP", rulep->subst_exp) < 0) { + rpc->fault(ctx, 500, "Internal error adding subst exp"); + return; + } +- if (rpc->struct_add(sh, "s", "REPLEXP", rulep->repl_exp) < 0 ) +- { ++ if(rpc->struct_add(sh, "s", "REPLEXP", rulep->repl_exp) < 0) { + rpc->fault(ctx, 500, "Internal error adding replace exp "); + return; + } +- if (rpc->struct_add(sh, "s", "ATTRS", rulep->attrs) < 0 ) +- { ++ if(rpc->struct_add(sh, "s", "ATTRS", rulep->attrs) < 0) { + rpc->fault(ctx, 500, "Internal error adding attribute"); + return; + } +@@ -807,26 +788,19 @@ static void dialplan_rpc_dump(rpc_t* rpc + return; + } + +-static const char* dialplan_rpc_dump_doc[2] = { +- "Dump dialplan content", +- 0 +-}; ++static const char *dialplan_rpc_dump_doc[2] = {"Dump dialplan content", 0}; + + + rpc_export_t dialplan_rpc_list[] = { +- {"dialplan.reload", dialplan_rpc_reload, +- dialplan_rpc_reload_doc, 0}, +- {"dialplan.translate", dialplan_rpc_translate, +- dialplan_rpc_translate_doc, 0}, +- {"dialplan.dump", dialplan_rpc_dump, +- dialplan_rpc_dump_doc, 0}, +- {0, 0, 0, 0} +-}; ++ {"dialplan.reload", dialplan_rpc_reload, dialplan_rpc_reload_doc, 0}, ++ {"dialplan.translate", dialplan_rpc_translate, ++ dialplan_rpc_translate_doc, 0}, ++ {"dialplan.dump", dialplan_rpc_dump, dialplan_rpc_dump_doc, 0}, ++ {0, 0, 0, 0}}; + + static int dialplan_init_rpc(void) + { +- if (rpc_register_array(dialplan_rpc_list)!=0) +- { ++ if(rpc_register_array(dialplan_rpc_list) != 0) { + LM_ERR("failed to register RPC commands\n"); + return -1; + } +@@ -863,20 +837,22 @@ static sr_kemi_t sr_kemi_dialplan_export + }; + /* clang-format on */ + +-static int ki_dp_translate(sip_msg_t* msg, int id, str *input_spv, str *output_spv) { ++static int ki_dp_translate( ++ sip_msg_t *msg, int id, str *input_spv, str *output_spv) ++{ + str input, output; + dpl_id_p idp; + str attrs, *outattrs; + pv_spec_t *pvs_i = NULL, *pvs_o = NULL; + +- if (!msg) ++ if(!msg) + return -1; + +- if (input_spv != NULL && (input_spv->s == NULL || input_spv->len <= 0)) { ++ if(input_spv != NULL && (input_spv->s == NULL || input_spv->len <= 0)) { + LM_ERR("invalid destination var name for input\n"); + return -1; + } +- if (output_spv != NULL && (output_spv->s == NULL || output_spv->len <= 0)) { ++ if(output_spv != NULL && (output_spv->s == NULL || output_spv->len <= 0)) { + LM_ERR("invalid destination var name for output\n"); + return -1; + } +@@ -892,56 +868,60 @@ static int ki_dp_translate(sip_msg_t* ms + pvs_o = pv_cache_get(output_spv); + } + +- if (pvs_i == NULL || pvs_o == NULL) { ++ if(pvs_i == NULL || pvs_o == NULL) { + LM_ERR("cannot get pv spec for input or output\n"); + return -1; + } + +- if ((pvs_i->type!=PVT_AVP && pvs_i->type!=PVT_XAVP && pvs_i->type!=PVT_SCRIPTVAR && +- pvs_i->type!=PVT_RURI && pvs_i->type!=PVT_RURI_USERNAME) || +- (pvs_o->type!=PVT_AVP && pvs_o->type!=PVT_XAVP && pvs_o->type!=PVT_SCRIPTVAR && +- pvs_o->type!=PVT_RURI && pvs_o->type!=PVT_RURI_USERNAME)) { ++ if((pvs_i->type != PVT_AVP && pvs_i->type != PVT_XAVP ++ && pvs_i->type != PVT_SCRIPTVAR && pvs_i->type != PVT_RURI ++ && pvs_i->type != PVT_RURI_USERNAME) ++ || (pvs_o->type != PVT_AVP && pvs_o->type != PVT_XAVP ++ && pvs_o->type != PVT_SCRIPTVAR && pvs_o->type != PVT_RURI ++ && pvs_o->type != PVT_RURI_USERNAME)) { + LM_ERR("type of pv error\n"); + return -1; + } + +- if ((idp = select_dpid(id)) ==0 ){ ++ if((idp = select_dpid(id)) == 0) { + LM_DBG("no information available for dpid %i\n", id); + return -2; + } + + /* get the input */ +- if (dp_get_svalue(msg, pvs_i, &input)!=0){ ++ if(dp_get_svalue(msg, pvs_i, &input) != 0) { + LM_ERR("invalid param 2\n"); + return -1; + } + + LM_DBG("input is %.*s\n", input.len, input.s); + +- outattrs = (!dp_attr_pvar)?NULL:&attrs; +- if (dp_translate_helper(msg, &input, &output, idp, outattrs)!=0) { ++ outattrs = (!dp_attr_pvar) ? NULL : &attrs; ++ if(dp_translate_helper(msg, &input, &output, idp, outattrs) != 0) { + LM_DBG("could not translate %.*s " +- "with dpid %i\n", input.len, input.s, idp->dp_id); ++ "with dpid %i\n", ++ input.len, input.s, idp->dp_id); + return -1; + } +- LM_DBG("input %.*s with dpid %i => output %.*s\n", +- input.len, input.s, idp->dp_id, output.len, output.s); ++ LM_DBG("input %.*s with dpid %i => output %.*s\n", input.len, input.s, ++ idp->dp_id, output.len, output.s); + + /* set the output */ +- if (dp_update(msg, pvs_o, &output, outattrs) !=0){ ++ if(dp_update(msg, pvs_o, &output, outattrs) != 0) { + LM_ERR("cannot set the output\n"); + return -1; + } + + return 1; +- + } + +-static int ki_dp_translate_id(sip_msg_t* msg, int id) { ++static int ki_dp_translate_id(sip_msg_t *msg, int id) ++{ + return ki_dp_translate(msg, id, NULL, NULL); + } + +-static int ki_dp_translate_vars(sip_msg_t* msg, int id, str *input, str *output) { ++static int ki_dp_translate_vars(sip_msg_t *msg, int id, str *input, str *output) ++{ + return ki_dp_translate(msg, id, input, output); + } + +--- a/src/modules/dialplan/dialplan.h ++++ b/src/modules/dialplan/dialplan.h +@@ -34,59 +34,64 @@ + #include "../../core/pvar.h" + #include "../../core/parser/msg_parser.h" + +-#define DP_EQUAL_OP 0 +-#define DP_REGEX_OP 1 +-#define DP_FNMATCH_OP 2 +- +-#define MAX_REPLACE_WITH 10 +- +-#define DP_TFLAGS_PV_MATCH (1 << 0) +-#define DP_TFLAGS_PV_SUBST (1 << 1) +- +-typedef struct dpl_node { +- int dpid; /* dialplan id */ +- int pr; /* priority */ +- int matchop; /* matching operator */ +- int matchlen; /* matching value length */ +- str match_exp; /* match-first string */ +- str subst_exp; /* match string with subtitution groupping */ +- str repl_exp; /* replacement expression string */ +- pcre *match_comp; /* compiled matching expression */ +- pcre *subst_comp; /* compiled substitution expression */ ++#define DP_EQUAL_OP 0 ++#define DP_REGEX_OP 1 ++#define DP_FNMATCH_OP 2 ++ ++#define MAX_REPLACE_WITH 10 ++ ++#define DP_TFLAGS_PV_MATCH (1 << 0) ++#define DP_TFLAGS_PV_SUBST (1 << 1) ++ ++typedef struct dpl_node ++{ ++ int dpid; /* dialplan id */ ++ int pr; /* priority */ ++ int matchop; /* matching operator */ ++ int matchlen; /* matching value length */ ++ str match_exp; /* match-first string */ ++ str subst_exp; /* match string with subtitution groupping */ ++ str repl_exp; /* replacement expression string */ ++ pcre *match_comp; /* compiled matching expression */ ++ pcre *subst_comp; /* compiled substitution expression */ + struct subst_expr *repl_comp; /* compiled replacement */ +- str attrs; /* attributes string */ +- unsigned int tflags; /* flags for type of values for matching */ ++ str attrs; /* attributes string */ ++ unsigned int tflags; /* flags for type of values for matching */ + +- struct dpl_node * next; /* next rule */ ++ struct dpl_node *next; /* next rule */ + } dpl_node_t, *dpl_node_p; + + /*For every distinct length of a matching string*/ +-typedef struct dpl_index{ ++typedef struct dpl_index ++{ + int len; +- dpl_node_t * first_rule; +- dpl_node_t * last_rule; ++ dpl_node_t *first_rule; ++ dpl_node_t *last_rule; + +- struct dpl_index * next; +-}dpl_index_t, *dpl_index_p; ++ struct dpl_index *next; ++} dpl_index_t, *dpl_index_p; + + /*For every DPID*/ +-typedef struct dpl_id{ ++typedef struct dpl_id ++{ + int dp_id; +- dpl_index_t* first_index;/*fast access :rules with specific length*/ +- struct dpl_id * next; +-}dpl_id_t,*dpl_id_p; ++ dpl_index_t *first_index; /*fast access :rules with specific length*/ ++ struct dpl_id *next; ++} dpl_id_t, *dpl_id_p; + + +-#define DP_VAL_INT 0 +-#define DP_VAL_SPEC 1 ++#define DP_VAL_INT 0 ++#define DP_VAL_SPEC 1 + +-typedef struct dp_param{ ++typedef struct dp_param ++{ + int type; +- union { ++ union ++ { + int id; +- pv_spec_t* sp[2]; ++ pv_spec_t *sp[2]; + } v; +-}dp_param_t, *dp_param_p; ++} dp_param_t, *dp_param_p; + + int init_data(); + void destroy_data(); +@@ -94,12 +99,12 @@ int dp_load_db(); + + dpl_id_p select_dpid(int id); + +-struct subst_expr* repl_exp_parse(str subst); ++struct subst_expr *repl_exp_parse(str subst); + void repl_expr_free(struct subst_expr *se); +-int dp_translate_helper(sip_msg_t *msg, str *user_name, str *repl_user, +- dpl_id_p idp, str *); +-int rule_translate(sip_msg_t *msg, str *instr, dpl_node_t *rule, +- pcre *subst_comp, str *); ++int dp_translate_helper( ++ sip_msg_t *msg, str *user_name, str *repl_user, dpl_id_p idp, str *); ++int rule_translate( ++ sip_msg_t *msg, str *instr, dpl_node_t *rule, pcre *subst_comp, str *); + + pcre *reg_ex_comp(const char *pattern, int *cap_cnt, int mtype); + #endif +--- a/src/modules/dialplan/dp_db.c ++++ b/src/modules/dialplan/dp_db.c +@@ -37,45 +37,46 @@ + #include "dp_db.h" + #include "dialplan.h" + +-str dp_db_url = str_init(DEFAULT_RODB_URL); +-str dp_table_name = str_init(DP_TABLE_NAME); +-str dpid_column = str_init(DPID_COL); +-str pr_column = str_init(PR_COL); +-str match_op_column = str_init(MATCH_OP_COL); +-str match_exp_column= str_init(MATCH_EXP_COL); +-str match_len_column= str_init(MATCH_LEN_COL); +-str subst_exp_column= str_init(SUBST_EXP_COL); +-str repl_exp_column = str_init(REPL_EXP_COL); +-str attrs_column = str_init(ATTRS_COL); ++str dp_db_url = str_init(DEFAULT_RODB_URL); ++str dp_table_name = str_init(DP_TABLE_NAME); ++str dpid_column = str_init(DPID_COL); ++str pr_column = str_init(PR_COL); ++str match_op_column = str_init(MATCH_OP_COL); ++str match_exp_column = str_init(MATCH_EXP_COL); ++str match_len_column = str_init(MATCH_LEN_COL); ++str subst_exp_column = str_init(SUBST_EXP_COL); ++str repl_exp_column = str_init(REPL_EXP_COL); ++str attrs_column = str_init(ATTRS_COL); + + extern int dp_fetch_rows; + extern int dp_match_dynamic; + +-static db1_con_t* dp_db_handle = 0; /* database connection handle */ ++static db1_con_t *dp_db_handle = 0; /* database connection handle */ + static db_func_t dp_dbf; + +-#define GET_STR_VALUE(_res, _values, _index)\ +- do{\ +- if ( VAL_NULL((_values)+ (_index)) ) { \ +- LM_ERR(" values %d is NULL - not allowed\n",_index);\ +- (_res).s = 0; (_res).len = 0;\ +- goto err;\ +- } \ +- (_res).s = VAL_STR((_values)+ (_index)).s;\ +- (_res).len = strlen(VAL_STR((_values)+ (_index)).s);\ +- }while(0); ++#define GET_STR_VALUE(_res, _values, _index) \ ++ do { \ ++ if(VAL_NULL((_values) + (_index))) { \ ++ LM_ERR(" values %d is NULL - not allowed\n", _index); \ ++ (_res).s = 0; \ ++ (_res).len = 0; \ ++ goto err; \ ++ } \ ++ (_res).s = VAL_STR((_values) + (_index)).s; \ ++ (_res).len = strlen(VAL_STR((_values) + (_index)).s); \ ++ } while(0); + +-void destroy_rule(dpl_node_t * rule); ++void destroy_rule(dpl_node_t *rule); + void destroy_hash(int); + +-dpl_node_t * build_rule(db_val_t * values); ++dpl_node_t *build_rule(db_val_t *values); + int add_rule2hash(dpl_node_t *, int); + +-void list_rule(dpl_node_t * ); ++void list_rule(dpl_node_t *); + void list_hash(int h_index); + + +-static dpl_id_p* dp_rules_hash = NULL; ++static dpl_id_p *dp_rules_hash = NULL; + static int *dp_crt_idx = NULL; + static int *dp_next_idx = NULL; + +@@ -91,7 +92,7 @@ int dpl_check_pv(str *in) + str s; + int len; + +- if(in==NULL || in->s==NULL) ++ if(in == NULL || in->s == NULL) + return -1; + + LM_DBG("parsing [%.*s]\n", in->len, in->s); +@@ -101,26 +102,27 @@ int dpl_check_pv(str *in) + + p = in->s; + +- while(is_in_str(p,in)) +- { +- while(is_in_str(p,in) && *p!=PV_MARKER) ++ while(is_in_str(p, in)) { ++ while(is_in_str(p, in) && *p != PV_MARKER) + p++; +- if(*p == '\0' || !is_in_str(p,in)) ++ if(*p == '\0' || !is_in_str(p, in)) + break; + /* last char is $ ? */ +- if(!is_in_str(p+1, in)) ++ if(!is_in_str(p + 1, in)) + break; + s.s = p; +- s.len = in->s+in->len-p; ++ s.len = in->s + in->len - p; + len = 0; + spec = pv_spec_lookup(&s, &len); +- if(spec!=NULL) { ++ if(spec != NULL) { + /* found a variable */ + LM_DBG("string [%.*s] has variables\n", in->len, in->s); + return 0; + } +- if(len) p += len; +- else p++; ++ if(len) ++ p += len; ++ else ++ p++; + } + + /* not found */ +@@ -129,27 +131,28 @@ int dpl_check_pv(str *in) + + int init_db_data(void) + { +- if(!dp_table_name.s || dp_table_name.len<=0){ ++ if(!dp_table_name.s || dp_table_name.len <= 0) { + LM_ERR("invalid database table name\n"); + return -1; + } + + /* Find a database module */ +- if (db_bind_mod(&dp_db_url, &dp_dbf) < 0){ ++ if(db_bind_mod(&dp_db_url, &dp_dbf) < 0) { + LM_ERR("unable to bind to a database driver\n"); + return -1; + } + +- if(dp_connect_db() !=0) ++ if(dp_connect_db() != 0) + return -1; + +- if(db_check_table_version(&dp_dbf, dp_db_handle, &dp_table_name, +- DP_TABLE_VERSION) < 0) { ++ if(db_check_table_version( ++ &dp_dbf, dp_db_handle, &dp_table_name, DP_TABLE_VERSION) ++ < 0) { + DB_TABLE_VERSION_ERROR(dp_table_name); + goto error; + } + +- if(dp_load_db() != 0){ ++ if(dp_load_db() != 0) { + LM_ERR("failed to load database data\n"); + goto error; + } +@@ -166,17 +169,17 @@ error: + + int dp_connect_db(void) + { +- if (dp_dbf.init==0){ ++ if(dp_dbf.init == 0) { + LM_CRIT("null dp_dbf\n"); + return -1; + } + +- if(dp_db_handle){ ++ if(dp_db_handle) { + LM_CRIT("BUG: connection to database already open\n"); + return -1; + } + +- if ((dp_db_handle = dp_dbf.init(&dp_db_url)) == 0){ ++ if((dp_db_handle = dp_dbf.init(&dp_db_url)) == 0) { + LM_ERR("unable to connect to the database\n"); + return -1; + } +@@ -187,7 +190,7 @@ int dp_connect_db(void) + + void dp_disconnect_db(void) + { +- if(dp_db_handle){ ++ if(dp_db_handle) { + dp_dbf.close(dp_db_handle); + dp_db_handle = 0; + } +@@ -198,20 +201,20 @@ int init_data(void) + { + int *p; + +- dp_rules_hash = (dpl_id_p *)shm_malloc(2*sizeof(dpl_id_p)); ++ dp_rules_hash = (dpl_id_p *)shm_malloc(2 * sizeof(dpl_id_p)); + if(!dp_rules_hash) { + LM_ERR("out of shm memory\n"); + return -1; + } + dp_rules_hash[0] = dp_rules_hash[1] = 0; + +- p = (int *)shm_malloc(2*sizeof(int)); +- if(!p){ ++ p = (int *)shm_malloc(2 * sizeof(int)); ++ if(!p) { + LM_ERR("out of shm memory\n"); + return -1; + } + dp_crt_idx = p; +- dp_next_idx = p+1; ++ dp_next_idx = p + 1; + *dp_crt_idx = *dp_next_idx = 0; + + LM_DBG("trying to initialize data from db\n"); +@@ -224,7 +227,7 @@ int init_data(void) + + void destroy_data(void) + { +- if(dp_rules_hash){ ++ if(dp_rules_hash) { + destroy_hash(0); + destroy_hash(1); + shm_free(dp_rules_hash); +@@ -240,45 +243,46 @@ void destroy_data(void) + int dp_load_db(void) + { + int i, nr_rows; +- db1_res_t * res = 0; +- db_val_t * values; +- db_row_t * rows; +- db_key_t query_cols[DP_TABLE_COL_NO] = { +- &dpid_column, &pr_column, +- &match_op_column, &match_exp_column, &match_len_column, +- &subst_exp_column, &repl_exp_column, &attrs_column }; ++ db1_res_t *res = 0; ++ db_val_t *values; ++ db_row_t *rows; ++ db_key_t query_cols[DP_TABLE_COL_NO] = {&dpid_column, &pr_column, ++ &match_op_column, &match_exp_column, &match_len_column, ++ &subst_exp_column, &repl_exp_column, &attrs_column}; + + db_key_t order = &pr_column; + + dpl_node_t *rule; + + LM_DBG("init\n"); +- if( (*dp_crt_idx) != (*dp_next_idx)){ ++ if((*dp_crt_idx) != (*dp_next_idx)) { + LM_WARN("a load command already generated, aborting reload...\n"); + return 0; + } + +- if (dp_dbf.use_table(dp_db_handle, &dp_table_name) < 0){ ++ if(dp_dbf.use_table(dp_db_handle, &dp_table_name) < 0) { + LM_ERR("error in use_table %.*s\n", dp_table_name.len, dp_table_name.s); + return -1; + } + +- if (DB_CAPABILITY(dp_dbf, DB_CAP_FETCH)) { +- if(dp_dbf.query(dp_db_handle,0,0,0,query_cols, 0, +- DP_TABLE_COL_NO, order, 0) < 0){ ++ if(DB_CAPABILITY(dp_dbf, DB_CAP_FETCH)) { ++ if(dp_dbf.query(dp_db_handle, 0, 0, 0, query_cols, 0, DP_TABLE_COL_NO, ++ order, 0) ++ < 0) { + LM_ERR("failed to query database!\n"); + return -1; + } +- if(dp_dbf.fetch_result(dp_db_handle, &res, dp_fetch_rows)<0) { ++ if(dp_dbf.fetch_result(dp_db_handle, &res, dp_fetch_rows) < 0) { + LM_ERR("failed to fetch\n"); +- if (res) ++ if(res) + dp_dbf.free_result(dp_db_handle, res); + return -1; + } + } else { + /*select the whole table and all the columns*/ +- if(dp_dbf.query(dp_db_handle,0,0,0,query_cols, 0, +- DP_TABLE_COL_NO, order, &res) < 0){ ++ if(dp_dbf.query(dp_db_handle, 0, 0, 0, query_cols, 0, DP_TABLE_COL_NO, ++ order, &res) ++ < 0) { + LM_ERR("failed to query database\n"); + return -1; + } +@@ -286,38 +290,37 @@ int dp_load_db(void) + + nr_rows = RES_ROW_N(res); + +- *dp_next_idx = ((*dp_crt_idx) == 0)? 1:0; ++ *dp_next_idx = ((*dp_crt_idx) == 0) ? 1 : 0; + destroy_hash(*dp_next_idx); + +- if(nr_rows == 0){ ++ if(nr_rows == 0) { + LM_WARN("no data in the db\n"); + goto end; + } + + do { +- for(i=0; i0); ++ } while(RES_ROW_N(res) > 0); + + + end: +@@ -328,7 +331,8 @@ end: + return 0; + + err2: +- if(rule) destroy_rule(rule); ++ if(rule) ++ destroy_rule(rule); + destroy_hash(*dp_next_idx); + dp_dbf.free_result(dp_db_handle, res); + *dp_next_idx = *dp_crt_idx; +@@ -340,16 +344,17 @@ int dpl_str_to_shm(str src, str *dest, i + { + int mdup = 0; + +- if(src.len ==0 || src.s ==0) ++ if(src.len == 0 || src.s == 0) + return 0; + +- if(mterm!=0 && PV_MARKER=='$') { +- if(src.len>1 && src.s[src.len-1]=='$' && src.s[src.len-2]!='$') { ++ if(mterm != 0 && PV_MARKER == '$') { ++ if(src.len > 1 && src.s[src.len - 1] == '$' ++ && src.s[src.len - 2] != '$') { + mdup = 1; + } + } +- dest->s = (char*)shm_malloc((src.len+1+mdup) * sizeof(char)); +- if(!dest->s){ ++ dest->s = (char *)shm_malloc((src.len + 1 + mdup) * sizeof(char)); ++ if(!dest->s) { + LM_ERR("out of shm memory\n"); + return -1; + } +@@ -378,28 +383,28 @@ pcre *reg_ex_comp(const char *pattern, i + size_t size; + + re = pcre_compile(pattern, 0, &error, &err_offset, NULL); +- if (re == NULL) { +- LM_ERR("PCRE compilation of '%s' failed at offset %d: %s\n", +- pattern, err_offset, error); ++ if(re == NULL) { ++ LM_ERR("PCRE compilation of '%s' failed at offset %d: %s\n", pattern, ++ err_offset, error); + return (pcre *)0; + } + rc = pcre_fullinfo(re, NULL, PCRE_INFO_SIZE, &size); +- if (rc != 0) { ++ if(rc != 0) { + pcre_free(re); + LM_ERR("pcre_fullinfo on compiled pattern '%s' yielded error: %d\n", + pattern, rc); + return (pcre *)0; + } + rc = pcre_fullinfo(re, NULL, PCRE_INFO_CAPTURECOUNT, cap_cnt); +- if (rc != 0) { ++ if(rc != 0) { + pcre_free(re); + LM_ERR("pcre_fullinfo on compiled pattern '%s' yielded error: %d\n", + pattern, rc); + return (pcre *)0; + } +- if(mtype==0) { ++ if(mtype == 0) { + result = (pcre *)shm_malloc(size); +- if (result == NULL) { ++ if(result == NULL) { + pcre_free(re); + LM_ERR("not enough shared memory for compiled PCRE pattern\n"); + return (pcre *)0; +@@ -414,20 +419,20 @@ pcre *reg_ex_comp(const char *pattern, i + + + /*compile the expressions, and if ok, build the rule */ +-dpl_node_t * build_rule(db_val_t * values) ++dpl_node_t *build_rule(db_val_t *values) + { + pcre *match_comp, *subst_comp; + struct subst_expr *repl_comp; +- dpl_node_t * new_rule; ++ dpl_node_t *new_rule; + str match_exp, subst_exp, repl_exp, attrs; + int matchop; +- int cap_cnt=0; +- unsigned int tflags=0; ++ int cap_cnt = 0; ++ unsigned int tflags = 0; + +- matchop = VAL_INT(values+2); ++ matchop = VAL_INT(values + 2); + +- if((matchop != DP_REGEX_OP) && (matchop!=DP_EQUAL_OP) +- && (matchop!=DP_FNMATCH_OP)){ ++ if((matchop != DP_REGEX_OP) && (matchop != DP_EQUAL_OP) ++ && (matchop != DP_FNMATCH_OP)) { + LM_ERR("invalid value for match operator\n"); + return NULL; + } +@@ -437,15 +442,15 @@ dpl_node_t * build_rule(db_val_t * value + new_rule = 0; + + GET_STR_VALUE(match_exp, values, 3); +- if(matchop == DP_REGEX_OP){ +- if(unlikely(dp_match_dynamic==1)) { +- if(dpl_check_pv(&match_exp)==0) { ++ if(matchop == DP_REGEX_OP) { ++ if(unlikely(dp_match_dynamic == 1)) { ++ if(dpl_check_pv(&match_exp) == 0) { + tflags |= DP_TFLAGS_PV_MATCH; + } + } +- if(!(tflags&DP_TFLAGS_PV_MATCH)) { ++ if(!(tflags & DP_TFLAGS_PV_MATCH)) { + match_comp = reg_ex_comp(match_exp.s, &cap_cnt, 0); +- if(!match_comp){ ++ if(!match_comp) { + LM_ERR("failed to compile match expression %.*s\n", + match_exp.len, match_exp.s); + goto err; +@@ -454,9 +459,9 @@ dpl_node_t * build_rule(db_val_t * value + } + + GET_STR_VALUE(repl_exp, values, 6); +- if(repl_exp.len && repl_exp.s){ ++ if(repl_exp.len && repl_exp.s) { + repl_comp = repl_exp_parse(repl_exp); +- if(!repl_comp){ ++ if(!repl_comp) { + LM_ERR("failed to compile replacing expression %.*s\n", + repl_exp.len, repl_exp.s); + goto err; +@@ -465,20 +470,20 @@ dpl_node_t * build_rule(db_val_t * value + + cap_cnt = 0; + GET_STR_VALUE(subst_exp, values, 5); +- if(subst_exp.s && subst_exp.len){ +- if(unlikely(dp_match_dynamic==1)) { +- if(dpl_check_pv(&subst_exp)==0) { ++ if(subst_exp.s && subst_exp.len) { ++ if(unlikely(dp_match_dynamic == 1)) { ++ if(dpl_check_pv(&subst_exp) == 0) { + tflags |= DP_TFLAGS_PV_SUBST; + } + } +- if(!(tflags&DP_TFLAGS_PV_SUBST)) { ++ if(!(tflags & DP_TFLAGS_PV_SUBST)) { + subst_comp = reg_ex_comp(subst_exp.s, &cap_cnt, 0); +- if(!subst_comp){ ++ if(!subst_comp) { + LM_ERR("failed to compile subst expression %.*s\n", + subst_exp.len, subst_exp.s); + goto err; + } +- if (cap_cnt > MAX_REPLACE_WITH) { ++ if(cap_cnt > MAX_REPLACE_WITH) { + LM_ERR("subst expression %.*s has too many sub-expressions\n", + subst_exp.len, subst_exp.s); + goto err; +@@ -486,72 +491,77 @@ dpl_node_t * build_rule(db_val_t * value + } + } + +- LM_DBG("building rule for [%d:%.*s/%.*s/%.*s]\n", matchop, +- match_exp.len, ZSW(match_exp.s), subst_exp.len, ZSW(subst_exp.s), +- repl_exp.len, ZSW(repl_exp.s)); +- if (!(tflags&(DP_TFLAGS_PV_SUBST|DP_TFLAGS_PV_MATCH)) && +- repl_comp && (cap_cnt < repl_comp->max_pmatch) && +- (repl_comp->max_pmatch != 0)) +- { ++ LM_DBG("building rule for [%d:%.*s/%.*s/%.*s]\n", matchop, match_exp.len, ++ ZSW(match_exp.s), subst_exp.len, ZSW(subst_exp.s), repl_exp.len, ++ ZSW(repl_exp.s)); ++ if(!(tflags & (DP_TFLAGS_PV_SUBST | DP_TFLAGS_PV_MATCH)) && repl_comp ++ && (cap_cnt < repl_comp->max_pmatch) ++ && (repl_comp->max_pmatch != 0)) { + LM_ERR("repl_exp %.*s refers to %d sub-expressions, but " +- "subst_exp %.*s has only %d\n", +- repl_exp.len, repl_exp.s, repl_comp->max_pmatch, +- subst_exp.len, subst_exp.s, cap_cnt); ++ "subst_exp %.*s has only %d\n", ++ repl_exp.len, repl_exp.s, repl_comp->max_pmatch, subst_exp.len, ++ subst_exp.s, cap_cnt); + goto err; + } + + new_rule = (dpl_node_t *)shm_malloc(sizeof(dpl_node_t)); +- if(!new_rule){ ++ if(!new_rule) { + LM_ERR("out of shm memory(new_rule)\n"); + goto err; + } + memset(new_rule, 0, sizeof(dpl_node_t)); + +- if(dpl_str_to_shm(match_exp, &new_rule->match_exp, +- tflags&DP_TFLAGS_PV_MATCH)!=0) ++ if(dpl_str_to_shm( ++ match_exp, &new_rule->match_exp, tflags & DP_TFLAGS_PV_MATCH) ++ != 0) + goto err; + +- if(dpl_str_to_shm(subst_exp, &new_rule->subst_exp, +- tflags&DP_TFLAGS_PV_SUBST)!=0) ++ if(dpl_str_to_shm( ++ subst_exp, &new_rule->subst_exp, tflags & DP_TFLAGS_PV_SUBST) ++ != 0) + goto err; + +- if(dpl_str_to_shm(repl_exp, &new_rule->repl_exp, 0)!=0) ++ if(dpl_str_to_shm(repl_exp, &new_rule->repl_exp, 0) != 0) + goto err; + + /*set the rest of the rule fields*/ +- new_rule->dpid = VAL_INT(values); +- new_rule->pr = VAL_INT(values+1); +- new_rule->matchlen = VAL_INT(values+4); +- new_rule->matchop = matchop; ++ new_rule->dpid = VAL_INT(values); ++ new_rule->pr = VAL_INT(values + 1); ++ new_rule->matchlen = VAL_INT(values + 4); ++ new_rule->matchop = matchop; + GET_STR_VALUE(attrs, values, 7); +- if(dpl_str_to_shm(attrs, &new_rule->attrs, 0)!=0) ++ if(dpl_str_to_shm(attrs, &new_rule->attrs, 0) != 0) + goto err; + + LM_DBG("attrs are: '%.*s'\n", new_rule->attrs.len, new_rule->attrs.s); + + new_rule->match_comp = match_comp; + new_rule->subst_comp = subst_comp; +- new_rule->repl_comp = repl_comp; +- new_rule->tflags = tflags; ++ new_rule->repl_comp = repl_comp; ++ new_rule->tflags = tflags; + + return new_rule; + + err: +- if(match_comp) shm_free(match_comp); +- if(subst_comp) shm_free(subst_comp); +- if(repl_comp) repl_expr_free(repl_comp); +- if(new_rule) destroy_rule(new_rule); ++ if(match_comp) ++ shm_free(match_comp); ++ if(subst_comp) ++ shm_free(subst_comp); ++ if(repl_comp) ++ repl_expr_free(repl_comp); ++ if(new_rule) ++ destroy_rule(new_rule); + return NULL; + } + + +-int add_rule2hash(dpl_node_t * rule, int h_index) ++int add_rule2hash(dpl_node_t *rule, int h_index) + { + dpl_id_p crt_idp, last_idp; + dpl_index_p indexp, last_indexp, new_indexp; + int new_id; + +- if(!dp_rules_hash){ ++ if(!dp_rules_hash) { + LM_ERR("data not allocated\n"); + return -1; + } +@@ -559,15 +569,15 @@ int add_rule2hash(dpl_node_t * rule, int + new_id = 0; + + /*search for the corresponding dpl_id*/ +- for(crt_idp = last_idp =dp_rules_hash[h_index]; crt_idp!= NULL; ++ for(crt_idp = last_idp = dp_rules_hash[h_index]; crt_idp != NULL; + last_idp = crt_idp, crt_idp = crt_idp->next) + if(crt_idp->dp_id == rule->dpid) + break; + + /*didn't find a dpl_id*/ +- if(!crt_idp){ +- crt_idp = (dpl_id_t*)shm_malloc(sizeof(dpl_id_t)); +- if(!crt_idp){ ++ if(!crt_idp) { ++ crt_idp = (dpl_id_t *)shm_malloc(sizeof(dpl_id_t)); ++ if(!crt_idp) { + LM_ERR("out of shm memory (crt_idp)\n"); + return -1; + } +@@ -578,11 +588,12 @@ int add_rule2hash(dpl_node_t * rule, int + } + + /*search for the corresponding dpl_index*/ +- for(indexp = last_indexp =crt_idp->first_index; indexp!=NULL; +- last_indexp = indexp, indexp = indexp->next){ ++ for(indexp = last_indexp = crt_idp->first_index; indexp != NULL; ++ last_indexp = indexp, indexp = indexp->next) { + if(indexp->len == rule->matchlen) + goto add_rule; +- if((rule->matchlen!=0)&&((indexp->len)?(indexp->len>rule->matchlen):1)) ++ if((rule->matchlen != 0) ++ && ((indexp->len) ? (indexp->len > rule->matchlen) : 1)) + goto add_index; + } + +@@ -590,18 +601,18 @@ add_index: + LM_DBG("new index , len %i\n", rule->matchlen); + + new_indexp = (dpl_index_t *)shm_malloc(sizeof(dpl_index_t)); +- if(!new_indexp){ ++ if(!new_indexp) { + LM_ERR("out of shm memory\n"); + goto err; + } +- memset(new_indexp , 0, sizeof(dpl_index_t)); ++ memset(new_indexp, 0, sizeof(dpl_index_t)); + new_indexp->next = indexp; + new_indexp->len = rule->matchlen; + + /*add as first index*/ +- if(last_indexp == indexp){ ++ if(last_indexp == indexp) { + crt_idp->first_index = new_indexp; +- }else{ ++ } else { + last_indexp->next = new_indexp; + } + +@@ -617,13 +628,13 @@ add_rule: + + indexp->last_rule = rule; + +- if(new_id){ ++ if(new_id) { + crt_idp->next = dp_rules_hash[h_index]; + dp_rules_hash[h_index] = crt_idp; + } + LM_DBG("added the rule id %i index %i pr %i next %p to the " +- "index with %i len\n", rule->dpid, rule->matchlen, +- rule->pr, rule->next, indexp->len); ++ "index with %i len\n", ++ rule->dpid, rule->matchlen, rule->pr, rule->next, indexp->len); + + return 0; + +@@ -643,24 +654,23 @@ void destroy_hash(int index) + if(!dp_rules_hash[index]) + return; + +- for(crt_idp = dp_rules_hash[index]; crt_idp != NULL;){ ++ for(crt_idp = dp_rules_hash[index]; crt_idp != NULL;) { + +- for(indexp = crt_idp->first_index; indexp != NULL;){ ++ for(indexp = crt_idp->first_index; indexp != NULL;) { + +- for(rulep = indexp->first_rule; rulep!= NULL;){ ++ for(rulep = indexp->first_rule; rulep != NULL;) { + + destroy_rule(rulep); + + indexp->first_rule = rulep->next; + shm_free(rulep); +- rulep=0; +- rulep= indexp->first_rule; ++ rulep = 0; ++ rulep = indexp->first_rule; + } +- crt_idp->first_index= indexp->next; ++ crt_idp->first_index = indexp->next; + shm_free(indexp); +- indexp=0; ++ indexp = 0; + indexp = crt_idp->first_index; +- + } + + dp_rules_hash[index] = crt_idp->next; +@@ -673,13 +683,13 @@ void destroy_hash(int index) + } + + +-void destroy_rule(dpl_node_t * rule){ ++void destroy_rule(dpl_node_t *rule) ++{ + + if(!rule) + return; + +- LM_DBG("destroying rule with priority %i\n", +- rule->pr); ++ LM_DBG("destroying rule with priority %i\n", rule->pr); + + if(rule->match_comp) + shm_free(rule->match_comp); +@@ -712,7 +722,7 @@ dpl_id_p select_dpid(int id) + if(!dp_rules_hash || !dp_crt_idx) + return NULL; + +- for(idp = dp_rules_hash[*dp_crt_idx]; idp!=NULL; idp = idp->next) ++ for(idp = dp_rules_hash[*dp_crt_idx]; idp != NULL; idp = idp->next) + if(idp->dp_id == id) + return idp; + +@@ -731,11 +741,14 @@ void list_hash(int h_index) + if(!dp_rules_hash[h_index]) + return; + +- for(crt_idp=dp_rules_hash[h_index]; crt_idp!=NULL; crt_idp = crt_idp->next){ ++ for(crt_idp = dp_rules_hash[h_index]; crt_idp != NULL; ++ crt_idp = crt_idp->next) { + LM_DBG("DPID: %i, pointer %p\n", crt_idp->dp_id, crt_idp); +- for(indexp=crt_idp->first_index; indexp!=NULL;indexp= indexp->next){ ++ for(indexp = crt_idp->first_index; indexp != NULL; ++ indexp = indexp->next) { + LM_DBG("INDEX LEN: %i\n", indexp->len); +- for(rulep = indexp->first_rule; rulep!= NULL;rulep = rulep->next){ ++ for(rulep = indexp->first_rule; rulep != NULL; ++ rulep = rulep->next) { + list_rule(rulep); + } + } +@@ -746,12 +759,9 @@ void list_hash(int h_index) + void list_rule(dpl_node_t *rule) + { + LM_DBG("RULE %p: pr %i next %p op %d tflags %u match_exp %.*s, " +- "subst_exp %.*s, repl_exp %.*s and attrs %.*s\n", rule, +- rule->pr, rule->next, +- rule->matchop, rule->tflags, +- rule->match_exp.len, ZSW(rule->match_exp.s), +- rule->subst_exp.len, ZSW(rule->subst_exp.s), +- rule->repl_exp.len, ZSW(rule->repl_exp.s), +- rule->attrs.len, ZSW(rule->attrs.s)); +- ++ "subst_exp %.*s, repl_exp %.*s and attrs %.*s\n", ++ rule, rule->pr, rule->next, rule->matchop, rule->tflags, ++ rule->match_exp.len, ZSW(rule->match_exp.s), rule->subst_exp.len, ++ ZSW(rule->subst_exp.s), rule->repl_exp.len, ZSW(rule->repl_exp.s), ++ rule->attrs.len, ZSW(rule->attrs.s)); + } +--- a/src/modules/dialplan/dp_db.h ++++ b/src/modules/dialplan/dp_db.h +@@ -32,30 +32,30 @@ + #include "../../core/str.h" + #include "../../lib/srdb1/db.h" + +-#define DP_TABLE_NAME "dialplan" +-#define DPID_COL "dpid" +-#define PR_COL "pr" +-#define MATCH_OP_COL "match_op" +-#define MATCH_EXP_COL "match_exp" +-#define MATCH_LEN_COL "match_len" +-#define SUBST_EXP_COL "subst_exp" +-#define REPL_EXP_COL "repl_exp" +-#define ATTRS_COL "attrs" ++#define DP_TABLE_NAME "dialplan" ++#define DPID_COL "dpid" ++#define PR_COL "pr" ++#define MATCH_OP_COL "match_op" ++#define MATCH_EXP_COL "match_exp" ++#define MATCH_LEN_COL "match_len" ++#define SUBST_EXP_COL "subst_exp" ++#define REPL_EXP_COL "repl_exp" ++#define ATTRS_COL "attrs" + + +-#define DP_TABLE_VERSION 2 +-#define DP_TABLE_COL_NO 8 ++#define DP_TABLE_VERSION 2 ++#define DP_TABLE_COL_NO 8 + + extern str dp_db_url; + extern str dp_table_name; +-extern str dpid_column; +-extern str pr_column; +-extern str match_op_column; +-extern str match_exp_column; +-extern str match_len_column; +-extern str subst_exp_column; +-extern str repl_exp_column; +-extern str attrs_column; ++extern str dpid_column; ++extern str pr_column; ++extern str match_op_column; ++extern str match_exp_column; ++extern str match_len_column; ++extern str subst_exp_column; ++extern str repl_exp_column; ++extern str attrs_column; + + int init_db_data(); + int dp_connect_db(); +--- a/src/modules/dialplan/dp_repl.c ++++ b/src/modules/dialplan/dp_repl.c +@@ -42,27 +42,28 @@ typedef struct dpl_dyn_pcre + int cnt; + str expr; + +- struct dpl_dyn_pcre * next; /* next rule */ ++ struct dpl_dyn_pcre *next; /* next rule */ + } dpl_dyn_pcre_t, *dpl_dyn_pcre_p; + +-static void dpl_get_avp_val(avp_t *avp, str *dst) { ++static void dpl_get_avp_val(avp_t *avp, str *dst) ++{ + avp_value_t val; + +- if (avp==0 || dst==0) return; ++ if(avp == 0 || dst == 0) ++ return; + + /* Warning! it uses static buffer from int2str !!! */ + + get_avp_val(avp, &val); +- if (avp->flags & AVP_VAL_STR) { ++ if(avp->flags & AVP_VAL_STR) { + *dst = val.s; +- } +- else { /* probably (!) number */ ++ } else { /* probably (!) number */ + dst->s = int2str(val.n, &dst->len); + } + } + + int dpl_dyn_printf_s(sip_msg_t *msg, const pv_elem_p elem, +- const pv_elem_p avp_elem, str *val, pv_elem_p *elem_prev, str *vexpr) ++ const pv_elem_p avp_elem, str *val, pv_elem_p *elem_prev, str *vexpr) + { + pv_elem_p e = NULL; + pv_elem_p t = NULL; +@@ -70,45 +71,52 @@ int dpl_dyn_printf_s(sip_msg_t *msg, con + str v = STR_NULL; + int ret = -1; + +- if(elem==NULL||avp_elem==NULL||elem_prev==NULL||vexpr==NULL) return -1; +- if(str_append(&(avp_elem->text), val, &s)<0) return -1; ++ if(elem == NULL || avp_elem == NULL || elem_prev == NULL || vexpr == NULL) ++ return -1; ++ if(str_append(&(avp_elem->text), val, &s) < 0) ++ return -1; + +- if(pv_parse_format(&s, &e)<0) { ++ if(pv_parse_format(&s, &e) < 0) { + LM_ERR("parsing expression: %.*s\n", s.len, s.s); + goto clean; + } +- if(*elem_prev==NULL && elem!=avp_elem) { ++ if(*elem_prev == NULL && elem != avp_elem) { + LM_DBG("search for elem_prev\n"); +- for(t=elem; t!=NULL; t=t->next) { +- if(t->next==avp_elem) { *elem_prev = t; ++ for(t = elem; t != NULL; t = t->next) { ++ if(t->next == avp_elem) { ++ *elem_prev = t; + LM_DBG("found!\n"); + } + } + } +- if(*elem_prev) (*elem_prev)->next = e; ++ if(*elem_prev) ++ (*elem_prev)->next = e; + e->next = avp_elem->next; +- if(pv_printf_s(msg, e, &v)<0){ ++ if(pv_printf_s(msg, e, &v) < 0) { + LM_ERR("cannot get avp pcre dynamic expression value\n"); + goto clean; + } + /* pv_printf_s uses pv_get_buffer() we do need to copy */ + vexpr->len = v.len; +- vexpr->s = pkg_malloc(sizeof(char)*(v.len+1)); +- if(vexpr->s==NULL) { ++ vexpr->s = pkg_malloc(sizeof(char) * (v.len + 1)); ++ if(vexpr->s == NULL) { + PKG_MEM_ERROR; + goto clean; + } + strcpy(vexpr->s, v.s); + ret = 0; + clean: +- if(s.s) pkg_free(s.s); +- if(e) pkg_free(e); +- if(*elem_prev) (*elem_prev)->next = avp_elem; ++ if(s.s) ++ pkg_free(s.s); ++ if(e) ++ pkg_free(e); ++ if(*elem_prev) ++ (*elem_prev)->next = avp_elem; + return ret; + } + + int dpl_get_avp_values(sip_msg_t *msg, const pv_elem_p elem, +- const pv_elem_p avp_elem, struct str_list **out) ++ const pv_elem_p avp_elem, struct str_list **out) + { + struct usr_avp *avp = NULL; + unsigned short name_type; +@@ -120,16 +128,17 @@ int dpl_get_avp_values(sip_msg_t *msg, c + pv_elem_p elem_prev = NULL; + struct str_list *tl = NULL; + +- if(elem==NULL||avp_elem==NULL||out==NULL||*out==NULL) { ++ if(elem == NULL || avp_elem == NULL || out == NULL || *out == NULL) { + LM_ERR("wrong parameters\n"); + return -1; + } +- if(pv_get_avp_name(msg, &(avp_elem->spec->pvp), &avp_name, &name_type)!=0) { ++ if(pv_get_avp_name(msg, &(avp_elem->spec->pvp), &avp_name, &name_type) ++ != 0) { + LM_ERR("invalid avp name\n"); + return -1; + } + avp = search_first_avp(name_type, avp_name, &avp_value, &state); +- if(avp==NULL) { ++ if(avp == NULL) { + LM_ERR("can't find first avp\n"); + return -1; + } +@@ -139,10 +148,10 @@ int dpl_get_avp_values(sip_msg_t *msg, c + /*LM_DBG("elem[%p] avp_elem[%p], elem_prev[%p] [%.*s]\n", + elem, avp_elem, elem_prev, tl->s.len, tl->s.s);*/ + sum = tl->s.len; +- while ((avp=search_next_avp(&state, &avp_value))!=0) { ++ while((avp = search_next_avp(&state, &avp_value)) != 0) { + dpl_get_avp_val(avp, &s); + dpl_dyn_printf_s(msg, elem, avp_elem, &s, &elem_prev, &ts); +- if(append_str_list(ts.s, ts.len, &tl, &sum)==NULL) { ++ if(append_str_list(ts.s, ts.len, &tl, &sum) == NULL) { + while(*out) { + tl = (*out)->next; + pkg_free(*out); +@@ -160,18 +169,20 @@ int dpl_get_avp_values(sip_msg_t *msg, c + int dpl_detect_avp_indx(const pv_elem_p elem, pv_elem_p *avp) + { + int num, num_avp_all; +- pv_elem_p e = elem;; +- if(elem==NULL||avp==NULL) return -1; ++ pv_elem_p e = elem; ++ ; ++ if(elem == NULL || avp == NULL) ++ return -1; + +- for(e=elem, num=num_avp_all=0; e!=NULL; e=e->next, num++) { +- if(e->spec!=NULL && e->spec->type==PVT_AVP && +- e->spec->pvp.pvi.type==PV_IDX_ITR) +- { ++ for(e = elem, num = num_avp_all = 0; e != NULL; e = e->next, num++) { ++ if(e->spec != NULL && e->spec->type == PVT_AVP ++ && e->spec->pvp.pvi.type == PV_IDX_ITR) { + *avp = e; + num_avp_all++; + } + } +- if(num_avp_all==1) return 1; /* just one avp_indx supported */ ++ if(num_avp_all == 1) ++ return 1; /* just one avp_indx supported */ + return 0; + } + +@@ -180,29 +191,29 @@ pcre *dpl_dyn_pcre_comp(sip_msg_t *msg, + pcre *re = NULL; + int ccnt = 0; + +- if(expr==NULL || expr->s==NULL || expr->len<=0 || +- vexpr==NULL || vexpr->s==NULL || vexpr->len<=0) ++ if(expr == NULL || expr->s == NULL || expr->len <= 0 || vexpr == NULL ++ || vexpr->s == NULL || vexpr->len <= 0) + return NULL; + + re = reg_ex_comp(vexpr->s, &ccnt, 1); + if(!re) { +- if(expr!=vexpr) ++ if(expr != vexpr) + LM_ERR("failed to compile pcre expression: %.*s (%.*s)\n", +- expr->len, expr->s, vexpr->len, vexpr->s); ++ expr->len, expr->s, vexpr->len, vexpr->s); + else +- LM_ERR("failed to compile pcre expression: %.*s\n", +- vexpr->len, vexpr->s); ++ LM_ERR("failed to compile pcre expression: %.*s\n", vexpr->len, ++ vexpr->s); + return NULL; + } + if(cap_cnt) { + *cap_cnt = ccnt; + } +- if(expr!=vexpr) +- LM_DBG("compiled dynamic pcre expression: %.*s (%.*s) %d\n", +- expr->len, expr->s, vexpr->len, vexpr->s, ccnt); ++ if(expr != vexpr) ++ LM_DBG("compiled dynamic pcre expression: %.*s (%.*s) %d\n", expr->len, ++ expr->s, vexpr->len, vexpr->s, ccnt); + else +- LM_DBG("compiled dynamic pcre expression: %.*s %d\n", +- vexpr->len, vexpr->s, ccnt); ++ LM_DBG("compiled dynamic pcre expression: %.*s %d\n", vexpr->len, ++ vexpr->s, ccnt); + return re; + } + +@@ -218,35 +229,33 @@ dpl_dyn_pcre_p dpl_dynamic_pcre_list(sip + int cnt = 0; + str vexpr = STR_NULL; + +- if(expr==NULL || expr->s==NULL || expr->len<=0) +- { ++ if(expr == NULL || expr->s == NULL || expr->len <= 0) { + LM_ERR("wrong parameters\n"); + return NULL; + } + +- if(pv_parse_format(expr, &elem)<0) { +- LM_ERR("parsing pcre expression: %.*s\n", +- expr->len, expr->s); ++ if(pv_parse_format(expr, &elem) < 0) { ++ LM_ERR("parsing pcre expression: %.*s\n", expr->len, expr->s); + return NULL; + } + LM_DBG("parsed pcre expression: %.*s\n", expr->len, expr->s); + if(dpl_detect_avp_indx(elem, &avp_elem)) { + l = pkg_malloc(sizeof(struct str_list)); +- if(l==NULL) { ++ if(l == NULL) { + PKG_MEM_ERROR; + goto error; + } + memset(l, 0, sizeof(struct str_list)); +- if(dpl_get_avp_values(msg, elem, avp_elem, &l)<0) { ++ if(dpl_get_avp_values(msg, elem, avp_elem, &l) < 0) { + LM_ERR("can't get list of avp values\n"); + goto error; + } + t = l; + while(t) { + re = dpl_dyn_pcre_comp(msg, &(t->s), &(t->s), &cnt); +- if(re!=NULL) { ++ if(re != NULL) { + rt = pkg_malloc(sizeof(dpl_dyn_pcre_t)); +- if(rt==NULL) { ++ if(rt == NULL) { + PKG_MEM_ERROR; + goto error; + } +@@ -259,17 +268,16 @@ dpl_dyn_pcre_p dpl_dynamic_pcre_list(sip + } + t = t->next; + } +- } +- else { +- if(pv_printf_s(msg, elem, &vexpr)<0){ ++ } else { ++ if(pv_printf_s(msg, elem, &vexpr) < 0) { + LM_ERR("cannot get pcre dynamic expression value: %.*s\n", + expr->len, expr->s); + goto error; + } + re = dpl_dyn_pcre_comp(msg, expr, &vexpr, &cnt); +- if(re!=NULL) { ++ if(re != NULL) { + rt = pkg_malloc(sizeof(dpl_dyn_pcre_t)); +- if(rt==NULL) { ++ if(rt == NULL) { + PKG_MEM_ERROR; + goto error; + } +@@ -285,15 +293,18 @@ dpl_dyn_pcre_p dpl_dynamic_pcre_list(sip + error: + while(re_list) { + rt = re_list->next; +- if(re_list->re) pcre_free(re_list->re); ++ if(re_list->re) ++ pcre_free(re_list->re); + pkg_free(re_list); + re_list = rt; + } + clean: +- if(elem) pv_elem_free_all(elem); ++ if(elem) ++ pv_elem_free_all(elem); + while(l) { + t = l->next; +- if(l->s.s) pkg_free(l->s.s); ++ if(l->s.s) ++ pkg_free(l->s.s); + pkg_free(l); + l = t; + } +@@ -305,7 +316,7 @@ void repl_expr_free(struct subst_expr *s + if(!se) + return; + +- if(se->replacement.s){ ++ if(se->replacement.s) { + shm_free(se->replacement.s); + se->replacement.s = 0; + } +@@ -315,13 +326,13 @@ void repl_expr_free(struct subst_expr *s + } + + +-struct subst_expr* repl_exp_parse(str subst) ++struct subst_expr *repl_exp_parse(str subst) + { + struct replace_with rw[MAX_REPLACE_WITH]; + int rw_no; +- struct subst_expr * se; ++ struct subst_expr *se; + int replace_all; +- char * p, *end, *repl, *repl_end; ++ char *p, *end, *repl, *repl_end; + int max_pmatch, r; + str shms; + +@@ -329,7 +340,7 @@ struct subst_expr* repl_exp_parse(str su + replace_all = 0; + shms.s = NULL; + +- if (!(shms.s=shm_malloc((subst.len+1) * sizeof(char))) ){ ++ if(!(shms.s = shm_malloc((subst.len + 1) * sizeof(char)))) { + LM_ERR("out of shm memory\n"); + goto error; + } +@@ -342,39 +353,41 @@ struct subst_expr* repl_exp_parse(str su + rw_no = 0; + + repl = p; +- if((rw_no = parse_repl(rw, &p, end, &max_pmatch, WITHOUT_SEP))< 0) { ++ if((rw_no = parse_repl(rw, &p, end, &max_pmatch, WITHOUT_SEP)) < 0) { + LM_ERR("parse repl failed\n"); + goto error; + } + +- repl_end=p; ++ repl_end = p; + + /* construct the subst_expr structure */ +- se = shm_malloc(sizeof(struct subst_expr)+ +- ((rw_no)?(rw_no-1)*sizeof(struct replace_with):0)); ++ se = shm_malloc( ++ sizeof(struct subst_expr) ++ + ((rw_no) ? (rw_no - 1) * sizeof(struct replace_with) : 0)); + /* 1 replace_with structure is already included in subst_expr */ +- if (se==0){ ++ if(se == 0) { + LM_ERR("out of shm memory (subst_expr)\n"); + goto error; + } +- memset((void*)se, 0, sizeof(struct subst_expr)); ++ memset((void *)se, 0, sizeof(struct subst_expr)); + + se->replacement.s = shms.s; + shms.s = NULL; +- se->replacement.len=repl_end-repl; +- if(!rw_no){ ++ se->replacement.len = repl_end - repl; ++ if(!rw_no) { + replace_all = 1; + } + /* start copying */ + LM_DBG("replacement expression is [%.*s]\n", se->replacement.len, + se->replacement.s); +- se->re=0; +- se->replace_all=replace_all; +- se->n_escapes=rw_no; +- se->max_pmatch=max_pmatch; ++ se->re = 0; ++ se->replace_all = replace_all; ++ se->n_escapes = rw_no; ++ se->max_pmatch = max_pmatch; + + /*replace_with is a simple structure, no shm alloc needed*/ +- for (r=0; rreplace[r]=rw[r]; ++ for(r = 0; r < rw_no; r++) ++ se->replace[r] = rw[r]; + return se; + + error: +@@ -384,17 +397,17 @@ error: + } + + +-#define MAX_PHONE_NB_DIGITS 127 +-static char dp_output_buf[MAX_PHONE_NB_DIGITS+1]; ++#define MAX_PHONE_NB_DIGITS 127 ++static char dp_output_buf[MAX_PHONE_NB_DIGITS + 1]; + int rule_translate(sip_msg_t *msg, str *instr, dpl_node_t *rule, + pcre *subst_comp, str *result) + { + int repl_nb, offset, match_nb, rc, cap_cnt; + struct replace_with token; +- struct subst_expr * repl_comp; ++ struct subst_expr *repl_comp; + str match; + pv_value_t sv; +- str* uri; ++ str *uri; + int ovector[3 * (MAX_REPLACE_WITH + 1)]; + char *p; + int size; +@@ -404,53 +417,50 @@ int rule_translate(sip_msg_t *msg, str * + result->len = 0; + + repl_comp = rule->repl_comp; +- if(!repl_comp){ ++ if(!repl_comp) { + LM_DBG("null replacement\n"); + return 0; + } + +- if(subst_comp){ ++ if(subst_comp) { + /*just in case something went wrong at load time*/ +- rc = pcre_fullinfo(subst_comp, NULL, PCRE_INFO_CAPTURECOUNT, +- &cap_cnt); +- if (rc != 0) { +- LM_ERR("pcre_fullinfo on compiled pattern yielded error: %d\n", +- rc); ++ rc = pcre_fullinfo(subst_comp, NULL, PCRE_INFO_CAPTURECOUNT, &cap_cnt); ++ if(rc != 0) { ++ LM_ERR("pcre_fullinfo on compiled pattern yielded error: %d\n", rc); + return -1; + } +- if(repl_comp->max_pmatch > cap_cnt){ ++ if(repl_comp->max_pmatch > cap_cnt) { + LM_ERR("illegal access to %i-th subexpr of subst expr (max %d)\n", + repl_comp->max_pmatch, cap_cnt); + return -1; + } +- if (rule->tflags&DP_TFLAGS_PV_SUBST && (cap_cnt > MAX_REPLACE_WITH)) { ++ if(rule->tflags & DP_TFLAGS_PV_SUBST && (cap_cnt > MAX_REPLACE_WITH)) { + LM_ERR("subst expression %.*s has too many sub-expressions\n", +- rule->subst_exp.len, rule->subst_exp.s); ++ rule->subst_exp.len, rule->subst_exp.s); + return -1; + } + + /*search for the pattern from the compiled subst_exp*/ +- if (pcre_exec(subst_comp, NULL, instr->s, instr->len, +- 0, 0, ovector, 3 * (MAX_REPLACE_WITH + 1)) <= 0) { ++ if(pcre_exec(subst_comp, NULL, instr->s, instr->len, 0, 0, ovector, ++ 3 * (MAX_REPLACE_WITH + 1)) ++ <= 0) { + LM_DBG("the string %.*s matched " +- "the match_exp %.*s but not the subst_exp %.*s!\n", +- instr->len, instr->s, +- rule->match_exp.len, rule->match_exp.s, +- rule->subst_exp.len, rule->subst_exp.s); ++ "the match_exp %.*s but not the subst_exp %.*s!\n", ++ instr->len, instr->s, rule->match_exp.len, ++ rule->match_exp.s, rule->subst_exp.len, rule->subst_exp.s); + return -1; + } + } + + /*simply copy from the replacing string*/ +- if(!subst_comp || (repl_comp->n_escapes <=0)){ +- if(!repl_comp->replacement.s || repl_comp->replacement.len == 0){ ++ if(!subst_comp || (repl_comp->n_escapes <= 0)) { ++ if(!repl_comp->replacement.s || repl_comp->replacement.len == 0) { + LM_ERR("invalid replacing string\n"); + goto error; + } + LM_DBG("simply replace the string, subst_comp %p, n_escapes %i\n", + subst_comp, repl_comp->n_escapes); +- memcpy(result->s, repl_comp->replacement.s, +- repl_comp->replacement.len); ++ memcpy(result->s, repl_comp->replacement.s, repl_comp->replacement.len); + result->len = repl_comp->replacement.len; + result->s[result->len] = '\0'; + return 0; +@@ -458,91 +468,90 @@ int rule_translate(sip_msg_t *msg, str * + + /* offset- offset in the replacement string */ + result->len = repl_nb = offset = 0; +- p=repl_comp->replacement.s; ++ p = repl_comp->replacement.s; + +- while( repl_nb < repl_comp->n_escapes){ ++ while(repl_nb < repl_comp->n_escapes) { + + token = repl_comp->replace[repl_nb]; + +- if(offset< token.offset){ +- if((repl_comp->replacement.len < offset)|| +- (result->len + token.offset -offset >= MAX_PHONE_NB_DIGITS)){ ++ if(offset < token.offset) { ++ if((repl_comp->replacement.len < offset) ++ || (result->len + token.offset - offset ++ >= MAX_PHONE_NB_DIGITS)) { + LM_ERR("invalid length\n"); + goto error; + } + /*copy from the replacing string*/ + size = token.offset - offset; + memcpy(result->s + result->len, p + offset, size); +- LM_DBG("copying <%.*s> from replacing string\n", +- size, p + offset); ++ LM_DBG("copying <%.*s> from replacing string\n", size, p + offset); + result->len += size; + offset = token.offset; + } + + switch(token.type) { + case REPLACE_NMATCH: +- /*copy from the match subexpression*/ ++ /*copy from the match subexpression*/ + match_nb = token.u.nmatch * 2; +- match.s = instr->s + ovector[match_nb]; ++ match.s = instr->s + ovector[match_nb]; + match.len = ovector[match_nb + 1] - ovector[match_nb]; +- if(result->len + match.len >= MAX_PHONE_NB_DIGITS){ ++ if(result->len + match.len >= MAX_PHONE_NB_DIGITS) { + LM_ERR("overflow\n"); + goto error; + } + + memcpy(result->s + result->len, match.s, match.len); +- LM_DBG("copying match <%.*s> token size %d\n", +- match.len, match.s, token.size); ++ LM_DBG("copying match <%.*s> token size %d\n", match.len, ++ match.s, token.size); + result->len += match.len; + offset += token.size; + break; + case REPLACE_CHAR: +- if(result->len + 1>= MAX_PHONE_NB_DIGITS){ ++ if(result->len + 1 >= MAX_PHONE_NB_DIGITS) { + LM_ERR("overflow\n"); + goto error; + } + *(result->s + result->len) = token.u.c; +- LM_DBG("copying char <%c> token size %d\n", +- token.u.c, token.size); ++ LM_DBG("copying char <%c> token size %d\n", token.u.c, ++ token.size); + result->len++; + offset += token.size; + break; +- case REPLACE_URI: +- if ( msg== NULL || msg->first_line.type!=SIP_REQUEST){ ++ case REPLACE_URI: ++ if(msg == NULL || msg->first_line.type != SIP_REQUEST) { + LM_CRIT("uri substitution attempt on no request" + " message\n"); + break; /* ignore, we can continue */ + } +- uri= (msg->new_uri.s)?(&msg->new_uri): +- (&msg->first_line.u.request.uri); +- if(result->len+uri->len>=MAX_PHONE_NB_DIGITS){ ++ uri = (msg->new_uri.s) ? (&msg->new_uri) ++ : (&msg->first_line.u.request.uri); ++ if(result->len + uri->len >= MAX_PHONE_NB_DIGITS) { + LM_ERR("overflow\n"); + goto error; + } + memcpy(result->s + result->len, uri->s, uri->len); +- LM_DBG("copying uri <%.*s> token size %d\n", +- uri->len, uri->s, token.size); +- result->len+=uri->len; ++ LM_DBG("copying uri <%.*s> token size %d\n", uri->len, uri->s, ++ token.size); ++ result->len += uri->len; + offset += token.size; + break; + case REPLACE_SPEC: +- if (msg== NULL) { ++ if(msg == NULL) { + LM_DBG("replace spec attempted on no message\n"); + break; + } +- if (pv_get_spec_value(msg, &token.u.spec, &sv) != 0) { ++ if(pv_get_spec_value(msg, &token.u.spec, &sv) != 0) { + LM_CRIT("item substitution returned error\n"); + break; /* ignore, we can continue */ + } +- if(result->len+sv.rs.len>=MAX_PHONE_NB_DIGITS){ ++ if(result->len + sv.rs.len >= MAX_PHONE_NB_DIGITS) { + LM_ERR("rule_translate: overflow\n"); + goto error; + } +- memcpy(result->s + result->len, sv.rs.s, +- sv.rs.len); +- LM_DBG("copying pvar value <%.*s> token size %d\n", +- sv.rs.len, sv.rs.s, token.size); +- result->len+=sv.rs.len; ++ memcpy(result->s + result->len, sv.rs.s, sv.rs.len); ++ LM_DBG("copying pvar value <%.*s> token size %d\n", sv.rs.len, ++ sv.rs.s, token.size); ++ result->len += sv.rs.len; + offset += token.size; + break; + default: +@@ -552,12 +561,12 @@ int rule_translate(sip_msg_t *msg, str * + repl_nb++; + } + /* anything left? */ +- if( repl_nb && offset < repl_comp->replacement.len){ ++ if(repl_nb && offset < repl_comp->replacement.len) { + /*copy from the replacing string*/ + size = repl_comp->replacement.len - offset; + memcpy(result->s + result->len, p + offset, size); +- LM_DBG("copying leftover <%.*s> from replacing string\n", +- size, p + offset); ++ LM_DBG("copying leftover <%.*s> from replacing string\n", size, ++ p + offset); + result->len += size; + } + +@@ -570,10 +579,10 @@ error: + return -1; + } + +-#define DP_MAX_ATTRS_LEN 255 +-static char dp_attrs_buf[DP_MAX_ATTRS_LEN+1]; +-int dp_translate_helper(sip_msg_t *msg, str *input, str *output, dpl_id_p idp, +- str *attrs) ++#define DP_MAX_ATTRS_LEN 255 ++static char dp_attrs_buf[DP_MAX_ATTRS_LEN + 1]; ++int dp_translate_helper( ++ sip_msg_t *msg, str *input, str *output, dpl_id_p idp, str *attrs) + { + dpl_node_p rulep; + dpl_index_p indexp; +@@ -588,70 +597,70 @@ int dp_translate_helper(sip_msg_t *msg, + } + + user_len = input->len; +- for(indexp = idp->first_index; indexp!=NULL; indexp = indexp->next) +- if(!indexp->len || (indexp->len!=0 && indexp->len == user_len) ) ++ for(indexp = idp->first_index; indexp != NULL; indexp = indexp->next) ++ if(!indexp->len || (indexp->len != 0 && indexp->len == user_len)) + break; + +- if(!indexp || (indexp!= NULL && !indexp->first_rule)){ ++ if(!indexp || (indexp != NULL && !indexp->first_rule)) { + LM_DBG("no rule for len %i\n", input->len); + return -1; + } + + search_rule: +- for(rulep=indexp->first_rule; rulep!=NULL; rulep= rulep->next) { ++ for(rulep = indexp->first_rule; rulep != NULL; rulep = rulep->next) { + switch(rulep->matchop) { + + case DP_REGEX_OP: +- LM_DBG("regex operator testing over [%.*s]\n", +- input->len, input->s); +- if(rulep->tflags&DP_TFLAGS_PV_MATCH) { ++ LM_DBG("regex operator testing over [%.*s]\n", input->len, ++ input->s); ++ if(rulep->tflags & DP_TFLAGS_PV_MATCH) { + re_list = dpl_dynamic_pcre_list(msg, &rulep->match_exp); +- if(re_list==NULL) { ++ if(re_list == NULL) { + /* failed to compile dynamic pcre -- ignore */ + LM_DBG("failed to compile dynamic pcre[%.*s]\n", +- rulep->match_exp.len, rulep->match_exp.s); ++ rulep->match_exp.len, rulep->match_exp.s); + continue; + } + rez = -1; + do { +- if(rez<0) { +- rez = pcre_exec(re_list->re, NULL, input->s, input->len, +- 0, 0, NULL, 0); ++ if(rez < 0) { ++ rez = pcre_exec(re_list->re, NULL, input->s, ++ input->len, 0, 0, NULL, 0); + LM_DBG("match check: [%.*s] %d\n", +- re_list->expr.len, re_list->expr.s, rez); +- } +- else LM_DBG("match check skipped: [%.*s] %d\n", +- re_list->expr.len, re_list->expr.s, rez); ++ re_list->expr.len, re_list->expr.s, rez); ++ } else ++ LM_DBG("match check skipped: [%.*s] %d\n", ++ re_list->expr.len, re_list->expr.s, rez); + rt = re_list->next; + pcre_free(re_list->re); + pkg_free(re_list); + re_list = rt; + } while(re_list); + } else { +- rez = pcre_exec(rulep->match_comp, NULL, input->s, input->len, +- 0, 0, NULL, 0); ++ rez = pcre_exec(rulep->match_comp, NULL, input->s, ++ input->len, 0, 0, NULL, 0); + } + break; + + case DP_EQUAL_OP: + LM_DBG("equal operator testing\n"); +- if(rulep->match_exp.s==NULL ++ if(rulep->match_exp.s == NULL + || rulep->match_exp.len != input->len) { + rez = -1; + } else { + rez = strncmp(rulep->match_exp.s, input->s, input->len); +- rez = (rez==0)?0:-1; ++ rez = (rez == 0) ? 0 : -1; + } + break; + + case DP_FNMATCH_OP: + LM_DBG("fnmatch operator testing\n"); +- if(rulep->match_exp.s!=NULL) { ++ if(rulep->match_exp.s != NULL) { + b = input->s[input->len]; + input->s[input->len] = '\0'; + rez = fnmatch(rulep->match_exp.s, input->s, 0); + input->s[input->len] = b; +- rez = (rez==0)?0:-1; ++ rez = (rez == 0) ? 0 : -1; + } else { + rez = -1; + } +@@ -665,8 +674,8 @@ search_rule: + goto repl; + } + /*test the rules with len 0*/ +- if(indexp->len){ +- for(indexp = indexp->next; indexp!=NULL; indexp = indexp->next) ++ if(indexp->len) { ++ for(indexp = indexp->next; indexp != NULL; indexp = indexp->next) + if(!indexp->len) + break; + if(indexp) +@@ -677,63 +686,61 @@ search_rule: + return -1; + + repl: +- LM_DBG("found a matching rule %p: pr %i, match_exp %.*s\n", +- rulep, rulep->pr, rulep->match_exp.len, rulep->match_exp.s); ++ LM_DBG("found a matching rule %p: pr %i, match_exp %.*s\n", rulep, ++ rulep->pr, rulep->match_exp.len, rulep->match_exp.s); + + if(attrs) { + attrs->len = 0; + attrs->s = 0; +- if(rulep->attrs.len>0) { +- LM_DBG("the rule's attrs are %.*s\n", +- rulep->attrs.len, rulep->attrs.s); ++ if(rulep->attrs.len > 0) { ++ LM_DBG("the rule's attrs are %.*s\n", rulep->attrs.len, ++ rulep->attrs.s); + if(rulep->attrs.len >= DP_MAX_ATTRS_LEN) { + LM_ERR("out of memory for attributes\n"); + return -1; + } + attrs->s = dp_attrs_buf; +- memcpy(attrs->s, rulep->attrs.s, rulep->attrs.len*sizeof(char)); ++ memcpy(attrs->s, rulep->attrs.s, rulep->attrs.len * sizeof(char)); + attrs->len = rulep->attrs.len; + attrs->s[attrs->len] = '\0'; + +- LM_DBG("the copied attributes are: %.*s\n", +- attrs->len, attrs->s); ++ LM_DBG("the copied attributes are: %.*s\n", attrs->len, attrs->s); + } + } + if(!output) { + return 0; + } +- if(rulep->tflags&DP_TFLAGS_PV_SUBST) { ++ if(rulep->tflags & DP_TFLAGS_PV_SUBST) { + re_list = dpl_dynamic_pcre_list(msg, &rulep->subst_exp); +- if(re_list==NULL) { ++ if(re_list == NULL) { + /* failed to compile dynamic pcre -- ignore */ + LM_DBG("failed to compile dynamic pcre[%.*s]\n", +- rulep->subst_exp.len, rulep->subst_exp.s); ++ rulep->subst_exp.len, rulep->subst_exp.s); + return -1; + } + rez = -1; + do { +- if(rez<0) { ++ if(rez < 0) { + rez = rule_translate(msg, input, rulep, re_list->re, output); +- LM_DBG("subst check: [%.*s] %d\n", +- re_list->expr.len, re_list->expr.s, rez); +- } +- else LM_DBG("subst check skipped: [%.*s] %d\n", +- re_list->expr.len, re_list->expr.s, rez); ++ LM_DBG("subst check: [%.*s] %d\n", re_list->expr.len, ++ re_list->expr.s, rez); ++ } else ++ LM_DBG("subst check skipped: [%.*s] %d\n", re_list->expr.len, ++ re_list->expr.s, rez); + rt = re_list->next; + pcre_free(re_list->re); + pkg_free(re_list); + re_list = rt; + } while(re_list); +- if(rez<0) { ++ if(rez < 0) { + LM_ERR("the string %.*s matched " +- "the match_exp %.*s but not the subst_exp %.*s!\n", +- input->len, input->s, +- rulep->match_exp.len, rulep->match_exp.s, +- rulep->subst_exp.len, rulep->subst_exp.s); ++ "the match_exp %.*s but not the subst_exp %.*s!\n", ++ input->len, input->s, rulep->match_exp.len, ++ rulep->match_exp.s, rulep->subst_exp.len, ++ rulep->subst_exp.s); + } +- } +- else { +- if(rule_translate(msg, input, rulep, rulep->subst_comp, output)!=0){ ++ } else { ++ if(rule_translate(msg, input, rulep, rulep->subst_comp, output) != 0) { + LM_ERR("could not build the output\n"); + return -1; + } diff --git a/net/kamailio/patches/011-dialplan-migrate-to-pcre2.patch b/net/kamailio/patches/011-dialplan-migrate-to-pcre2.patch new file mode 100644 index 000000000..23eede050 --- /dev/null +++ b/net/kamailio/patches/011-dialplan-migrate-to-pcre2.patch @@ -0,0 +1,456 @@ +From 374227b15ff7fbed8660beb93d52da15dcb4ba9e Mon Sep 17 00:00:00 2001 +From: Victor Seva +Date: Mon, 21 Aug 2023 12:27:43 +0200 +Subject: [PATCH] dialplan: migrate to pcre2 + +--- + src/modules/dialplan/Makefile | 11 +--- + src/modules/dialplan/dialplan.c | 5 ++ + src/modules/dialplan/dialplan.h | 20 ++++--- + src/modules/dialplan/dp_db.c | 103 +++++++++++++++++++------------- + src/modules/dialplan/dp_repl.c | 56 +++++++++++------ + 5 files changed, 121 insertions(+), 74 deletions(-) + +--- a/src/modules/dialplan/Makefile ++++ b/src/modules/dialplan/Makefile +@@ -6,20 +6,15 @@ auto_gen= + NAME=dialplan.so + + ifeq ($(CROSS_COMPILE),) +-PCRE_BUILDER = $(shell \ +- if pkg-config --exists libcre; then \ +- echo 'pkg-config libpcre'; \ +- else \ +- which pcre-config; \ +- fi) ++PCRE_BUILDER = $(shell command -v pcre2-config) + endif + + ifeq ($(PCRE_BUILDER),) + PCREDEFS=-I$(LOCALBASE)/include +- PCRELIBS=-L$(LOCALBASE)/lib -lpcre ++ PCRELIBS=-L$(LOCALBASE)/lib -lpcre2-8 + else + PCREDEFS = $(shell $(PCRE_BUILDER) --cflags) +- PCRELIBS = $(shell $(PCRE_BUILDER) --libs) ++ PCRELIBS = $(shell $(PCRE_BUILDER) --libs8) + endif + DEFS+=$(PCREDEFS) + LIBS=$(PCRELIBS) +--- a/src/modules/dialplan/dialplan.c ++++ b/src/modules/dialplan/dialplan.c +@@ -5,6 +5,8 @@ + * + * Copyright (C) 2014 Olle E. Johansson, Edvina AB + * ++ * Copyright (C) 2023 Victor Seva ++ * + * This file is part of Kamailio, a free SIP server. + * + * Kamailio is free software; you can redistribute it and/or modify +@@ -79,6 +81,9 @@ static int ki_dp_translate_vars( + int dp_replace_fixup(void **param, int param_no); + int dp_replace_fixup_free(void **param, int param_no); + ++pcre2_general_context *dpl_gctx = NULL; ++pcre2_compile_context *dpl_ctx = NULL; ++ + str dp_attr_pvar_s = STR_NULL; + pv_spec_t *dp_attr_pvar = NULL; + +--- a/src/modules/dialplan/dialplan.h ++++ b/src/modules/dialplan/dialplan.h +@@ -13,8 +13,8 @@ + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * +- * You should have received a copy of the GNU General Public License +- * along with this program; if not, write to the Free Software ++ * You should have received a copy of the GNU General Public License ++ * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + */ +@@ -30,7 +30,8 @@ + #ifndef _DP_DIALPLAN_H + #define _DP_DIALPLAN_H + +-#include ++#define PCRE2_CODE_UNIT_WIDTH 8 ++#include + #include "../../core/pvar.h" + #include "../../core/parser/msg_parser.h" + +@@ -43,6 +44,9 @@ + #define DP_TFLAGS_PV_MATCH (1 << 0) + #define DP_TFLAGS_PV_SUBST (1 << 1) + ++extern pcre2_general_context *dpl_gctx; ++extern pcre2_compile_context *dpl_ctx; ++ + typedef struct dpl_node + { + int dpid; /* dialplan id */ +@@ -52,8 +56,8 @@ typedef struct dpl_node + str match_exp; /* match-first string */ + str subst_exp; /* match string with subtitution groupping */ + str repl_exp; /* replacement expression string */ +- pcre *match_comp; /* compiled matching expression */ +- pcre *subst_comp; /* compiled substitution expression */ ++ pcre2_code *match_comp; /* compiled matching expression */ ++ pcre2_code *subst_comp; /* compiled substitution expression */ + struct subst_expr *repl_comp; /* compiled replacement */ + str attrs; /* attributes string */ + unsigned int tflags; /* flags for type of values for matching */ +@@ -103,8 +107,8 @@ struct subst_expr *repl_exp_parse(str su + void repl_expr_free(struct subst_expr *se); + int dp_translate_helper( + sip_msg_t *msg, str *user_name, str *repl_user, dpl_id_p idp, str *); +-int rule_translate( +- sip_msg_t *msg, str *instr, dpl_node_t *rule, pcre *subst_comp, str *); ++int rule_translate(sip_msg_t *msg, str *instr, dpl_node_t *rule, ++ pcre2_code *subst_comp, str *); + +-pcre *reg_ex_comp(const char *pattern, int *cap_cnt, int mtype); ++pcre2_code *reg_ex_comp(const char *pattern, int *cap_cnt, int mtype); + #endif +--- a/src/modules/dialplan/dp_db.c ++++ b/src/modules/dialplan/dp_db.c +@@ -196,11 +196,31 @@ void dp_disconnect_db(void) + } + } + ++static void *pcre2_malloc(size_t size, void *ext) ++{ ++ return shm_malloc(size); ++} ++ ++static void pcre2_free(void *ptr, void *ext) ++{ ++ shm_free(ptr); ++ ptr = NULL; ++} + + int init_data(void) + { + int *p; + ++ if((dpl_gctx = pcre2_general_context_create(pcre2_malloc, pcre2_free, NULL)) ++ == NULL) { ++ LM_ERR("pcre2 general context creation failed\n"); ++ return -1; ++ } ++ if((dpl_ctx = pcre2_compile_context_create(dpl_gctx)) == NULL) { ++ LM_ERR("pcre2 compile context creation failed\n"); ++ return -1; ++ } ++ + dp_rules_hash = (dpl_id_p *)shm_malloc(2 * sizeof(dpl_id_p)); + if(!dp_rules_hash) { + LM_ERR("out of shm memory\n"); +@@ -227,6 +247,14 @@ int init_data(void) + + void destroy_data(void) + { ++ if(dpl_ctx) { ++ pcre2_compile_context_free(dpl_ctx); ++ } ++ ++ if(dpl_gctx) { ++ pcre2_general_context_free(dpl_gctx); ++ } ++ + if(dp_rules_hash) { + destroy_hash(0); + destroy_hash(1); +@@ -373,55 +401,50 @@ int dpl_str_to_shm(str src, str *dest, i + + + /* Compile pcre pattern +- * if mtype==0 - return pointer to shm copy of result +- * if mtype==1 - return pcre pointer that has to be pcre_free() */ +-pcre *reg_ex_comp(const char *pattern, int *cap_cnt, int mtype) +-{ +- pcre *re, *result; +- const char *error; +- int rc, err_offset; +- size_t size; ++ * if mtype==0 - return pointer using shm ++ * if mtype==1 - return pcre2_code pointer that has to be pcre2_code_free() */ ++pcre2_code *reg_ex_comp(const char *pattern, int *cap_cnt, int mtype) ++{ ++ pcre2_code *re; ++ int pcre_error_num = 0; ++ char pcre_error[128]; ++ size_t pcre_erroffset; ++ int rc; + +- re = pcre_compile(pattern, 0, &error, &err_offset, NULL); ++ re = pcre2_compile((PCRE2_SPTR)pattern, PCRE2_ZERO_TERMINATED, 0, ++ &pcre_error_num, &pcre_erroffset, mtype == 0 ? dpl_ctx : NULL); + if(re == NULL) { +- LM_ERR("PCRE compilation of '%s' failed at offset %d: %s\n", pattern, +- err_offset, error); +- return (pcre *)0; +- } +- rc = pcre_fullinfo(re, NULL, PCRE_INFO_SIZE, &size); +- if(rc != 0) { +- pcre_free(re); +- LM_ERR("pcre_fullinfo on compiled pattern '%s' yielded error: %d\n", +- pattern, rc); +- return (pcre *)0; ++ switch(pcre2_get_error_message( ++ pcre_error_num, (PCRE2_UCHAR *)pcre_error, 128)) { ++ case PCRE2_ERROR_NOMEMORY: ++ snprintf(pcre_error, 128, ++ "unknown error[%d]: pcre2 error buffer too small", ++ pcre_error_num); ++ break; ++ case PCRE2_ERROR_BADDATA: ++ snprintf(pcre_error, 128, "unknown pcre2 error[%d]", ++ pcre_error_num); ++ break; ++ } ++ LM_ERR("PCRE compilation of '%s' failed at offset %zu: %s\n", pattern, ++ pcre_erroffset, pcre_error); ++ return NULL; + } +- rc = pcre_fullinfo(re, NULL, PCRE_INFO_CAPTURECOUNT, cap_cnt); ++ rc = pcre2_pattern_info(re, PCRE2_INFO_CAPTURECOUNT, cap_cnt); + if(rc != 0) { +- pcre_free(re); ++ pcre2_code_free(re); + LM_ERR("pcre_fullinfo on compiled pattern '%s' yielded error: %d\n", + pattern, rc); +- return (pcre *)0; +- } +- if(mtype == 0) { +- result = (pcre *)shm_malloc(size); +- if(result == NULL) { +- pcre_free(re); +- LM_ERR("not enough shared memory for compiled PCRE pattern\n"); +- return (pcre *)0; +- } +- memcpy(result, re, size); +- pcre_free(re); +- return result; +- } else { +- return re; ++ return NULL; + } ++ return re; + } + + + /*compile the expressions, and if ok, build the rule */ + dpl_node_t *build_rule(db_val_t *values) + { +- pcre *match_comp, *subst_comp; ++ pcre2_code *match_comp, *subst_comp; + struct subst_expr *repl_comp; + dpl_node_t *new_rule; + str match_exp, subst_exp, repl_exp, attrs; +@@ -544,9 +567,9 @@ dpl_node_t *build_rule(db_val_t *values) + + err: + if(match_comp) +- shm_free(match_comp); ++ pcre2_code_free(match_comp); + if(subst_comp) +- shm_free(subst_comp); ++ pcre2_code_free(subst_comp); + if(repl_comp) + repl_expr_free(repl_comp); + if(new_rule) +@@ -692,10 +715,10 @@ void destroy_rule(dpl_node_t *rule) + LM_DBG("destroying rule with priority %i\n", rule->pr); + + if(rule->match_comp) +- shm_free(rule->match_comp); ++ pcre2_code_free(rule->match_comp); + + if(rule->subst_comp) +- shm_free(rule->subst_comp); ++ pcre2_code_free(rule->subst_comp); + + /*destroy repl_exp*/ + if(rule->repl_comp) +--- a/src/modules/dialplan/dp_repl.c ++++ b/src/modules/dialplan/dp_repl.c +@@ -15,8 +15,8 @@ + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * +- * You should have received a copy of the GNU General Public License +- * along with this program; if not, write to the Free Software ++ * You should have received a copy of the GNU General Public License ++ * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + */ +@@ -38,7 +38,7 @@ + + typedef struct dpl_dyn_pcre + { +- pcre *re; ++ pcre2_code *re; + int cnt; + str expr; + +@@ -186,9 +186,10 @@ int dpl_detect_avp_indx(const pv_elem_p + return 0; + } + +-pcre *dpl_dyn_pcre_comp(sip_msg_t *msg, str *expr, str *vexpr, int *cap_cnt) ++pcre2_code *dpl_dyn_pcre_comp( ++ sip_msg_t *msg, str *expr, str *vexpr, int *cap_cnt) + { +- pcre *re = NULL; ++ pcre2_code *re = NULL; + int ccnt = 0; + + if(expr == NULL || expr->s == NULL || expr->len <= 0 || vexpr == NULL +@@ -225,7 +226,7 @@ dpl_dyn_pcre_p dpl_dynamic_pcre_list(sip + dpl_dyn_pcre_p rt = NULL; + struct str_list *l = NULL; + struct str_list *t = NULL; +- pcre *re = NULL; ++ pcre2_code *re = NULL; + int cnt = 0; + str vexpr = STR_NULL; + +@@ -294,7 +295,7 @@ error: + while(re_list) { + rt = re_list->next; + if(re_list->re) +- pcre_free(re_list->re); ++ pcre2_code_free(re_list->re); + pkg_free(re_list); + re_list = rt; + } +@@ -400,15 +401,16 @@ error: + #define MAX_PHONE_NB_DIGITS 127 + static char dp_output_buf[MAX_PHONE_NB_DIGITS + 1]; + int rule_translate(sip_msg_t *msg, str *instr, dpl_node_t *rule, +- pcre *subst_comp, str *result) ++ pcre2_code *subst_comp, str *result) + { + int repl_nb, offset, match_nb, rc, cap_cnt; + struct replace_with token; + struct subst_expr *repl_comp; ++ pcre2_match_data *pcre_md = NULL; + str match; + pv_value_t sv; + str *uri; +- int ovector[3 * (MAX_REPLACE_WITH + 1)]; ++ PCRE2_SIZE *ovector = NULL; + char *p; + int size; + +@@ -424,7 +426,7 @@ int rule_translate(sip_msg_t *msg, str * + + if(subst_comp) { + /*just in case something went wrong at load time*/ +- rc = pcre_fullinfo(subst_comp, NULL, PCRE_INFO_CAPTURECOUNT, &cap_cnt); ++ rc = pcre2_pattern_info(subst_comp, PCRE2_INFO_CAPTURECOUNT, &cap_cnt); + if(rc != 0) { + LM_ERR("pcre_fullinfo on compiled pattern yielded error: %d\n", rc); + return -1; +@@ -441,15 +443,19 @@ int rule_translate(sip_msg_t *msg, str * + } + + /*search for the pattern from the compiled subst_exp*/ +- if(pcre_exec(subst_comp, NULL, instr->s, instr->len, 0, 0, ovector, +- 3 * (MAX_REPLACE_WITH + 1)) ++ pcre_md = pcre2_match_data_create_from_pattern(subst_comp, NULL); ++ if(pcre2_match(subst_comp, (PCRE2_SPTR)instr->s, (PCRE2_SIZE)instr->len, ++ 0, 0, pcre_md, NULL) + <= 0) { + LM_DBG("the string %.*s matched " + "the match_exp %.*s but not the subst_exp %.*s!\n", + instr->len, instr->s, rule->match_exp.len, + rule->match_exp.s, rule->subst_exp.len, rule->subst_exp.s); ++ if(pcre_md) ++ pcre2_match_data_free(pcre_md); + return -1; + } ++ ovector = pcre2_get_ovector_pointer(pcre_md); + } + + /*simply copy from the replacing string*/ +@@ -463,6 +469,8 @@ int rule_translate(sip_msg_t *msg, str * + memcpy(result->s, repl_comp->replacement.s, repl_comp->replacement.len); + result->len = repl_comp->replacement.len; + result->s[result->len] = '\0'; ++ if(pcre_md) ++ pcre2_match_data_free(pcre_md); + return 0; + } + +@@ -571,11 +579,15 @@ int rule_translate(sip_msg_t *msg, str * + } + + result->s[result->len] = '\0'; ++ if(pcre_md) ++ pcre2_match_data_free(pcre_md); + return 0; + + error: + result->s = 0; + result->len = 0; ++ if(pcre_md) ++ pcre2_match_data_free(pcre_md); + return -1; + } + +@@ -584,6 +596,7 @@ static char dp_attrs_buf[DP_MAX_ATTRS_LE + int dp_translate_helper( + sip_msg_t *msg, str *input, str *output, dpl_id_p idp, str *attrs) + { ++ pcre2_match_data *pcre_md = NULL; + dpl_node_p rulep; + dpl_index_p indexp; + int user_len, rez; +@@ -624,21 +637,28 @@ search_rule: + rez = -1; + do { + if(rez < 0) { +- rez = pcre_exec(re_list->re, NULL, input->s, +- input->len, 0, 0, NULL, 0); ++ pcre_md = pcre2_match_data_create_from_pattern( ++ re_list->re, NULL); ++ rez = pcre2_match(re_list->re, (PCRE2_SPTR)input->s, ++ (PCRE2_SIZE)input->len, 0, 0, pcre_md, ++ NULL); + LM_DBG("match check: [%.*s] %d\n", + re_list->expr.len, re_list->expr.s, rez); + } else + LM_DBG("match check skipped: [%.*s] %d\n", + re_list->expr.len, re_list->expr.s, rez); + rt = re_list->next; +- pcre_free(re_list->re); ++ pcre2_match_data_free(pcre_md); ++ pcre2_code_free(re_list->re); + pkg_free(re_list); + re_list = rt; + } while(re_list); + } else { +- rez = pcre_exec(rulep->match_comp, NULL, input->s, +- input->len, 0, 0, NULL, 0); ++ pcre_md = pcre2_match_data_create_from_pattern( ++ rulep->match_comp, NULL); ++ rez = pcre2_match(rulep->match_comp, (PCRE2_SPTR)input->s, ++ (PCRE2_SIZE)input->len, 0, 0, pcre_md, 0); ++ pcre2_match_data_free(pcre_md); + } + break; + +@@ -728,7 +748,7 @@ repl: + LM_DBG("subst check skipped: [%.*s] %d\n", re_list->expr.len, + re_list->expr.s, rez); + rt = re_list->next; +- pcre_free(re_list->re); ++ pcre2_code_free(re_list->re); + pkg_free(re_list); + re_list = rt; + } while(re_list); diff --git a/net/kamailio/patches/020-lcr-clang-format-for-coherent-indentation-and-coding.patch b/net/kamailio/patches/020-lcr-clang-format-for-coherent-indentation-and-coding.patch new file mode 100644 index 000000000..8a5447c87 --- /dev/null +++ b/net/kamailio/patches/020-lcr-clang-format-for-coherent-indentation-and-coding.patch @@ -0,0 +1,510 @@ +From ecc2c9e54fa8f24c1e96860c1f59b43f2e1e8b7a Mon Sep 17 00:00:00 2001 +From: Victor Seva +Date: Wed, 17 May 2023 16:36:55 +0200 +Subject: [PATCH] lcr: clang-format for coherent indentation and coding style + +--- + src/modules/lcr/lcr_mod.c | 125 +++++++++++++++++++++----------------- + src/modules/lcr/lcr_rpc.c | 65 ++++++++++---------- + 2 files changed, 102 insertions(+), 88 deletions(-) + +--- a/src/modules/lcr/lcr_mod.c ++++ b/src/modules/lcr/lcr_mod.c +@@ -259,7 +259,8 @@ static int inactivate_gw(struct sip_msg + static int defunct_gw(struct sip_msg *_m, char *_s1, char *_s2); + static int from_gw_1(struct sip_msg *_m, char *_s1, char *_s2); + static int from_gw_3(struct sip_msg *_m, char *_s1, char *_s2, char *_s3); +-static int from_gw_4(struct sip_msg *_m, char *_s1, char *_s2, char *_s3, char *_s4); ++static int from_gw_4( ++ struct sip_msg *_m, char *_s1, char *_s2, char *_s3, char *_s4); + static int from_any_gw_0(struct sip_msg *_m, char *_s1, char *_s2); + static int from_any_gw_2(struct sip_msg *_m, char *_s1, char *_s2); + static int from_any_gw_3(struct sip_msg *_m, char *_s1, char *_s2, char *_s3); +@@ -554,7 +555,8 @@ static int mod_init(void) + LM_ERR("malformed or non AVP definition <%s>\n", rule_id_avp_param); + return -1; + } +- if(pv_get_avp_name(0, &(avp_spec->pvp), &rule_id_avp, &avp_flags) != 0) { ++ if(pv_get_avp_name(0, &(avp_spec->pvp), &rule_id_avp, &avp_flags) ++ != 0) { + LM_ERR("invalid AVP definition <%s>\n", rule_id_avp_param); + return -1; + } +@@ -680,18 +682,21 @@ static int mod_init(void) + LM_ERR("unable to open database connection\n"); + return -1; + } +- if(db_check_table_version(&lcr_dbf, dbh, &lcr_rule_table, +- LCR_RULE_TABLE_VERSION) < 0) { ++ if(db_check_table_version( ++ &lcr_dbf, dbh, &lcr_rule_table, LCR_RULE_TABLE_VERSION) ++ < 0) { + DB_TABLE_VERSION_ERROR(lcr_rule_table); + goto dberror; + } + if(db_check_table_version(&lcr_dbf, dbh, &lcr_rule_target_table, +- LCR_RULE_TARGET_TABLE_VERSION) < 0) { ++ LCR_RULE_TARGET_TABLE_VERSION) ++ < 0) { + DB_TABLE_VERSION_ERROR(lcr_rule_target_table); + goto dberror; + } +- if (db_check_table_version(&lcr_dbf, dbh, &lcr_gw_table, +- LCR_GW_TABLE_VERSION) < 0) { ++ if(db_check_table_version( ++ &lcr_dbf, dbh, &lcr_gw_table, LCR_GW_TABLE_VERSION) ++ < 0) { + DB_TABLE_VERSION_ERROR(lcr_gw_table); + goto dberror; + } +@@ -923,20 +928,24 @@ static int comp_gws(const void *_g1, con + /* + * Compare a gateway using IP address and the src port + */ +-static struct gw_info * find_gateway_by_ip_and_port(struct gw_info * gw, struct gw_info * gws) { ++static struct gw_info *find_gateway_by_ip_and_port( ++ struct gw_info *gw, struct gw_info *gws) ++{ + int tmp = 0, gw_index = 0, i; + +- for (i = 1; i <= gws[0].ip_addr.u.addr32[0]; i++) { +- tmp = memcmp(gws[i].ip_addr.u.addr, gw->ip_addr.u.addr, gws[i].ip_addr.len); +- if (gws[i].ip_addr.af == gw->ip_addr.af && +- gws[i].ip_addr.len == gw->ip_addr.len && +- tmp == 0 && /* a comparison of the IP address value */ +- gws[i].port == gw->port) { +- gw_index = i; +- break; ++ for(i = 1; i <= gws[0].ip_addr.u.addr32[0]; i++) { ++ tmp = memcmp( ++ gws[i].ip_addr.u.addr, gw->ip_addr.u.addr, gws[i].ip_addr.len); ++ if(gws[i].ip_addr.af == gw->ip_addr.af ++ && gws[i].ip_addr.len == gw->ip_addr.len && tmp == 0 ++ && /* a comparison of the IP address value */ ++ gws[i].port == gw->port) { ++ gw_index = i; ++ break; + } + } +- if (gw_index != 0) return &(gws[gw_index]); ++ if(gw_index != 0) ++ return &(gws[gw_index]); + + return NULL; + } +@@ -1074,7 +1083,7 @@ static int insert_gws(db1_res_t *res, st + row = RES_ROWS(res) + i; + if((VAL_NULL(ROW_VALUES(row) + 12) == 1) + || ((VAL_TYPE(ROW_VALUES(row) + 12) != DB1_INT) +- && (VAL_TYPE(ROW_VALUES(row) + 12) != DB1_UINT))) { ++ && (VAL_TYPE(ROW_VALUES(row) + 12) != DB1_UINT))) { + LM_ERR("lcr_gw id at row <%u> is null or not int\n", i); + return 0; + } +@@ -1501,8 +1510,7 @@ int reload_tables() + + if((VAL_NULL(ROW_VALUES(row)) == 1) + || ((VAL_TYPE(ROW_VALUES(row)) != DB1_INT) +- && (VAL_TYPE(ROW_VALUES(row)) +- != DB1_UINT))) { ++ && (VAL_TYPE(ROW_VALUES(row)) != DB1_UINT))) { + LM_ERR("lcr rule id at row <%u> is null or not int\n", i); + goto err; + } +@@ -1544,8 +1552,8 @@ int reload_tables() + + if((VAL_NULL(ROW_VALUES(row) + 3) == 1) + || ((VAL_TYPE(ROW_VALUES(row) + 3) != DB1_INT) +- && (VAL_TYPE(ROW_VALUES(row) + 3) +- != DB1_UINT))) { ++ && (VAL_TYPE(ROW_VALUES(row) + 3) ++ != DB1_UINT))) { + LM_ERR("lcr rule <%u> stopper is NULL or not int\n", + rule_id); + goto err; +@@ -1558,8 +1566,8 @@ int reload_tables() + + if((VAL_NULL(ROW_VALUES(row) + 4) == 1) + || ((VAL_TYPE(ROW_VALUES(row) + 4) != DB1_INT) +- && (VAL_TYPE(ROW_VALUES(row) + 4) +- != DB1_UINT))) { ++ && (VAL_TYPE(ROW_VALUES(row) + 4) ++ != DB1_UINT))) { + LM_ERR("lcr rule <%u> enabled is NULL or not int\n", + rule_id); + goto err; +@@ -1769,8 +1777,7 @@ int reload_tables() + row = RES_ROWS(res) + i; + if((VAL_NULL(ROW_VALUES(row)) == 1) + || ((VAL_TYPE(ROW_VALUES(row)) != DB1_INT) +- && (VAL_TYPE(ROW_VALUES(row)) +- != DB1_UINT))) { ++ && (VAL_TYPE(ROW_VALUES(row)) != DB1_UINT))) { + LM_ERR("lcr_rule_target rule_id at row <%u> is null " + "or not int\n", + i); +@@ -1779,8 +1786,8 @@ int reload_tables() + rule_id = (unsigned int)VAL_INT(ROW_VALUES(row)); + if((VAL_NULL(ROW_VALUES(row) + 1) == 1) + || ((VAL_TYPE(ROW_VALUES(row) + 1) != DB1_INT) +- && (VAL_TYPE(ROW_VALUES(row) + 1) +- != DB1_UINT))) { ++ && (VAL_TYPE(ROW_VALUES(row) + 1) ++ != DB1_UINT))) { + LM_ERR("lcr_rule_target gw_id at row <%u> is null " + "or not int\n", + i); +@@ -1789,8 +1796,8 @@ int reload_tables() + gw_id = (unsigned int)VAL_INT(ROW_VALUES(row) + 1); + if((VAL_NULL(ROW_VALUES(row) + 2) == 1) + || ((VAL_TYPE(ROW_VALUES(row) + 2) != DB1_INT) +- && (VAL_TYPE(ROW_VALUES(row) + 2) +- != DB1_UINT))) { ++ && (VAL_TYPE(ROW_VALUES(row) + 2) ++ != DB1_UINT))) { + LM_ERR("lcr_rule_target priority at row <%u> is null " + "or not int\n", + i); +@@ -1805,8 +1812,8 @@ int reload_tables() + } + if((VAL_NULL(ROW_VALUES(row) + 3) == 1) + || ((VAL_TYPE(ROW_VALUES(row) + 3) != DB1_INT) +- && (VAL_TYPE(ROW_VALUES(row) + 3) +- != DB1_UINT))) { ++ && (VAL_TYPE(ROW_VALUES(row) + 3) ++ != DB1_UINT))) { + LM_ERR("lcr_rule_target weight at row <%u> is null " + "or not int\n", + i); +@@ -2087,10 +2094,10 @@ void add_gws_into_avps(struct gw_info *g + if(5 /* gw_index */ + 5 /* scheme */ + 4 /* strip */ + prefix_len + + tag_len + 1 /* @ */ + + ((hostname_len > IP6_MAX_STR_SIZE + 2) +- ? hostname_len +- : IP6_MAX_STR_SIZE + 2) ++ ? hostname_len ++ : IP6_MAX_STR_SIZE + 2) + + 6 /* port */ + params_len /* params */ +- + 15 /* transport */ + 10 /* flags */ ++ + 15 /* transport */ + 10 /* flags */ + + 7 /* separators */ + + 10 /* rule_id */ + > MAX_URI_LEN) { +@@ -2174,7 +2181,7 @@ int load_gws_dummy(int lcr_id, str *ruri + if((rule->from_uri_len != 0) + && (pcre_exec(rule->from_uri_re, NULL, from_uri->s, + from_uri->len, 0, 0, NULL, 0) +- < 0)) ++ < 0)) + goto next; + + if((from_uri->len > 0) && (rule->mt_tvalue_len > 0)) { +@@ -2339,7 +2346,7 @@ static int ki_load_gws_furi( + if((rule->from_uri_len != 0) + && (pcre_exec(rule->from_uri_re, NULL, from_uri->s, + from_uri->len, 0, 0, NULL, 0) +- < 0)) { ++ < 0)) { + LM_DBG("from uri <%.*s> did not match to from regex <%.*s>\n", + from_uri->len, from_uri->s, rule->from_uri_len, + rule->from_uri); +@@ -2375,7 +2382,7 @@ static int ki_load_gws_furi( + if((rule->request_uri_len != 0) + && (pcre_exec(rule->request_uri_re, NULL, request_uri->s, + request_uri->len, 0, 0, NULL, 0) +- < 0)) { ++ < 0)) { + LM_DBG("request uri <%.*s> did not match to request regex " + "<%.*s>\n", + request_uri->len, request_uri->s, rule->request_uri_len, +@@ -2549,7 +2556,8 @@ static int generate_uris(struct sip_msg + return 0; /* No more gateways left */ + + decode_avp_value(gw_uri_val.s.s, gw_index, &scheme, &strip, &prefix, +- &tmp_tag, addr, &hostname, &port, ¶ms, &transport, flags, rule_id); ++ &tmp_tag, addr, &hostname, &port, ¶ms, &transport, flags, ++ rule_id); + + if(addr->af != 0) { + addr_str.s = ip_addr2a(addr); +@@ -2560,8 +2568,8 @@ static int generate_uris(struct sip_msg + + if(scheme.len + r_uri_user->len - strip + prefix.len + 1 /* @ */ + + ((hostname.len > IP6_MAX_STR_SIZE + 2) +- ? hostname.len +- : IP6_MAX_STR_SIZE + 2) ++ ? hostname.len ++ : IP6_MAX_STR_SIZE + 2) + + 1 /* : */ + port.len + params.len + transport.len + + 1 /* null */ + > MAX_URI_LEN) { +@@ -2992,7 +3000,7 @@ static int ki_next_gw(sip_msg_t *_m) + if(rule_id_avp_param) { + val.n = rule_id; + add_avp(rule_id_avp_type, rule_id_avp, val); +- LM_DBG("added rule_id_avp <%u>\n", (unsigned int)val.n); ++ LM_DBG("added rule_id_avp <%u>\n", (unsigned int)val.n); + } + + /* Add index of selected gw to defunct gw AVP */ +@@ -3018,7 +3026,8 @@ static int next_gw(struct sip_msg *_m, c + * Checks if request comes from ip address of a gateway + */ + static int do_from_gw(struct sip_msg *_m, unsigned int lcr_id, +- struct ip_addr *src_addr, uri_transport transport, unsigned int src_port) ++ struct ip_addr *src_addr, uri_transport transport, ++ unsigned int src_port) + { + struct gw_info *res, gw, *gws; + int_str val; +@@ -3032,18 +3041,20 @@ static int do_from_gw(struct sip_msg *_m + } + + gw.ip_addr = *src_addr; +- if (src_port != 0) { ++ if(src_port != 0) { + /* Search for gw based on its ip address and port */ + gw.port = src_port; + res = find_gateway_by_ip_and_port(&gw, gws); + } else { + /* Search for gw based on its ip address */ +- res = (struct gw_info *)bsearch(&gw, &(gws[1]), gws[0].ip_addr.u.addr32[0], +- sizeof(struct gw_info), comp_gws); ++ res = (struct gw_info *)bsearch(&gw, &(gws[1]), ++ gws[0].ip_addr.u.addr32[0], sizeof(struct gw_info), comp_gws); + } + + /* Store tag and flags and return result */ +- if((res != NULL) && ((transport == PROTO_NONE) || (res->transport_code == transport))) { ++ if((res != NULL) ++ && ((transport == PROTO_NONE) ++ || (res->transport_code == transport))) { + LM_DBG("request came from gw\n"); + if(tag_avp_param) { + val.s.s = res->tag; +@@ -3178,8 +3189,8 @@ static int from_gw_3( + return ki_from_gw_addr_port(_m, lcr_id, &addr_str, transport, 0); + } + +-static int from_gw_4( +- struct sip_msg *_m, char *_lcr_id, char *_addr, char *_transport, char *_src_port) ++static int from_gw_4(struct sip_msg *_m, char *_lcr_id, char *_addr, ++ char *_transport, char *_src_port) + { + int lcr_id; + str addr_str; +@@ -3202,7 +3213,7 @@ static int from_gw_4( + LM_ERR("invalid transport parameter %s\n", _lcr_id); + return -1; + } +- tmp=0; ++ tmp = 0; + src_port = strtol(_src_port, &tmp, 10); + if((tmp == 0) || (*tmp) || (tmp == _src_port)) { + LM_ERR("invalid port parameter %s\n", _src_port); +@@ -3243,8 +3254,8 @@ static int from_any_gw_0(struct sip_msg + * Checks if request comes from ip address of a gateway taking source + * IP address, transport protocol and source port from parameters. + */ +-static int ki_from_any_gw_addr_port(sip_msg_t *_m, str *addr_str, int transport, +- int src_port) ++static int ki_from_any_gw_addr_port( ++ sip_msg_t *_m, str *addr_str, int transport, int src_port) + { + unsigned int i; + struct ip_addr *ip, src_addr; +@@ -3307,7 +3318,8 @@ static int from_any_gw_2(struct sip_msg + return ki_from_any_gw_addr_port(_m, &addr_str, transport, 0); + } + +-static int from_any_gw_3(struct sip_msg *_m, char *_addr, char *_transport, char *_src_port) ++static int from_any_gw_3( ++ struct sip_msg *_m, char *_addr, char *_transport, char *_src_port) + { + str addr_str; + uri_transport transport; +@@ -3323,7 +3335,7 @@ static int from_any_gw_3(struct sip_msg + LM_ERR("invalid transport parameter %s\n", _transport); + return -1; + } +- tmp=0; ++ tmp = 0; + src_port = strtol(_src_port, &tmp, 10); + if((tmp == 0) || (*tmp) || (tmp == _src_port)) { + LM_ERR("invalid port parameter %s\n", _src_port); +@@ -3355,8 +3367,9 @@ static int do_to_gw(struct sip_msg *_m, + sizeof(struct gw_info), comp_gws); + + /* Return result */ +- if((res != NULL) && ((transport == PROTO_NONE) +- || (res->transport_code == transport))) { ++ if((res != NULL) ++ && ((transport == PROTO_NONE) ++ || (res->transport_code == transport))) { + LM_DBG("request goes to gw\n"); + return 1; + } else { +--- a/src/modules/lcr/lcr_rpc.c ++++ b/src/modules/lcr/lcr_rpc.c +@@ -48,7 +48,8 @@ static void reload(rpc_t *rpc, void *c) + static const char *dump_gws_doc[2] = {"Dump the contents of lcr_gws table.", 0}; + + +-static void dump_gw(rpc_t *rpc, void *st, struct gw_info *gw, unsigned int gw_index, unsigned int lcr_id) ++static void dump_gw(rpc_t *rpc, void *st, struct gw_info *gw, ++ unsigned int gw_index, unsigned int lcr_id) + { + str scheme, gw_name, hostname, params, transport; + str prefix, tag; +@@ -72,14 +73,10 @@ static void dump_gw(rpc_t *rpc, void *st + break; + case AF_INET6: + rpc->struct_printf(st, "ip_addr", "%x:%x:%x:%x:%x:%x:%x:%x", +- gw->ip_addr.u.addr16[0], +- gw->ip_addr.u.addr16[1], +- gw->ip_addr.u.addr16[2], +- gw->ip_addr.u.addr16[3], +- gw->ip_addr.u.addr16[4], +- gw->ip_addr.u.addr16[5], +- gw->ip_addr.u.addr16[6], +- gw->ip_addr.u.addr16[7]); ++ gw->ip_addr.u.addr16[0], gw->ip_addr.u.addr16[1], ++ gw->ip_addr.u.addr16[2], gw->ip_addr.u.addr16[3], ++ gw->ip_addr.u.addr16[4], gw->ip_addr.u.addr16[5], ++ gw->ip_addr.u.addr16[6], gw->ip_addr.u.addr16[7]); + break; + case 0: + rpc->struct_add(st, "s", "ip_addr", "0.0.0.0"); +@@ -99,11 +96,10 @@ static void dump_gw(rpc_t *rpc, void *st + prefix.len = gw->prefix_len; + tag.s = gw->tag; + tag.len = gw->tag_len; +- start = int2strbuf( +- gw->defunct_until, &(buf[0]), INT2STR_MAX_LEN, &len); +- rpc->struct_add(st, "dSSdds", "strip", gw->strip, "prefix", +- &prefix, "tag", &tag, "flags", gw->flags, "state", +- gw->state, "defunct_until", start); ++ start = int2strbuf(gw->defunct_until, &(buf[0]), INT2STR_MAX_LEN, &len); ++ rpc->struct_add(st, "dSSdds", "strip", gw->strip, "prefix", &prefix, "tag", ++ &tag, "flags", gw->flags, "state", gw->state, "defunct_until", ++ start); + } + + static void dump_gws(rpc_t *rpc, void *c) +@@ -119,7 +115,7 @@ static void dump_gws(rpc_t *rpc, void *c + gws = gw_pt[j]; + + for(i = 1; i <= gws[0].ip_addr.u.addr32[0]; i++) { +- if (srec==NULL) { ++ if(srec == NULL) { + /* We create one array per lcr_id */ + if(rpc->add(c, "{", &rec) < 0) + return; +@@ -143,7 +139,7 @@ static void dump_rules(rpc_t *rpc, void + int i, j; + int _filter_by_prefix = 0; + int _lcr_id = 0; +- str _prefix = {NULL,0}; ++ str _prefix = {NULL, 0}; + struct rule_info **rules, *rule; + struct target *t; + void *rec = NULL; +@@ -151,29 +147,32 @@ static void dump_rules(rpc_t *rpc, void + void *st, *sst, *ssst; + str prefix, from_uri, request_uri; + +- if (rpc->scan(c, "d", &_lcr_id)>0) { +- if (rpc->scan(c, ".S", &_prefix)>0) { ++ if(rpc->scan(c, "d", &_lcr_id) > 0) { ++ if(rpc->scan(c, ".S", &_prefix) > 0) { + _filter_by_prefix = 1; + } + } + + for(j = 1; j <= lcr_count_param; j++) { + +- if (_lcr_id && _lcr_id!=j) continue; ++ if(_lcr_id && _lcr_id != j) ++ continue; + + rules = rule_pt[j]; + + for(i = 0; i < lcr_rule_hash_size_param; i++) { + rule = rules[i]; + while(rule) { +- if (_filter_by_prefix && _prefix.len && _prefix.s) { +- if (_prefix.len < rule->prefix_len || +- strncmp(_prefix.s, rule->prefix, rule->prefix_len)!=0) { ++ if(_filter_by_prefix && _prefix.len && _prefix.s) { ++ if(_prefix.len < rule->prefix_len ++ || strncmp(_prefix.s, rule->prefix, ++ rule->prefix_len) ++ != 0) { + rule = rule->next; + continue; + } + } +- if (srec==NULL) { ++ if(srec == NULL) { + /* We create one array per lcr_id */ + if(rpc->add(c, "{", &rec) < 0) + return; +@@ -192,11 +191,11 @@ static void dump_rules(rpc_t *rpc, void + rule->rule_id, "prefix", &prefix, "from_uri", &from_uri, + "request_uri", &request_uri, "stopper", rule->stopper); + t = rule->targets; +- if (t) { +- if (rpc->struct_add(st, "[", "gw", &sst) < 0) ++ if(t) { ++ if(rpc->struct_add(st, "[", "gw", &sst) < 0) + return; + while(t) { +- if (rpc->array_add(sst, "{", &ssst) < 0) ++ if(rpc->array_add(sst, "{", &ssst) < 0) + return; + rpc->struct_add(ssst, "ddd", "gw_index", t->gw_index, + "priority", t->priority, "weight", t->weight); +@@ -210,10 +209,10 @@ static void dump_rules(rpc_t *rpc, void + /* Mark the end of rule array */ + srec = NULL; + +- if (_filter_by_prefix) ++ if(_filter_by_prefix) + continue; + rule = rules[lcr_rule_hash_size_param]; +- if (rule) { ++ if(rule) { + if(rpc->struct_add(rec, "[", "prefix_len", &st) < 0) + return; + while(rule) { +@@ -222,7 +221,8 @@ static void dump_rules(rpc_t *rpc, void + } + } + } +- if (rec==NULL) rpc->fault(c, 404, "Empty reply"); ++ if(rec == NULL) ++ rpc->fault(c, 404, "Empty reply"); + } + + +@@ -269,8 +269,9 @@ static void load_gws(rpc_t *rpc, void *c + + ret = rpc->scan(c, "dS*SS", &lcr_id, &uri_user, &caller_uri, &request_uri); + if(ret == -1) { +- rpc->fault(c, 400, "parameter error; if using cli, remember to prefix " +- "numeric uri_user param value with 's:'"); ++ rpc->fault(c, 400, ++ "parameter error; if using cli, remember to prefix " ++ "numeric uri_user param value with 's:'"); + return; + } + +@@ -289,7 +290,7 @@ static void load_gws(rpc_t *rpc, void *c + + gws = gw_pt[lcr_id]; + for(j = 0; j < gw_count; j++) { +- if (rec==NULL) { ++ if(rec == NULL) { + if(rpc->add(c, "[", &rec) < 0) + return; + } diff --git a/net/kamailio/patches/021-lcr-typos.patch b/net/kamailio/patches/021-lcr-typos.patch new file mode 100644 index 000000000..4029f393f --- /dev/null +++ b/net/kamailio/patches/021-lcr-typos.patch @@ -0,0 +1,51 @@ +From 70a9ea2b1e5cceeaf050356e7baf00127a58567d Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?=D0=94=D0=B8=D0=BB=D1=8F=D0=BD=20=D0=9F=D0=B0=D0=BB=D0=B0?= + =?UTF-8?q?=D1=83=D0=B7=D0=BE=D0=B2?= +Date: Mon, 8 May 2023 13:13:49 +0200 +Subject: [PATCH] lcr: typos + +--- + src/modules/lcr/doc/lcr_admin.xml | 2 +- + src/modules/lcr/lcr_mod.c | 6 +++--- + 2 files changed, 4 insertions(+), 4 deletions(-) + +--- a/src/modules/lcr/doc/lcr_admin.xml ++++ b/src/modules/lcr/doc/lcr_admin.xml +@@ -1641,7 +1641,7 @@ if (to_any_gw("192.55.66.2", 1)) { + + Causes lcr module to dump the contents of its + in-memory lcr_rule and lcr_rule_target tables. +- Rules can be filetered by lcr_id or lcr_id and prefix. ++ Rules can be filtered by lcr_id or lcr_id and prefix. + The filters are passed as optional parameters. + + Parameters: +--- a/src/modules/lcr/lcr_mod.c ++++ b/src/modules/lcr/lcr_mod.c +@@ -188,7 +188,7 @@ unsigned int lcr_gw_count_param = DEF_LC + /* can gws be defuncted */ + static unsigned int defunct_capability_param = 0; + +-/* dont strip or tag param */ ++/* don't strip or tag param */ + static int dont_strip_or_prefix_flag_param = -1; + + /* ping related params */ +@@ -846,7 +846,7 @@ static int comp_matched(const void *m1, + if(mi1->priority < mi2->priority) + return 1; + if(mi1->priority == mi2->priority) { +- /* Sort by randomized weigth */ ++ /* Sort by randomized weight */ + if(mi1->weight > mi2->weight) + return 1; + if(mi1->weight == mi2->weight) +@@ -863,7 +863,7 @@ static int comp_matched(const void *m1, + if(mi1->priority < mi2->priority) + return 1; + if(mi1->priority == mi2->priority) { +- /* Sort by randomized weigth */ ++ /* Sort by randomized weight */ + if(mi1->weight > mi2->weight) + return 1; + if(mi1->weight == mi2->weight) diff --git a/net/kamailio/patches/022-lcr-pcre2-migration.patch b/net/kamailio/patches/022-lcr-pcre2-migration.patch new file mode 100644 index 000000000..c894e3a01 --- /dev/null +++ b/net/kamailio/patches/022-lcr-pcre2-migration.patch @@ -0,0 +1,508 @@ +From e3e2c41e8c46a13bad18dd40fd9e3540020dd5eb Mon Sep 17 00:00:00 2001 +From: Victor Seva +Date: Mon, 21 Aug 2023 13:30:36 +0200 +Subject: [PATCH] lcr: pcre2 migration + +--- + src/modules/lcr/Makefile | 12 +-- + src/modules/lcr/hash.c | 24 ++--- + src/modules/lcr/hash.h | 10 +- + src/modules/lcr/lcr_mod.c | 187 +++++++++++++++++++++++++------------- + src/modules/lcr/lcr_mod.h | 8 +- + 5 files changed, 150 insertions(+), 91 deletions(-) + +--- a/src/modules/lcr/Makefile ++++ b/src/modules/lcr/Makefile +@@ -9,20 +9,15 @@ auto_gen= + NAME=lcr.so + + ifeq ($(CROSS_COMPILE),) +-PCRE_BUILDER = $(shell \ +- if pkg-config --exists libcre; then \ +- echo 'pkg-config libpcre'; \ +- else \ +- which pcre-config; \ +- fi) ++PCRE_BUILDER = $(shell command -v pcre2-config) + endif + + ifeq ($(PCRE_BUILDER),) + PCREDEFS=-I$(LOCALBASE)/include +- PCRELIBS=-L$(LOCALBASE)/lib -lpcre ++ PCRELIBS=-L$(LOCALBASE)/lib -lpcre2-8 + else + PCREDEFS = $(shell $(PCRE_BUILDER) --cflags) +- PCRELIBS = $(shell $(PCRE_BUILDER) --libs) ++ PCRELIBS = $(shell $(PCRE_BUILDER) --libs8) + endif + + DEFS+=$(PCREDEFS) +@@ -31,4 +26,3 @@ LIBS+=$(PCRELIBS) + SERLIBPATH=../../lib + SER_LIBS+=$(SERLIBPATH)/srdb1/srdb1 + include ../../Makefile.modules +- +--- a/src/modules/lcr/hash.c ++++ b/src/modules/lcr/hash.c +@@ -15,8 +15,8 @@ + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * +- * You should have received a copy of the GNU General Public License +- * along with this program; if not, write to the Free Software ++ * You should have received a copy of the GNU General Public License ++ * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +@@ -36,10 +36,10 @@ + /* Add lcr entry into hash table */ + int rule_hash_table_insert(struct rule_info **hash_table, unsigned int lcr_id, + unsigned int rule_id, unsigned short prefix_len, char *prefix, +- unsigned short from_uri_len, char *from_uri, pcre *from_uri_re, ++ unsigned short from_uri_len, char *from_uri, pcre2_code *from_uri_re, + unsigned short mt_tvalue_len, char *mt_tvalue, +- unsigned short request_uri_len, char *request_uri, pcre *request_uri_re, +- unsigned short stopper) ++ unsigned short request_uri_len, char *request_uri, ++ pcre2_code *request_uri_re, unsigned short stopper) + { + struct rule_info *rule; + str prefix_str; +@@ -50,9 +50,9 @@ int rule_hash_table_insert(struct rule_i + if(rule == NULL) { + SHM_MEM_ERROR_FMT("for rule hash table entry\n"); + if(from_uri_re) +- shm_free(from_uri_re); ++ pcre2_code_free(from_uri_re); + if(request_uri_re) +- shm_free(request_uri_re); ++ pcre2_code_free(request_uri_re); + return 0; + } + memset(rule, 0, sizeof(struct rule_info)); +@@ -99,9 +99,9 @@ int rule_hash_table_insert(struct rule_i + if(rid == NULL) { + PKG_MEM_ERROR_FMT("for rule_id hash table entry\n"); + if(from_uri_re) +- shm_free(from_uri_re); ++ pcre2_code_free(from_uri_re); + if(request_uri_re) +- shm_free(request_uri_re); ++ pcre2_code_free(request_uri_re); + shm_free(rule); + return 0; + } +@@ -180,7 +180,7 @@ int rule_hash_table_insert_target(struct + } + + +-/* ++/* + * Return pointer to lcr hash table entry to which given prefix hashes to. + */ + struct rule_info *rule_hash_table_lookup( +@@ -209,10 +209,10 @@ void rule_hash_table_contents_free(struc + r = hash_table[i]; + while(r) { + if(r->from_uri_re) { +- shm_free(r->from_uri_re); ++ pcre2_code_free(r->from_uri_re); + } + if(r->request_uri_re) +- shm_free(r->request_uri_re); ++ pcre2_code_free(r->request_uri_re); + t = r->targets; + while(t) { + next_t = t->next; +--- a/src/modules/lcr/hash.h ++++ b/src/modules/lcr/hash.h +@@ -15,8 +15,8 @@ + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * +- * You should have received a copy of the GNU General Public License +- * along with this program; if not, write to the Free Software ++ * You should have received a copy of the GNU General Public License ++ * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +@@ -34,10 +34,10 @@ + + int rule_hash_table_insert(struct rule_info **hash_table, unsigned int lcr_id, + unsigned int rule_id, unsigned short prefix_len, char *prefix, +- unsigned short from_uri_len, char *from_uri, pcre *from_uri_re, ++ unsigned short from_uri_len, char *from_uri, pcre2_code *from_uri_re, + unsigned short mt_tvalue_len, char *mt_tvalue, +- unsigned short request_uri_len, char *request_uri, pcre *request_uri_re, +- unsigned short stopper); ++ unsigned short request_uri_len, char *request_uri, ++ pcre2_code *request_uri_re, unsigned short stopper); + + int rule_hash_table_insert_target(struct rule_info **hash_table, + struct gw_info *gws, unsigned int rule_id, unsigned int gw_id, +--- a/src/modules/lcr/lcr_mod.c ++++ b/src/modules/lcr/lcr_mod.c +@@ -16,8 +16,8 @@ + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * +- * You should have received a copy of the GNU General Public License +- * along with this program; if not, write to the Free Software ++ * You should have received a copy of the GNU General Public License ++ * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + */ +@@ -43,7 +43,8 @@ + #include + #include + #include +-#include ++#define PCRE2_CODE_UNIT_WIDTH 8 ++#include + #include "../../core/locking.h" + #include "../../core/sr_module.h" + #include "../../core/dprint.h" +@@ -204,6 +205,9 @@ static unsigned int priority_ordering_pa + /* mtree tree name */ + str mtree_param = {"lcr", 3}; + ++static pcre2_general_context *lcr_gctx = NULL; ++static pcre2_compile_context *lcr_ctx = NULL; ++ + /* + * Other module types and variables + */ +@@ -364,7 +368,7 @@ static param_export_t params[] = { + * Module interface + */ + struct module_exports exports = { +- "lcr", ++ "lcr", + DEFAULT_DLFLAGS, /* dlopen flags */ + cmds, /* Exported functions */ + params, /* Exported parameters */ +@@ -422,6 +426,16 @@ static void lcr_db_close(void) + } + } + ++static void *pcre2_malloc(size_t size, void *ext) ++{ ++ return shm_malloc(size); ++} ++ ++static void pcre2_free(void *ptr, void *ext) ++{ ++ shm_free(ptr); ++ ptr = NULL; ++} + + /* + * Module initialization function that is called before the main process forks +@@ -703,7 +717,15 @@ static int mod_init(void) + lcr_db_close(); + + /* rule shared memory */ +- ++ if((lcr_gctx = pcre2_general_context_create(pcre2_malloc, pcre2_free, NULL)) ++ == NULL) { ++ LM_ERR("pcre2 general context creation failed\n"); ++ goto err; ++ } ++ if((lcr_ctx = pcre2_compile_context_create(lcr_gctx)) == NULL) { ++ LM_ERR("pcre2 compile context creation failed\n"); ++ goto err; ++ } + /* rule hash table pointer table */ + /* pointer at index 0 points to temp rule hash table */ + rule_pt = (struct rule_info ***)shm_malloc( +@@ -779,6 +801,12 @@ dberror: + lcr_db_close(); + + err: ++ if(lcr_ctx) { ++ pcre2_compile_context_free(lcr_ctx); ++ } ++ if(lcr_gctx) { ++ pcre2_general_context_free(lcr_gctx); ++ } + free_shared_memory(); + return -1; + } +@@ -794,7 +822,12 @@ static int child_init(int rank) + static void destroy(void) + { + lcr_db_close(); +- ++ if(lcr_ctx) { ++ pcre2_compile_context_free(lcr_ctx); ++ } ++ if(lcr_gctx) { ++ pcre2_general_context_free(lcr_gctx); ++ } + free_shared_memory(); + } + +@@ -875,33 +908,32 @@ static int comp_matched(const void *m1, + + + /* Compile pattern into shared memory and return pointer to it. */ +-static pcre *reg_ex_comp(const char *pattern) ++static pcre2_code *reg_ex_comp(const char *pattern) + { +- pcre *re, *result; +- const char *error; +- int rc, err_offset; +- size_t size; +- +- re = pcre_compile(pattern, 0, &error, &err_offset, NULL); +- if(re == NULL) { +- LM_ERR("pcre compilation of '%s' failed at offset %d: %s\n", pattern, +- err_offset, error); +- return (pcre *)0; +- } +- rc = pcre_fullinfo(re, NULL, PCRE_INFO_SIZE, &size); +- if(rc != 0) { +- LM_ERR("pcre_fullinfo on compiled pattern '%s' yielded error: %d\n", +- pattern, rc); +- return (pcre *)0; +- } +- result = (pcre *)shm_malloc(size); ++ pcre2_code *result; ++ int pcre_error_num = 0; ++ char pcre_error[128]; ++ size_t pcre_erroffset; ++ ++ result = pcre2_compile((PCRE2_SPTR)pattern, PCRE2_ZERO_TERMINATED, 0, ++ &pcre_error_num, &pcre_erroffset, lcr_ctx); + if(result == NULL) { +- pcre_free(re); +- SHM_MEM_ERROR_FMT("for compiled PCRE pattern\n"); +- return (pcre *)0; ++ switch(pcre2_get_error_message( ++ pcre_error_num, (PCRE2_UCHAR *)pcre_error, 128)) { ++ case PCRE2_ERROR_NOMEMORY: ++ snprintf(pcre_error, 128, ++ "unknown error[%d]: pcre2 error buffer too small", ++ pcre_error_num); ++ break; ++ case PCRE2_ERROR_BADDATA: ++ snprintf(pcre_error, 128, "unknown pcre2 error[%d]", ++ pcre_error_num); ++ break; ++ } ++ LM_ERR("pcre compilation of '%s' failed at offset %zu: %s\n", pattern, ++ pcre_erroffset, pcre_error); ++ return NULL; + } +- memcpy(result, re, size); +- pcre_free(re); + return result; + } + +@@ -950,7 +982,7 @@ static struct gw_info *find_gateway_by_i + return NULL; + } + +-/* ++/* + * Insert gw info into index i or gws table + */ + static int insert_gw(struct gw_info *gws, unsigned int i, unsigned int gw_id, +@@ -1024,7 +1056,7 @@ static int insert_gw(struct gw_info *gws + + + /* +- * Insert prefix_len into list pointed by last rule hash table entry ++ * Insert prefix_len into list pointed by last rule hash table entry + * if not there already. Keep list in decending prefix_len order. + */ + static int prefix_len_insert( +@@ -1414,7 +1446,7 @@ int reload_tables() + db_key_t gw_cols[13]; + db_key_t rule_cols[7]; + db_key_t target_cols[4]; +- pcre *from_uri_re, *request_uri_re; ++ pcre2_code *from_uri_re, *request_uri_re; + struct gw_info *gws, *gw_pt_tmp; + struct rule_info **rules, **rule_pt_tmp; + +@@ -2129,11 +2161,12 @@ void add_gws_into_avps(struct gw_info *g + int load_gws_dummy(int lcr_id, str *ruri_user, str *from_uri, str *request_uri, + unsigned int *gw_indexes) + { +- int i, j; ++ int i, j, rc; + unsigned int gw_index, now, dex; + struct rule_info **rules, *rule, *pl; + struct gw_info *gws; + struct target *t; ++ pcre2_match_data *pcre_md = NULL; + struct matched_gw_info matched_gws[MAX_NO_OF_GWS + 1]; + struct sip_uri furi; + struct usr_avp *avp; +@@ -2178,12 +2211,18 @@ int load_gws_dummy(int lcr_id, str *ruri + || strncmp(rule->prefix, ruri_user->s, pl->prefix_len)) + goto next; + +- if((rule->from_uri_len != 0) +- && (pcre_exec(rule->from_uri_re, NULL, from_uri->s, +- from_uri->len, 0, 0, NULL, 0) +- < 0)) +- goto next; +- ++ if(rule->from_uri_len != 0) { ++ pcre_md = pcre2_match_data_create_from_pattern( ++ rule->from_uri_re, NULL); ++ rc = pcre2_match(rule->from_uri_re, (PCRE2_SPTR)from_uri->s, ++ (PCRE2_SIZE)from_uri->len, 0, 0, pcre_md, NULL); ++ if(pcre_md) { ++ pcre2_match_data_free(pcre_md); ++ pcre_md = NULL; ++ } ++ if(rc < 0) ++ goto next; ++ } + if((from_uri->len > 0) && (rule->mt_tvalue_len > 0)) { + if(mtree_api.mt_match(&msg, &mtree_param, &(furi.user), 2) + == -1) { +@@ -2216,9 +2255,16 @@ int load_gws_dummy(int lcr_id, str *ruri + "param has not been given.\n"); + return -1; + } +- if(pcre_exec(rule->request_uri_re, NULL, request_uri->s, +- request_uri->len, 0, 0, NULL, 0) +- < 0) ++ pcre_md = pcre2_match_data_create_from_pattern( ++ rule->request_uri_re, NULL); ++ rc = pcre2_match(rule->request_uri_re, ++ (PCRE2_SPTR)request_uri->s, ++ (PCRE2_SIZE)request_uri->len, 0, 0, pcre_md, NULL); ++ if(pcre_md) { ++ pcre2_match_data_free(pcre_md); ++ pcre_md = NULL; ++ } ++ if(rc < 0) + goto next; + } + +@@ -2282,9 +2328,10 @@ static int ki_load_gws_furi( + sip_msg_t *_m, int lcr_id, str *ruri_user, str *from_uri) + { + str *request_uri; +- int i, j; ++ int i, j, rc; + unsigned int gw_index, now, dex; + int_str val; ++ pcre2_match_data *pcre_md = NULL; + struct matched_gw_info matched_gws[MAX_NO_OF_GWS + 1]; + struct rule_info **rules, *rule, *pl; + struct gw_info *gws; +@@ -2343,14 +2390,22 @@ static int ki_load_gws_furi( + goto next; + + /* Match from uri */ +- if((rule->from_uri_len != 0) +- && (pcre_exec(rule->from_uri_re, NULL, from_uri->s, +- from_uri->len, 0, 0, NULL, 0) +- < 0)) { +- LM_DBG("from uri <%.*s> did not match to from regex <%.*s>\n", +- from_uri->len, from_uri->s, rule->from_uri_len, +- rule->from_uri); +- goto next; ++ if(rule->from_uri_len != 0) { ++ pcre_md = pcre2_match_data_create_from_pattern( ++ rule->from_uri_re, NULL); ++ rc = pcre2_match(rule->from_uri_re, (PCRE2_SPTR)from_uri->s, ++ (PCRE2_SIZE)from_uri->len, 0, 0, pcre_md, NULL); ++ if(pcre_md) { ++ pcre2_match_data_free(pcre_md); ++ pcre_md = NULL; ++ } ++ if(rc < 0) { ++ LM_DBG("from uri <%.*s> did not match to from regex " ++ "<%.*s>\n", ++ from_uri->len, from_uri->s, rule->from_uri_len, ++ rule->from_uri); ++ goto next; ++ } + } + + /* Match from uri user */ +@@ -2379,15 +2434,23 @@ static int ki_load_gws_furi( + } + + /* Match request uri */ +- if((rule->request_uri_len != 0) +- && (pcre_exec(rule->request_uri_re, NULL, request_uri->s, +- request_uri->len, 0, 0, NULL, 0) +- < 0)) { +- LM_DBG("request uri <%.*s> did not match to request regex " +- "<%.*s>\n", +- request_uri->len, request_uri->s, rule->request_uri_len, +- rule->request_uri); +- goto next; ++ if(rule->request_uri_len != 0) { ++ pcre_md = pcre2_match_data_create_from_pattern( ++ rule->request_uri_re, NULL); ++ rc = pcre2_match(rule->request_uri_re, ++ (PCRE2_SPTR)request_uri->s, ++ (PCRE2_SIZE)request_uri->len, 0, 0, pcre_md, NULL); ++ if(pcre_md) { ++ pcre2_match_data_free(pcre_md); ++ pcre_md = NULL; ++ } ++ if(rc < 0) { ++ LM_DBG("request uri <%.*s> did not match to request regex " ++ "<%.*s>\n", ++ request_uri->len, request_uri->s, ++ rule->request_uri_len, rule->request_uri); ++ goto next; ++ } + } + + /* Load gws associated with this rule */ +@@ -3015,7 +3078,7 @@ static int ki_next_gw(sip_msg_t *_m) + } + + /** +- * ++ * + */ + static int next_gw(struct sip_msg *_m, char *_s1, char *_s2) + { +--- a/src/modules/lcr/lcr_mod.h ++++ b/src/modules/lcr/lcr_mod.h +@@ -2,6 +2,7 @@ + * Various lcr related constant, types, and external variables + * + * Copyright (C) 2005-2014 Juha Heinanen ++ * Copyright (C) 2023 Victor Seva + * + * This file is part of Kamailio, a free SIP server. + * +@@ -33,7 +34,8 @@ + #define LCR_MOD_H + + #include +-#include ++#define PCRE2_CODE_UNIT_WIDTH 8 ++#include + #include "../../core/locking.h" + #include "../../core/parser/parse_uri.h" + #include "../../core/ip_addr.h" +@@ -60,10 +62,10 @@ struct rule_info + unsigned short from_uri_len; + char mt_tvalue[MAX_MT_TVALUE_LEN + 1]; + unsigned short mt_tvalue_len; +- pcre *from_uri_re; ++ pcre2_code *from_uri_re; + char request_uri[MAX_URI_LEN + 1]; + unsigned short request_uri_len; +- pcre *request_uri_re; ++ pcre2_code *request_uri_re; + unsigned short stopper; + unsigned int enabled; + struct target *targets; diff --git a/net/kamailio/patches/030-regex-clang-format-for-coherent-indentation-and-codi.patch b/net/kamailio/patches/030-regex-clang-format-for-coherent-indentation-and-codi.patch new file mode 100644 index 000000000..485fa69c1 --- /dev/null +++ b/net/kamailio/patches/030-regex-clang-format-for-coherent-indentation-and-codi.patch @@ -0,0 +1,715 @@ +From fb7c59cafceb35628d40c727dbfa2990335b922a Mon Sep 17 00:00:00 2001 +From: Victor Seva +Date: Wed, 17 May 2023 16:37:10 +0200 +Subject: [PATCH] regex: clang-format for coherent indentation and coding style + +--- + src/modules/regex/regex_mod.c | 313 ++++++++++++++++------------------ + 1 file changed, 150 insertions(+), 163 deletions(-) + +--- a/src/modules/regex/regex_mod.c ++++ b/src/modules/regex/regex_mod.c +@@ -49,9 +49,9 @@ MODULE_VERSION + #define START 0 + #define RELOAD 1 + +-#define FILE_MAX_LINE 500 /*!< Max line size in the file */ +-#define MAX_GROUPS 20 /*!< Max number of groups */ +-#define GROUP_MAX_SIZE 8192 /*!< Max size of a group */ ++#define FILE_MAX_LINE 500 /*!< Max line size in the file */ ++#define MAX_GROUPS 20 /*!< Max number of groups */ ++#define GROUP_MAX_SIZE 8192 /*!< Max size of a group */ + + + static int regex_init_rpc(void); +@@ -66,12 +66,12 @@ gen_lock_t *reload_lock; + * Module exported parameter variables + */ + static char *file; +-static int max_groups = MAX_GROUPS; +-static int group_max_size = GROUP_MAX_SIZE; +-static int pcre_caseless = 0; +-static int pcre_multiline = 0; +-static int pcre_dotall = 0; +-static int pcre_extended = 0; ++static int max_groups = MAX_GROUPS; ++static int group_max_size = GROUP_MAX_SIZE; ++static int pcre_caseless = 0; ++static int pcre_multiline = 0; ++static int pcre_dotall = 0; ++static int pcre_extended = 0; + + + /* +@@ -100,119 +100,117 @@ static void free_shared_memory(void); + /* + * Script functions + */ +-static int w_pcre_match(struct sip_msg* _msg, char* _s1, char* _s2); +-static int w_pcre_match_group(struct sip_msg* _msg, char* _s1, char* _s2); ++static int w_pcre_match(struct sip_msg *_msg, char *_s1, char *_s2); ++static int w_pcre_match_group(struct sip_msg *_msg, char *_s1, char *_s2); + + + /* + * Exported functions + */ +-static cmd_export_t cmds[] = +-{ +- { "pcre_match", (cmd_function)w_pcre_match, 2, fixup_spve_spve, 0, +- REQUEST_ROUTE|FAILURE_ROUTE|ONREPLY_ROUTE|BRANCH_ROUTE|LOCAL_ROUTE }, +- { "pcre_match_group", (cmd_function)w_pcre_match_group, 2, fixup_spve_spve, 0, +- REQUEST_ROUTE|FAILURE_ROUTE|ONREPLY_ROUTE|BRANCH_ROUTE|LOCAL_ROUTE }, +- { "pcre_match_group", (cmd_function)w_pcre_match_group, 1, fixup_spve_null, 0, +- REQUEST_ROUTE|FAILURE_ROUTE|ONREPLY_ROUTE|BRANCH_ROUTE|LOCAL_ROUTE }, +- { 0, 0, 0, 0, 0, 0 } +-}; ++static cmd_export_t cmds[] = { ++ {"pcre_match", (cmd_function)w_pcre_match, 2, fixup_spve_spve, 0, ++ REQUEST_ROUTE | FAILURE_ROUTE | ONREPLY_ROUTE | BRANCH_ROUTE ++ | LOCAL_ROUTE}, ++ {"pcre_match_group", (cmd_function)w_pcre_match_group, 2, ++ fixup_spve_spve, 0, ++ REQUEST_ROUTE | FAILURE_ROUTE | ONREPLY_ROUTE | BRANCH_ROUTE ++ | LOCAL_ROUTE}, ++ {"pcre_match_group", (cmd_function)w_pcre_match_group, 1, ++ fixup_spve_null, 0, ++ REQUEST_ROUTE | FAILURE_ROUTE | ONREPLY_ROUTE | BRANCH_ROUTE ++ | LOCAL_ROUTE}, ++ {0, 0, 0, 0, 0, 0}}; + + + /* + * Exported parameters + */ +-static param_export_t params[] = { +- {"file", PARAM_STRING, &file }, +- {"max_groups", INT_PARAM, &max_groups }, +- {"group_max_size", INT_PARAM, &group_max_size }, +- {"pcre_caseless", INT_PARAM, &pcre_caseless }, +- {"pcre_multiline", INT_PARAM, &pcre_multiline }, +- {"pcre_dotall", INT_PARAM, &pcre_dotall }, +- {"pcre_extended", INT_PARAM, &pcre_extended }, +- {0, 0, 0} +-}; ++static param_export_t params[] = {{"file", PARAM_STRING, &file}, ++ {"max_groups", INT_PARAM, &max_groups}, ++ {"group_max_size", INT_PARAM, &group_max_size}, ++ {"pcre_caseless", INT_PARAM, &pcre_caseless}, ++ {"pcre_multiline", INT_PARAM, &pcre_multiline}, ++ {"pcre_dotall", INT_PARAM, &pcre_dotall}, ++ {"pcre_extended", INT_PARAM, &pcre_extended}, {0, 0, 0}}; + + + /* + * Module interface + */ + struct module_exports exports = { +- "regex", /*!< module name */ +- DEFAULT_DLFLAGS, /*!< dlopen flags */ +- cmds, /*!< exported functions */ +- params, /*!< exported parameters */ +- 0, /*!< exported RPC functions */ +- 0, /*!< exported pseudo-variables */ +- 0, /*!< response handling function */ +- mod_init, /*!< module initialization function */ +- 0, /*!< per-child init function */ +- destroy /*!< destroy function */ ++ "regex", /*!< module name */ ++ DEFAULT_DLFLAGS, /*!< dlopen flags */ ++ cmds, /*!< exported functions */ ++ params, /*!< exported parameters */ ++ 0, /*!< exported RPC functions */ ++ 0, /*!< exported pseudo-variables */ ++ 0, /*!< response handling function */ ++ mod_init, /*!< module initialization function */ ++ 0, /*!< per-child init function */ ++ destroy /*!< destroy function */ + }; + + +- + /*! \brief + * Init module function + */ + static int mod_init(void) + { +- if(regex_init_rpc()<0) +- { ++ if(regex_init_rpc() < 0) { + LM_ERR("failed to register RPC commands\n"); + return -1; + } + + /* Group matching feature */ +- if (file == NULL) { ++ if(file == NULL) { + LM_NOTICE("'file' parameter is not set, group matching disabled\n"); + } else { + /* Create and init the lock */ + reload_lock = lock_alloc(); +- if (reload_lock == NULL) { ++ if(reload_lock == NULL) { + LM_ERR("cannot allocate reload_lock\n"); + goto err; + } +- if (lock_init(reload_lock) == NULL) { ++ if(lock_init(reload_lock) == NULL) { + LM_ERR("cannot init the reload_lock\n"); + lock_dealloc(reload_lock); + goto err; + } + + /* PCRE options */ +- if (pcre_caseless != 0) { ++ if(pcre_caseless != 0) { + LM_DBG("PCRE CASELESS enabled\n"); + pcre_options = pcre_options | PCRE_CASELESS; + } +- if (pcre_multiline != 0) { ++ if(pcre_multiline != 0) { + LM_DBG("PCRE MULTILINE enabled\n"); + pcre_options = pcre_options | PCRE_MULTILINE; + } +- if (pcre_dotall != 0) { ++ if(pcre_dotall != 0) { + LM_DBG("PCRE DOTALL enabled\n"); + pcre_options = pcre_options | PCRE_DOTALL; + } +- if (pcre_extended != 0) { ++ if(pcre_extended != 0) { + LM_DBG("PCRE EXTENDED enabled\n"); + pcre_options = pcre_options | PCRE_EXTENDED; + } + LM_DBG("PCRE options: %i\n", pcre_options); + + /* Pointer to pcres */ +- if ((pcres_addr = shm_malloc(sizeof(pcre **))) == 0) { ++ if((pcres_addr = shm_malloc(sizeof(pcre **))) == 0) { + LM_ERR("no memory for pcres_addr\n"); + goto err; + } + + /* Integer containing the number of pcres */ +- if ((num_pcres = shm_malloc(sizeof(int))) == 0) { ++ if((num_pcres = shm_malloc(sizeof(int))) == 0) { + LM_ERR("no memory for num_pcres\n"); + goto err; + } + + /* Load the pcres */ + LM_DBG("loading pcres...\n"); +- if (load_pcres(START)) { ++ if(load_pcres(START)) { + LM_ERR("failed to load pcres\n"); + goto err; + } +@@ -251,21 +249,21 @@ static int load_pcres(int action) + /* Get the lock */ + lock_get(reload_lock); + +- if (!(f = fopen(file, "r"))) { ++ if(!(f = fopen(file, "r"))) { + LM_ERR("could not open file '%s'\n", file); + goto err; + } + + /* Array containing each pattern in the file */ +- if ((patterns = pkg_malloc(sizeof(char*) * max_groups)) == 0) { ++ if((patterns = pkg_malloc(sizeof(char *) * max_groups)) == 0) { + LM_ERR("no more memory for patterns\n"); + fclose(f); + goto err; + } +- memset(patterns, 0, sizeof(char*) * max_groups); ++ memset(patterns, 0, sizeof(char *) * max_groups); + +- for (i=0; i= max_groups) { ++ if(i >= max_groups) { + LM_ERR("max patterns exceeded\n"); + fclose(f); + goto err; +@@ -309,14 +308,14 @@ static int load_pcres(int action) + + llen = strlen(line); + /* Check if the patter size is too big (aprox) */ +- if (strlen(patterns[i]) + llen >= group_max_size - 4) { ++ if(strlen(patterns[i]) + llen >= group_max_size - 4) { + LM_ERR("pattern max file exceeded\n"); + fclose(f); + goto err; + } + + /* Append ')' at the end of the line */ +- if (line[llen - 1] == '\n') { ++ if(line[llen - 1] == '\n') { + line[llen - 1] = ')'; + line[llen] = '\n'; + line[llen + 1] = '\0'; +@@ -328,7 +327,7 @@ static int load_pcres(int action) + + /* Append '(' at the beginning of the line */ + llen = strlen(patterns[i]); +- memcpy(patterns[i]+llen, "(", 1); ++ memcpy(patterns[i] + llen, "(", 1); + llen++; + + /* Append the line to the current pattern (including the ending 0) */ +@@ -340,16 +339,16 @@ static int load_pcres(int action) + + fclose(f); + +- if(num_pcres_tmp==0) { ++ if(num_pcres_tmp == 0) { + LM_ERR("no expressions in the file\n"); + goto err; + } + + /* Fix the patterns */ +- for (i=0; i < num_pcres_tmp; i++) { ++ for(i = 0; i < num_pcres_tmp; i++) { + + /* Convert empty groups in unmatcheable regular expression ^$ */ +- if (strlen(patterns[i]) == 1) { ++ if(strlen(patterns[i]) == 1) { + patterns[i][0] = '^'; + patterns[i][1] = '$'; + patterns[i][2] = '\0'; +@@ -357,13 +356,13 @@ static int load_pcres(int action) + } + + /* Delete possible '\n' at the end of the pattern */ +- if (patterns[i][strlen(patterns[i])-1] == '\n') { +- patterns[i][strlen(patterns[i])-1] = '\0'; ++ if(patterns[i][strlen(patterns[i]) - 1] == '\n') { ++ patterns[i][strlen(patterns[i]) - 1] = '\0'; + } + + /* Replace '\n' with '|' (except at the end of the pattern) */ +- for (j=0; j < strlen(patterns[i]); j++) { +- if (patterns[i][j] == '\n' && j != strlen(patterns[i])-1) { ++ for(j = 0; j < strlen(patterns[i]); j++) { ++ if(patterns[i][j] == '\n' && j != strlen(patterns[i]) - 1) { + patterns[i][j] = '|'; + } + } +@@ -374,38 +373,38 @@ static int load_pcres(int action) + + /* Log the group patterns */ + LM_INFO("num groups = %d\n", num_pcres_tmp); +- for (i=0; i < num_pcres_tmp; i++) { +- LM_INFO("%s (size = %i)\n", i, patterns[i], +- i, (int)strlen(patterns[i])); ++ for(i = 0; i < num_pcres_tmp; i++) { ++ LM_INFO("%s (size = %i)\n", i, patterns[i], i, ++ (int)strlen(patterns[i])); + } + + /* Temporal pointer of pcres */ +- if ((pcres_tmp = pkg_malloc(sizeof(pcre *) * num_pcres_tmp)) == 0) { ++ if((pcres_tmp = pkg_malloc(sizeof(pcre *) * num_pcres_tmp)) == 0) { + LM_ERR("no more memory for pcres_tmp\n"); + goto err; + } +- for (i=0; is, pcre_options, &pcre_error, &pcre_erroffset, NULL); +- if (pcre_re == NULL) { ++ pcre_re = pcre_compile( ++ regex->s, pcre_options, &pcre_error, &pcre_erroffset, NULL); ++ if(pcre_re == NULL) { + LM_ERR("pcre_re compilation of '%s' failed at offset %d: %s\n", + regex->s, pcre_erroffset, pcre_error); + return -4; + } + +- pcre_rc = pcre_exec( +- pcre_re, /* the compiled pattern */ +- NULL, /* no extra data - we didn't study the pattern */ +- string->s, /* the matching string */ +- (int)(string->len), /* the length of the subject */ +- 0, /* start at offset 0 in the string */ +- 0, /* default options */ +- NULL, /* output vector for substring information */ +- 0); /* number of elements in the output vector */ ++ pcre_rc = pcre_exec(pcre_re, /* the compiled pattern */ ++ NULL, /* no extra data - we didn't study the pattern */ ++ string->s, /* the matching string */ ++ (int)(string->len), /* the length of the subject */ ++ 0, /* start at offset 0 in the string */ ++ 0, /* default options */ ++ NULL, /* output vector for substring information */ ++ 0); /* number of elements in the output vector */ + + /* Matching failed: handle error cases */ +- if (pcre_rc < 0) { ++ if(pcre_rc < 0) { + switch(pcre_rc) { + case PCRE_ERROR_NOMATCH: + LM_DBG("'%s' doesn't match '%s'\n", string->s, regex->s); +@@ -562,28 +561,26 @@ static int ki_pcre_match(sip_msg_t* msg, + } + + /*! \brief Return true if the argument matches the regular expression parameter */ +-static int w_pcre_match(struct sip_msg* _msg, char* _s1, char* _s2) ++static int w_pcre_match(struct sip_msg *_msg, char *_s1, char *_s2) + { + str string; + str regex; + +- if (_s1 == NULL) { ++ if(_s1 == NULL) { + LM_ERR("bad parameters\n"); + return -2; + } + +- if (_s2 == NULL) { ++ if(_s2 == NULL) { + LM_ERR("bad parameters\n"); + return -2; + } + +- if (fixup_get_svalue(_msg, (gparam_p)_s1, &string)) +- { ++ if(fixup_get_svalue(_msg, (gparam_p)_s1, &string)) { + LM_ERR("cannot print the format for string\n"); + return -3; + } +- if (fixup_get_svalue(_msg, (gparam_p)_s2, ®ex)) +- { ++ if(fixup_get_svalue(_msg, (gparam_p)_s2, ®ex)) { + LM_ERR("cannot print the format for regex\n"); + return -3; + } +@@ -592,17 +589,17 @@ static int w_pcre_match(struct sip_msg* + } + + /*! \brief Return true if the string argument matches the pattern group parameter */ +-static int ki_pcre_match_group(sip_msg_t* _msg, str* string, int num_pcre) ++static int ki_pcre_match_group(sip_msg_t *_msg, str *string, int num_pcre) + { + int pcre_rc; + + /* Check if group matching feature is enabled */ +- if (file == NULL) { ++ if(file == NULL) { + LM_ERR("group matching is disabled\n"); + return -2; + } + +- if (num_pcre >= *num_pcres) { ++ if(num_pcre >= *num_pcres) { + LM_ERR("invalid pcre index '%i', there are %i pcres\n", num_pcre, + *num_pcres); + return -4; +@@ -610,20 +607,19 @@ static int ki_pcre_match_group(sip_msg_t + + lock_get(reload_lock); + +- pcre_rc = pcre_exec( +- (*pcres_addr)[num_pcre], /* the compiled pattern */ +- NULL, /* no extra data - we didn't study the pattern */ +- string->s, /* the matching string */ +- (int)(string->len), /* the length of the subject */ +- 0, /* start at offset 0 in the string */ +- 0, /* default options */ +- NULL, /* output vector for substring information */ +- 0); /* number of elements in the output vector */ ++ pcre_rc = pcre_exec((*pcres_addr)[num_pcre], /* the compiled pattern */ ++ NULL, /* no extra data - we didn't study the pattern */ ++ string->s, /* the matching string */ ++ (int)(string->len), /* the length of the subject */ ++ 0, /* start at offset 0 in the string */ ++ 0, /* default options */ ++ NULL, /* output vector for substring information */ ++ 0); /* number of elements in the output vector */ + + lock_release(reload_lock); + + /* Matching failed: handle error cases */ +- if (pcre_rc < 0) { ++ if(pcre_rc < 0) { + switch(pcre_rc) { + case PCRE_ERROR_NOMATCH: + LM_DBG("'%s' doesn't match pcres[%i]\n", string->s, num_pcre); +@@ -640,29 +636,27 @@ static int ki_pcre_match_group(sip_msg_t + } + + /*! \brief Return true if the string argument matches the pattern group parameter */ +-static int w_pcre_match_group(struct sip_msg* _msg, char* _s1, char* _s2) ++static int w_pcre_match_group(struct sip_msg *_msg, char *_s1, char *_s2) + { + str string, group; + unsigned int num_pcre = 0; + +- if (_s1 == NULL) { ++ if(_s1 == NULL) { + LM_ERR("bad parameters\n"); + return -3; + } + +- if (_s2 == NULL) { ++ if(_s2 == NULL) { + num_pcre = 0; + } else { +- if (fixup_get_svalue(_msg, (gparam_p)_s2, &group)) +- { ++ if(fixup_get_svalue(_msg, (gparam_p)_s2, &group)) { + LM_ERR("cannot print the format for second param\n"); + return -5; + } + str2int(&group, &num_pcre); + } + +- if (fixup_get_svalue(_msg, (gparam_p)_s1, &string)) +- { ++ if(fixup_get_svalue(_msg, (gparam_p)_s1, &string)) { + LM_ERR("cannot print the format for first param\n"); + return -5; + } +@@ -676,42 +670,35 @@ static int w_pcre_match_group(struct sip + */ + + /*! \brief Reload pcres by reading the file again */ +-void regex_rpc_reload(rpc_t* rpc, void* ctx) ++void regex_rpc_reload(rpc_t *rpc, void *ctx) + { + /* Check if group matching feature is enabled */ +- if (file == NULL) { ++ if(file == NULL) { + LM_NOTICE("'file' parameter is not set, group matching disabled\n"); + rpc->fault(ctx, 500, "Group matching not enabled"); + return; + } + LM_INFO("reloading pcres...\n"); +- if (load_pcres(RELOAD)) { ++ if(load_pcres(RELOAD)) { + LM_ERR("failed to reload pcres\n"); + rpc->fault(ctx, 500, "Failed to reload"); + return; + } + LM_INFO("reload success\n"); +- + } + +-static const char* regex_rpc_reload_doc[2] = { +- "Reload regex file", +- 0 +-}; ++static const char *regex_rpc_reload_doc[2] = {"Reload regex file", 0}; + + rpc_export_t regex_rpc_cmds[] = { +- {"regex.reload", regex_rpc_reload, +- regex_rpc_reload_doc, 0}, +- {0, 0, 0, 0} +-}; ++ {"regex.reload", regex_rpc_reload, regex_rpc_reload_doc, 0}, ++ {0, 0, 0, 0}}; + + /** + * register RPC commands + */ + static int regex_init_rpc(void) + { +- if (rpc_register_array(regex_rpc_cmds)!=0) +- { ++ if(rpc_register_array(regex_rpc_cmds) != 0) { + LM_ERR("failed to register RPC commands\n"); + return -1; + } diff --git a/net/kamailio/patches/031-regex-typos.patch b/net/kamailio/patches/031-regex-typos.patch new file mode 100644 index 000000000..e08b41350 --- /dev/null +++ b/net/kamailio/patches/031-regex-typos.patch @@ -0,0 +1,39 @@ +From 650b109dbcfe2c3083e09c987bae7ca39e4a19d2 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?=D0=94=D0=B8=D0=BB=D1=8F=D0=BD=20=D0=9F=D0=B0=D0=BB=D0=B0?= + =?UTF-8?q?=D1=83=D0=B7=D0=BE=D0=B2?= +Date: Wed, 21 Jun 2023 21:34:21 +0200 +Subject: [PATCH] regex: typos + +--- + src/modules/regex/regex_mod.c | 6 +++--- + 1 file changed, 3 insertions(+), 3 deletions(-) + +--- a/src/modules/regex/regex_mod.c ++++ b/src/modules/regex/regex_mod.c +@@ -230,7 +230,7 @@ static void destroy(void) + } + + +-/*! \brief Convert the file content into regular expresions and store them in pcres */ ++/*! \brief Convert the file content into regular expressions and store them in pcres */ + static int load_pcres(int action) + { + int i, j; +@@ -307,7 +307,7 @@ static int load_pcres(int action) + } + + llen = strlen(line); +- /* Check if the patter size is too big (aprox) */ ++ /* Check if the pattern size is too big (approx) */ + if(strlen(patterns[i]) + llen >= group_max_size - 4) { + LM_ERR("pattern max file exceeded\n"); + fclose(f); +@@ -387,7 +387,7 @@ static int load_pcres(int action) + pcres_tmp[i] = NULL; + } + +- /* Compile the patters */ ++ /* Compile the patterns */ + for(i = 0; i < num_pcres_tmp; i++) { + + pcre_tmp = pcre_compile( diff --git a/net/kamailio/patches/032-regex-convert-to-memory-error-logging-helper.patch b/net/kamailio/patches/032-regex-convert-to-memory-error-logging-helper.patch new file mode 100644 index 000000000..573cc4ef7 --- /dev/null +++ b/net/kamailio/patches/032-regex-convert-to-memory-error-logging-helper.patch @@ -0,0 +1,44 @@ +From 5c7de00bc0826cf739577010ba7b4882e83819cc Mon Sep 17 00:00:00 2001 +From: Victor Seva +Date: Wed, 9 Aug 2023 10:52:47 +0000 +Subject: [PATCH] regex: convert to memory error logging helper + +--- + src/modules/regex/regex_mod.c | 8 ++++---- + 1 file changed, 4 insertions(+), 4 deletions(-) + +--- a/src/modules/regex/regex_mod.c ++++ b/src/modules/regex/regex_mod.c +@@ -198,13 +198,13 @@ static int mod_init(void) + + /* Pointer to pcres */ + if((pcres_addr = shm_malloc(sizeof(pcre **))) == 0) { +- LM_ERR("no memory for pcres_addr\n"); ++ SHM_MEM_ERROR; + goto err; + } + + /* Integer containing the number of pcres */ + if((num_pcres = shm_malloc(sizeof(int))) == 0) { +- LM_ERR("no memory for num_pcres\n"); ++ SHM_MEM_ERROR; + goto err; + } + +@@ -425,14 +425,14 @@ static int load_pcres(int action) + shm_free(pcres); + } + if((pcres = shm_malloc(sizeof(pcre *) * num_pcres_tmp)) == 0) { +- LM_ERR("no more memory for pcres\n"); ++ SHM_MEM_ERROR; + goto err; + } + memset(pcres, 0, sizeof(pcre *) * num_pcres_tmp); + for(i = 0; i < num_pcres_tmp; i++) { + pcre_rc = pcre_fullinfo(pcres_tmp[i], NULL, PCRE_INFO_SIZE, &pcre_size); + if((pcres[i] = shm_malloc(pcre_size)) == 0) { +- LM_ERR("no more memory for pcres[%i]\n", i); ++ SHM_MEM_ERROR; + goto err; + } + memcpy(pcres[i], pcres_tmp[i], pcre_size); diff --git a/net/kamailio/patches/033-regex-migration-to-pcre2.patch b/net/kamailio/patches/033-regex-migration-to-pcre2.patch new file mode 100644 index 000000000..957affac8 --- /dev/null +++ b/net/kamailio/patches/033-regex-migration-to-pcre2.patch @@ -0,0 +1,433 @@ +From 325c7a34fca74770a4351e00e27fcae75d57852e Mon Sep 17 00:00:00 2001 +From: Victor Seva +Date: Wed, 9 Aug 2023 10:48:41 +0000 +Subject: [PATCH] regex: migration to pcre2 + +--- + src/modules/regex/Makefile | 11 +- + src/modules/regex/regex_mod.c | 240 ++++++++++++++++++++++------------ + 2 files changed, 158 insertions(+), 93 deletions(-) + +--- a/src/modules/regex/Makefile ++++ b/src/modules/regex/Makefile +@@ -5,20 +5,15 @@ auto_gen= + NAME=regex.so + + ifeq ($(CROSS_COMPILE),) +-PCRE_BUILDER = $(shell \ +- if pkg-config --exists libcre; then \ +- echo 'pkg-config libpcre'; \ +- else \ +- which pcre-config; \ +- fi) ++PCRE_BUILDER = $(shell command -v pcre2-config) + endif + + ifeq ($(PCRE_BUILDER),) + PCREDEFS=-I$(LOCALBASE)/include +- PCRELIBS=-L$(LOCALBASE)/lib -lpcre ++ PCRELIBS=-L$(LOCALBASE)/lib -lpcre2-8 + else + PCREDEFS = $(shell $(PCRE_BUILDER) --cflags) +- PCRELIBS = $(shell $(PCRE_BUILDER) --libs) ++ PCRELIBS = $(shell $(PCRE_BUILDER) --libs8) + endif + + DEFS+=$(PCREDEFS) +--- a/src/modules/regex/regex_mod.c ++++ b/src/modules/regex/regex_mod.c +@@ -2,6 +2,7 @@ + * regex module - pcre operations + * + * Copyright (C) 2008 Iñaki Baz Castillo ++ * Copyright (C) 2023 Victor Seva + * + * This file is part of Kamailio, a free SIP server. + * +@@ -25,6 +26,7 @@ + * \file + * \brief REGEX :: Perl-compatible regular expressions using PCRE library + * Copyright (C) 2008 Iñaki Baz Castillo ++ * Copyright (C) 2023 Victor Seva + * \ingroup regex + */ + +@@ -32,7 +34,8 @@ + #include + #include + #include +-#include ++#define PCRE2_CODE_UNIT_WIDTH 8 ++#include + #include "../../core/sr_module.h" + #include "../../core/dprint.h" + #include "../../core/pt.h" +@@ -77,8 +80,11 @@ static int pcre_extended = 0; + /* + * Module internal parameter variables + */ +-static pcre **pcres; +-static pcre ***pcres_addr; ++static pcre2_general_context *pcres_gctx = NULL; ++static pcre2_match_context *pcres_mctx = NULL; ++static pcre2_compile_context *pcres_ctx = NULL; ++static pcre2_code **pcres; ++static pcre2_code ***pcres_addr; + static int *num_pcres; + static int pcre_options = 0x00000000; + +@@ -151,6 +157,17 @@ struct module_exports exports = { + }; + + ++static void *pcre2_malloc(size_t size, void *ext) ++{ ++ return shm_malloc(size); ++} ++ ++static void pcre2_free(void *ptr, void *ext) ++{ ++ shm_free(ptr); ++ ptr = NULL; ++} ++ + /*! \brief + * Init module function + */ +@@ -180,24 +197,39 @@ static int mod_init(void) + /* PCRE options */ + if(pcre_caseless != 0) { + LM_DBG("PCRE CASELESS enabled\n"); +- pcre_options = pcre_options | PCRE_CASELESS; ++ pcre_options = pcre_options | PCRE2_CASELESS; + } + if(pcre_multiline != 0) { + LM_DBG("PCRE MULTILINE enabled\n"); +- pcre_options = pcre_options | PCRE_MULTILINE; ++ pcre_options = pcre_options | PCRE2_MULTILINE; + } + if(pcre_dotall != 0) { + LM_DBG("PCRE DOTALL enabled\n"); +- pcre_options = pcre_options | PCRE_DOTALL; ++ pcre_options = pcre_options | PCRE2_DOTALL; + } + if(pcre_extended != 0) { + LM_DBG("PCRE EXTENDED enabled\n"); +- pcre_options = pcre_options | PCRE_EXTENDED; ++ pcre_options = pcre_options | PCRE2_EXTENDED; + } + LM_DBG("PCRE options: %i\n", pcre_options); + ++ if((pcres_gctx = pcre2_general_context_create( ++ pcre2_malloc, pcre2_free, NULL)) ++ == NULL) { ++ LM_ERR("pcre2 general context creation failed\n"); ++ return -1; ++ } ++ if((pcres_ctx = pcre2_compile_context_create(pcres_gctx)) == NULL) { ++ LM_ERR("pcre2 compile context creation failed\n"); ++ return -1; ++ } ++ if((pcres_mctx = pcre2_match_context_create(pcres_gctx)) == NULL) { ++ LM_ERR("pcre2 match context creation failed\n"); ++ return -1; ++ } ++ + /* Pointer to pcres */ +- if((pcres_addr = shm_malloc(sizeof(pcre **))) == 0) { ++ if((pcres_addr = shm_malloc(sizeof(pcre2_code **))) == 0) { + SHM_MEM_ERROR; + goto err; + } +@@ -227,6 +259,18 @@ err: + static void destroy(void) + { + free_shared_memory(); ++ ++ if(pcres_ctx) { ++ pcre2_compile_context_free(pcres_ctx); ++ } ++ ++ if(pcres_mctx) { ++ pcre2_match_context_free(pcres_mctx); ++ } ++ ++ if(pcres_gctx) { ++ pcre2_general_context_free(pcres_gctx); ++ } + } + + +@@ -237,13 +281,11 @@ static int load_pcres(int action) + FILE *f; + char line[FILE_MAX_LINE]; + char **patterns = NULL; +- pcre *pcre_tmp = NULL; +- size_t pcre_size; +- int pcre_rc; +- const char *pcre_error; +- int pcre_erroffset; ++ int pcre_error_num = 0; ++ char pcre_error[128]; ++ size_t pcre_erroffset; + int num_pcres_tmp = 0; +- pcre **pcres_tmp = NULL; ++ pcre2_code **pcres_tmp = NULL; + int llen; + + /* Get the lock */ +@@ -379,38 +421,34 @@ static int load_pcres(int action) + } + + /* Temporal pointer of pcres */ +- if((pcres_tmp = pkg_malloc(sizeof(pcre *) * num_pcres_tmp)) == 0) { ++ if((pcres_tmp = pkg_malloc(sizeof(pcre2_code *) * num_pcres_tmp)) == 0) { + LM_ERR("no more memory for pcres_tmp\n"); + goto err; + } +- for(i = 0; i < num_pcres_tmp; i++) { +- pcres_tmp[i] = NULL; +- } ++ memset(pcres_tmp, 0, sizeof(pcre2_code *) * num_pcres_tmp); + + /* Compile the patterns */ + for(i = 0; i < num_pcres_tmp; i++) { +- +- pcre_tmp = pcre_compile( +- patterns[i], pcre_options, &pcre_error, &pcre_erroffset, NULL); +- if(pcre_tmp == NULL) { +- LM_ERR("pcre_tmp compilation of '%s' failed at offset %d: %s\n", ++ pcres_tmp[i] = pcre2_compile((PCRE2_SPTR)patterns[i], ++ PCRE2_ZERO_TERMINATED, pcre_options, &pcre_error_num, ++ &pcre_erroffset, pcres_ctx); ++ if(pcres_tmp[i] == NULL) { ++ switch(pcre2_get_error_message( ++ pcre_error_num, (PCRE2_UCHAR *)pcre_error, 128)) { ++ case PCRE2_ERROR_NOMEMORY: ++ snprintf(pcre_error, 128, ++ "unknown error[%d]: pcre2 error buffer too small", ++ pcre_error_num); ++ break; ++ case PCRE2_ERROR_BADDATA: ++ snprintf(pcre_error, 128, "unknown pcre2 error[%d]", ++ pcre_error_num); ++ break; ++ } ++ LM_ERR("pcre_tmp compilation of '%s' failed at offset %zu: %s\n", + patterns[i], pcre_erroffset, pcre_error); + goto err; + } +- pcre_rc = pcre_fullinfo(pcre_tmp, NULL, PCRE_INFO_SIZE, &pcre_size); +- if(pcre_rc) { +- printf("pcre_fullinfo on compiled pattern[%i] yielded error: %d\n", +- i, pcre_rc); +- goto err; +- } +- +- if((pcres_tmp[i] = pkg_malloc(pcre_size)) == 0) { +- LM_ERR("no more memory for pcres_tmp[%i]\n", i); +- goto err; +- } +- +- memcpy(pcres_tmp[i], pcre_tmp, pcre_size); +- pcre_free(pcre_tmp); + pkg_free(patterns[i]); + patterns[i] = NULL; + } +@@ -419,31 +457,15 @@ static int load_pcres(int action) + if(action == RELOAD) { + for(i = 0; i < *num_pcres; i++) { /* Use the previous num_pcres value */ + if(pcres[i]) { +- shm_free(pcres[i]); ++ pcre2_code_free(pcres[i]); + } + } + shm_free(pcres); + } +- if((pcres = shm_malloc(sizeof(pcre *) * num_pcres_tmp)) == 0) { +- SHM_MEM_ERROR; +- goto err; +- } +- memset(pcres, 0, sizeof(pcre *) * num_pcres_tmp); +- for(i = 0; i < num_pcres_tmp; i++) { +- pcre_rc = pcre_fullinfo(pcres_tmp[i], NULL, PCRE_INFO_SIZE, &pcre_size); +- if((pcres[i] = shm_malloc(pcre_size)) == 0) { +- SHM_MEM_ERROR; +- goto err; +- } +- memcpy(pcres[i], pcres_tmp[i], pcre_size); +- } + *num_pcres = num_pcres_tmp; ++ *pcres = *pcres_tmp; + *pcres_addr = pcres; + +- /* Free used memory */ +- for(i = 0; i < num_pcres_tmp; i++) { +- pkg_free(pcres_tmp[i]); +- } + pkg_free(pcres_tmp); + /* Free allocated slots for unused patterns */ + for(i = num_pcres_tmp; i < max_groups; i++) { +@@ -466,7 +488,7 @@ err: + if(pcres_tmp) { + for(i = 0; i < num_pcres_tmp; i++) { + if(pcres_tmp[i]) { +- pkg_free(pcres_tmp[i]); ++ pcre2_code_free(pcres_tmp[i]); + } + } + pkg_free(pcres_tmp); +@@ -520,42 +542,73 @@ static void free_shared_memory(void) + /*! \brief Return true if the argument matches the regular expression parameter */ + static int ki_pcre_match(sip_msg_t *msg, str *string, str *regex) + { +- pcre *pcre_re = NULL; ++ pcre2_code *pcre_re = NULL; ++ pcre2_match_data *pcre_md = NULL; + int pcre_rc; +- const char *pcre_error; +- int pcre_erroffset; ++ int pcre_error_num = 0; ++ char pcre_error[128]; ++ size_t pcre_erroffset; + +- pcre_re = pcre_compile( +- regex->s, pcre_options, &pcre_error, &pcre_erroffset, NULL); ++ pcre_re = pcre2_compile((PCRE2_SPTR)regex->s, PCRE2_ZERO_TERMINATED, ++ pcre_options, &pcre_error_num, &pcre_erroffset, pcres_ctx); + if(pcre_re == NULL) { +- LM_ERR("pcre_re compilation of '%s' failed at offset %d: %s\n", ++ switch(pcre2_get_error_message( ++ pcre_error_num, (PCRE2_UCHAR *)pcre_error, 128)) { ++ case PCRE2_ERROR_NOMEMORY: ++ snprintf(pcre_error, 128, ++ "unknown error[%d]: pcre2 error buffer too small", ++ pcre_error_num); ++ break; ++ case PCRE2_ERROR_BADDATA: ++ snprintf(pcre_error, 128, "unknown pcre2 error[%d]", ++ pcre_error_num); ++ break; ++ } ++ LM_ERR("pcre_re compilation of '%s' failed at offset %zu: %s\n", + regex->s, pcre_erroffset, pcre_error); + return -4; + } + +- pcre_rc = pcre_exec(pcre_re, /* the compiled pattern */ +- NULL, /* no extra data - we didn't study the pattern */ +- string->s, /* the matching string */ +- (int)(string->len), /* the length of the subject */ +- 0, /* start at offset 0 in the string */ +- 0, /* default options */ +- NULL, /* output vector for substring information */ +- 0); /* number of elements in the output vector */ ++ pcre_md = pcre2_match_data_create_from_pattern(pcre_re, pcres_gctx); ++ pcre_rc = pcre2_match(pcre_re, /* the compiled pattern */ ++ (PCRE2_SPTR)string->s, /* the matching string */ ++ (PCRE2_SIZE)(string->len), /* the length of the subject */ ++ 0, /* start at offset 0 in the string */ ++ 0, /* default options */ ++ pcre_md, /* the match data block */ ++ pcres_mctx); /* a match context; NULL means use defaults */ + + /* Matching failed: handle error cases */ + if(pcre_rc < 0) { + switch(pcre_rc) { +- case PCRE_ERROR_NOMATCH: ++ case PCRE2_ERROR_NOMATCH: + LM_DBG("'%s' doesn't match '%s'\n", string->s, regex->s); + break; + default: +- LM_DBG("matching error '%d'\n", pcre_rc); ++ switch(pcre2_get_error_message( ++ pcre_rc, (PCRE2_UCHAR *)pcre_error, 128)) { ++ case PCRE2_ERROR_NOMEMORY: ++ snprintf(pcre_error, 128, ++ "unknown error[%d]: pcre2 error buffer too " ++ "small", ++ pcre_rc); ++ break; ++ case PCRE2_ERROR_BADDATA: ++ snprintf(pcre_error, 128, "unknown pcre2 error[%d]", ++ pcre_rc); ++ break; ++ } ++ LM_ERR("matching error:'%s' failed[%d]\n", pcre_error, pcre_rc); + break; + } +- pcre_free(pcre_re); ++ if(pcre_md) ++ pcre2_match_data_free(pcre_md); ++ pcre2_code_free(pcre_re); + return -1; + } +- pcre_free(pcre_re); ++ if(pcre_md) ++ pcre2_match_data_free(pcre_md); ++ pcre2_code_free(pcre_re); + LM_DBG("'%s' matches '%s'\n", string->s, regex->s); + return 1; + } +@@ -592,6 +645,8 @@ static int w_pcre_match(struct sip_msg * + static int ki_pcre_match_group(sip_msg_t *_msg, str *string, int num_pcre) + { + int pcre_rc; ++ pcre2_match_data *pcre_md = NULL; ++ char pcre_error[128]; + + /* Check if group matching feature is enabled */ + if(file == NULL) { +@@ -606,26 +661,41 @@ static int ki_pcre_match_group(sip_msg_t + } + + lock_get(reload_lock); +- +- pcre_rc = pcre_exec((*pcres_addr)[num_pcre], /* the compiled pattern */ +- NULL, /* no extra data - we didn't study the pattern */ +- string->s, /* the matching string */ +- (int)(string->len), /* the length of the subject */ +- 0, /* start at offset 0 in the string */ +- 0, /* default options */ +- NULL, /* output vector for substring information */ +- 0); /* number of elements in the output vector */ ++ pcre_md = pcre2_match_data_create_from_pattern( ++ (*pcres_addr)[num_pcre], pcres_gctx); ++ pcre_rc = pcre2_match((*pcres_addr)[num_pcre], /* the compiled pattern */ ++ (PCRE2_SPTR)string->s, /* the matching string */ ++ (PCRE2_SIZE)(string->len), /* the length of the subject */ ++ 0, /* start at offset 0 in the string */ ++ 0, /* default options */ ++ pcre_md, /* the match data block */ ++ pcres_mctx); /* a match context; NULL means use defaults */ + + lock_release(reload_lock); ++ if(pcre_md) ++ pcre2_match_data_free(pcre_md); + + /* Matching failed: handle error cases */ + if(pcre_rc < 0) { + switch(pcre_rc) { +- case PCRE_ERROR_NOMATCH: ++ case PCRE2_ERROR_NOMATCH: + LM_DBG("'%s' doesn't match pcres[%i]\n", string->s, num_pcre); + break; + default: +- LM_DBG("matching error '%d'\n", pcre_rc); ++ switch(pcre2_get_error_message( ++ pcre_rc, (PCRE2_UCHAR *)pcre_error, 128)) { ++ case PCRE2_ERROR_NOMEMORY: ++ snprintf(pcre_error, 128, ++ "unknown error[%d]: pcre2 error buffer too " ++ "small", ++ pcre_rc); ++ break; ++ case PCRE2_ERROR_BADDATA: ++ snprintf(pcre_error, 128, "unknown pcre2 error[%d]", ++ pcre_rc); ++ break; ++ } ++ LM_ERR("matching error:'%s' failed[%d]\n", pcre_error, pcre_rc); + break; + } + return -1; diff --git a/net/kamailio/patches/050-fix-kamailio-utils.patch b/net/kamailio/patches/050-fix-kamailio-utils.patch new file mode 100644 index 000000000..a620e8952 --- /dev/null +++ b/net/kamailio/patches/050-fix-kamailio-utils.patch @@ -0,0 +1,9 @@ +--- a/utils/kamctl/kamctlrc ++++ b/utils/kamctl/kamctlrc +@@ -166,3 +166,6 @@ + ## Extra start options - default is: not set + ## example: start Kamailio with 64MB shared memory: STARTOPTIONS="-m 64" + # STARTOPTIONS= ++ ++# Disable colour printing in terminal ++NOHLPRINT=1 diff --git a/net/kamailio/patches/100-kamcmd-don-t-clash-with-ENV-NAME-or-ctl.so-module.patch b/net/kamailio/patches/100-kamcmd-don-t-clash-with-ENV-NAME-or-ctl.so-module.patch new file mode 100644 index 000000000..893cf6a44 --- /dev/null +++ b/net/kamailio/patches/100-kamcmd-don-t-clash-with-ENV-NAME-or-ctl.so-module.patch @@ -0,0 +1,45 @@ +From 8421e2be8331a03b0087eb33241fac98e1fd821f Mon Sep 17 00:00:00 2001 +From: Christian Marangi +Date: Fri, 3 Nov 2023 03:09:21 +0100 +Subject: [PATCH] kamcmd: don't clash with ENV NAME or ctl.so module + +NAME variable might be set to the current HOSTNAME in some shell and +also clash with the value set by the module calling MOD_INSTALL_UTILS by +passing a NAME variable. + +With commit 1774cee62098 ("kamcmd: allow defining the name of the +application from command line") this resulted in the kamcmd bin being +renamed to all kind of name from hostname to ctl.so. + +Fix this by checking the variable to a more safe name that is not +already defined in shell by default and also that doesn't clash with +module variables, use UTIL_NAME as an alternative to NAME. + +UTIL_NAME now needs to be used to create kamcmd with custom name. + +Fixes: 1774cee62098 ("kamcmd: allow defining the name of the application from command line") +Signed-off-by: Christian Marangi +--- + utils/kamcmd/Makefile | 9 +++++++-- + 1 file changed, 7 insertions(+), 2 deletions(-) + +--- a/utils/kamcmd/Makefile ++++ b/utils/kamcmd/Makefile +@@ -8,10 +8,15 @@ include $(COREPATH)/Makefile.targets + auto_gen= + RELEASE=1.5 + UTIL_SRC_NAME=kamcmd ++# Pass CUSTOM_NAME to overwrite the kamcmd/sercmd bin name ++ifeq ($(CUSTOM_NAME),) + ifeq ($(FLAVOUR),ser) +- NAME?=sercmd ++ NAME=sercmd + else +- NAME?=kamcmd ++ NAME=kamcmd ++endif ++else ++ NAME=$(CUSTOM_NAME) + endif + + readline_localpath=$(LOCALBASE)/include/readline/readline.h diff --git a/net/kamailio/patches/120-libevent-libs.patch b/net/kamailio/patches/120-libevent-libs.patch new file mode 100644 index 000000000..b3aa328a0 --- /dev/null +++ b/net/kamailio/patches/120-libevent-libs.patch @@ -0,0 +1,10 @@ +--- a/src/modules/janssonrpcc/netstring.h ++++ b/src/modules/janssonrpcc/netstring.h +@@ -24,6 +24,7 @@ + #define __NETSTRING_STREAM_H + + #include ++#include + #include + + typedef struct { diff --git a/net/kamailio/patches/130-change-snmp-mibs-path.patch b/net/kamailio/patches/130-change-snmp-mibs-path.patch new file mode 100644 index 000000000..fff2a8460 --- /dev/null +++ b/net/kamailio/patches/130-change-snmp-mibs-path.patch @@ -0,0 +1,11 @@ +--- a/src/modules/snmpstats/Makefile ++++ b/src/modules/snmpstats/Makefile +@@ -16,7 +16,7 @@ ifeq ($(BUILDER),) + INSTALLMIBDIR = $(share_prefix)/share/snmp/mibs + else + BUILDAGENTLIBS = $(shell net-snmp-config --netsnmp-agent-libs) +- INSTALLMIBDIR = $(basedir)$(shell net-snmp-config --prefix)/share/snmp/mibs ++ INSTALLMIBDIR = $(basedir)/usr/share/snmp/mibs + endif + + ifeq ($(EMBEDDED_PERL),1) diff --git a/net/kamailio/patches/140-redis_use_pkg-config.patch b/net/kamailio/patches/140-redis_use_pkg-config.patch new file mode 100644 index 000000000..cbcaca1d3 --- /dev/null +++ b/net/kamailio/patches/140-redis_use_pkg-config.patch @@ -0,0 +1,64 @@ +--- a/src/modules/cnxcc/Makefile ++++ b/src/modules/cnxcc/Makefile +@@ -8,12 +8,10 @@ include ../../Makefile.defs + auto_gen= + NAME=cnxcc.so + +-ifeq ($(CROSS_COMPILE),) + HIREDIS_BUILDER = $(shell \ + if pkg-config --exists hiredis; then \ + echo 'pkg-config hiredis'; \ + fi) +-endif + + ifeq ($(HIREDIS_BUILDER),) + HIREDISDEFS=-I$(LOCALBASE)/include +--- a/src/modules/db_redis/Makefile ++++ b/src/modules/db_redis/Makefile +@@ -5,7 +5,6 @@ include ../../Makefile.defs + auto_gen= + NAME=db_redis.so + +-ifeq ($(CROSS_COMPILE),) + HIREDIS_BUILDER = $(shell \ + if pkg-config --exists hiredis; then \ + echo 'pkg-config hiredis'; \ +@@ -16,8 +15,6 @@ HIREDIS_CLUSTER_BUILDER = $(shell \ + echo 'pkg-config hiredis_cluster'; \ + fi) + +-endif +- + ifeq ($(HIREDIS_BUILDER),) + HIREDISDEFS=-I$(LOCALBASE)/include -I$(LOCALBASE)/include/hiredis -I/usr/include/hiredis + HIREDISLIBS=-L$(LOCALBASE)/lib -lhiredis +--- a/src/modules/ndb_redis/Makefile ++++ b/src/modules/ndb_redis/Makefile +@@ -5,12 +5,10 @@ include ../../Makefile.defs + auto_gen= + NAME=ndb_redis.so + +-ifeq ($(CROSS_COMPILE),) + HIREDIS_BUILDER = $(shell \ + if pkg-config --exists hiredis; then \ + echo 'pkg-config hiredis'; \ + fi) +-endif + + ifeq ($(HIREDIS_BUILDER),) + HIREDISDEFS=-I$(LOCALBASE)/include -I$(LOCALBASE)/include/hiredis -I/usr/include/hiredis +--- a/src/modules/topos_redis/Makefile ++++ b/src/modules/topos_redis/Makefile +@@ -5,12 +5,10 @@ include ../../Makefile.defs + auto_gen= + NAME=topos_redis.so + +-ifeq ($(CROSS_COMPILE),) + HIREDIS_BUILDER = $(shell \ + if pkg-config --exists hiredis; then \ + echo 'pkg-config hiredis'; \ + fi) +-endif + + ifeq ($(HIREDIS_BUILDER),) + HIREDISDEFS=-I$(LOCALBASE)/include -I$(LOCALBASE)/include/hiredis -I/usr/include/hiredis diff --git a/net/kamailio/patches/150-erlang-fix-flags.patch b/net/kamailio/patches/150-erlang-fix-flags.patch new file mode 100644 index 000000000..60ab4f2c3 --- /dev/null +++ b/net/kamailio/patches/150-erlang-fix-flags.patch @@ -0,0 +1,30 @@ +--- a/src/modules/erlang/Makefile ++++ b/src/modules/erlang/Makefile +@@ -5,20 +5,21 @@ include ../../Makefile.defs + auto_gen= + NAME=erlang.so + +-ERLANG=$(shell which erl) ++# In OpenWrt Erlang resides in standard locations, no special flags required ++#ERLANG=$(shell which erl) + + ifneq ($(ERLANG),) + ERLANG_LIBDIR=$(shell $(ERLANG) -noshell -eval 'io:format("~n~s/lib~n", [[code:lib_dir("erl_interface")]]).' -s erlang halt | tail -n 1) + ERLANG_INCDIR=$(shell $(ERLANG) -noshell -eval 'io:format("~n~s/include~n", [[code:lib_dir("erl_interface")]]).' -s erlang halt | tail -n 1) + endif + +-ifeq ($(ERLANG_LIBDIR)$(ERLANG_INCDIR),) +-$(error Not found Erlang) +-endif ++#ifeq ($(ERLANG_LIBDIR)$(ERLANG_INCDIR),) ++#$(error Not found Erlang) ++#endif + +-LIBS=-L$(ERLANG_LIBDIR) -lei -lpthread ++LIBS=-lei -lpthread + +-DEFS+=-I$(ERLANG_INCDIR) ++#DEFS+=-I$(ERLANG_INCDIR) + DEFS+=-D_REENTRANT + + diff --git a/net/miax/Makefile b/net/miax/Makefile new file mode 100644 index 000000000..ec2893246 --- /dev/null +++ b/net/miax/Makefile @@ -0,0 +1,55 @@ +# +# Copyright (C) 2014 OpenWrt.org +# +# This is free software, licensed under the GNU General Public License v2. +# See /LICENSE for more information. +# + +include $(TOPDIR)/rules.mk + +PKG_NAME:=miax +PKG_VERSION:=1.4 +PKG_RELEASE:=3 + +PKG_SOURCE:=$(PKG_NAME)_$(PKG_VERSION).tar.gz +PKG_SOURCE_URL:=@SF/miax +PKG_HASH:=2be07cdb1929d6b07f04ec3a66edf4fb2febd691c72f5fd4893923f6474b53e9 +PKG_CHECK_FORMAT_SECURITY:=0 + +PKG_BUILD_DIR:=$(BUILD_DIR)/$(PKG_NAME) + +PKG_LICENSE:=GPL-2.0 +PKG_LICENSE_FILES:=COPYING LICENSE + +include $(INCLUDE_DIR)/package.mk + +define Package/miax + SECTION:=net + CATEGORY:=Network + SUBMENU:=Telephony + DEPENDS:=+libpthread + TITLE:=A console iax (asterisk) client + URL:=http://www.eja.it/?l=en&n=miax +endef + +define Package/miax/description + miax is a console iax (asterisk) client, it can work with + a soundcard as a normal voip phone, taking input/output from + keyboard or analog/gsm/isdn modem. +endef + +define Build/Compile + $(MAKE) -C "$(PKG_BUILD_DIR)" \ + CC="$(TARGET_CC)" \ + OFLAGS="$(TARGET_CFLAGS)" \ + CPPFLAGS="$(TARGET_CPPFLAGS)" \ + LDFLAGS="$(TARGET_LDFLAGS)" \ + all +endef + +define Package/miax/install + $(INSTALL_DIR) $(1)/usr/bin + $(INSTALL_BIN) $(PKG_BUILD_DIR)/miax $(1)/usr/bin/ +endef + +$(eval $(call BuildPackage,miax)) diff --git a/net/miax/patches/001-cross.patch b/net/miax/patches/001-cross.patch new file mode 100644 index 000000000..f47c1101d --- /dev/null +++ b/net/miax/patches/001-cross.patch @@ -0,0 +1,24 @@ +diff -ruN miax-1.4-old/Makefile miax-1.4-new/Makefile +--- miax-1.4-old/Makefile 2005-04-27 18:56:13.000000000 +0200 ++++ miax-1.4-new/Makefile 2005-11-30 01:07:21.000000000 +0100 +@@ -1,4 +1,5 @@ +-CFLAGS= -Iiax/ -Igsm/inc -DIAXC_IAX2 -DLIBIAX -g -DPOSIXSLEEP -DLINUX -O2 ++OFLAGS= -02 -g ++CFLAGS= -Iiax/ -Igsm/inc $(CPPFLAGS) -DIAXC_IAX2 -DLIBIAX -DPOSIXSLEEP -DLINUX $(OFLAGS) + SYSLIBS=-lpthread -lm -lbluetooth + + +@@ -32,11 +33,10 @@ + miax.o + + all: $(OBJS) +- gcc $(OBJS) $(CFLAGS) $(SYSLIBS) -o miax +- cp miax /bin/miax ++ $(CC) $(OBJS) $(CFLAGS) $(LDFLAGS) $(SYSLIBS) -o miax + + static: $(OBJS) bluetooth.o +- gcc $(OBJS) $(CFLAGS) $(SYSLIBS) -static -o miax ++ $(CC) $(OBJS) $(CFLAGS) $(LDFLAGS) $(SYSLIBS) -static -o miax + + clean: + rm -f $(OBJS) miax diff --git a/net/miax/patches/002-remove-bluetooth-support.patch b/net/miax/patches/002-remove-bluetooth-support.patch new file mode 100644 index 000000000..02532e049 --- /dev/null +++ b/net/miax/patches/002-remove-bluetooth-support.patch @@ -0,0 +1,465 @@ +--- a/bluetooth.c ++++ b/bluetooth.c +@@ -1,345 +0,0 @@ +-/* +-* Miax +-* +-* Copyright (C) 2004 by Ubaldo Porcheddu +-* +-* This program is free software; you can redistribute it and/or modify +-* it under the terms of the GNU General Public License as published by +-* the Free Software Foundation; either version 2 of the License, or +-* (at your option) any later version. +-* +-* This program 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 +-* General Public License for more details. +-* +-* You should have received a copy of the GNU General Public License +-* along with this program; if not, write to the Free Software +-* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +-*/ +- +-#include +-#include +-#include +-#include +-#include +-#include +-#include +-#include +-#include +-#include +-#include +-#include +-#include +-#include +-#include +-#include +-#include "iaxclient_lib.h" +- +-#define RTP 320 +-#define AFRAME 48 +- +-static int fd_audio, il=0, ol=0, audio=0, compression=0; +-static char dev_audio[10], in[512], out[512]; +-static int fd_modem, call=0, callsetup=0, m_status=0; +-static bdaddr_t src, dst; +-static int btchannel=3; +-static int init=0; +-extern int debug; +- +-int bt_init(char *devs) { +- int l; +- +- if (init == 0) { +- l=strlen(devs); +- str2ba(strtok(devs,"/"), &src); +- str2ba(strtok(NULL,"/"), &dst); +- if (l > 35) { btchannel=atoi(strtok(NULL,"/")); } +- init=1; +- } +- return 0; +- } +- +- +-int rfcomm_connect(bdaddr_t *src, bdaddr_t *dst, int channel) { +- +- struct sockaddr_rc addr; +- int s; +- +- if ((s = socket(PF_BLUETOOTH, SOCK_STREAM, BTPROTO_RFCOMM)) < 0) { +- return -1; +- } +- memset(&addr, 0, sizeof(addr)); +- addr.rc_family = AF_BLUETOOTH; +- bacpy(&addr.rc_bdaddr, src); +- addr.rc_channel = 0; +- if (bind(s, (struct sockaddr *)&addr, sizeof(addr)) < 0) { +- close(s); +- return -1; +- } +- memset(&addr, 0, sizeof(addr)); +- addr.rc_family = AF_BLUETOOTH; +- bacpy(&addr.rc_bdaddr, dst); +- addr.rc_channel = channel; +- if (connect(s, (struct sockaddr *)&addr, sizeof(addr)) < 0 ){ +- close(s); +- return -1; +- } +- +- return s; +- } +- +- +-int sco_connect(bdaddr_t *src, bdaddr_t *dst) { +- +- struct sockaddr_sco addr; +- struct sco_conninfo conn; +- struct sco_options opts; +- int s, size; +- +- if ((s = socket(PF_BLUETOOTH, SOCK_SEQPACKET, BTPROTO_SCO)) < 0) { +- return -1; +- } +- memset(&addr, 0, sizeof(addr)); +- addr.sco_family = AF_BLUETOOTH; +- bacpy(&addr.sco_bdaddr, src); +- if (bind(s, (struct sockaddr *)&addr, sizeof(addr)) < 0) { +- close(s); +- return -1; +- } +- memset(&addr, 0, sizeof(addr)); +- addr.sco_family = AF_BLUETOOTH; +- bacpy(&addr.sco_bdaddr, dst); +- if (connect(s, (struct sockaddr *)&addr, sizeof(addr)) < 0 ){ +- close(s); +- return -1; +- } +- +- return s; +- } +- +- +-int bt_audio_init(char *dev, int enc) { +- +- compression=enc; +- return bt_init(dev); +- } +- +- +-int bt_audio_open() { +- +- if ((fd_audio = sco_connect(&src, &dst)) < 0) { +- perror("Can't connect SCO audio channel"); +- close(fd_modem); +- return -1; +- } +- audio=1; +- fprintf(stderr, "BT audio ready.\n"); +- +- return fd_audio; +- } +- +- +-int bt_audio_close() { +- +- audio=-1; +- +- return close(fd_audio); +- } +- +- +-int bt_audio_out(struct iaxc_call *call, void *encoded) { +- +- char buf[512], data[RTP]; +- int i=0,n=0,x=0,y=0,z=0; +- +- if (audio == 0) { bt_audio_open(); } +- if (audio == 1) { +- +- y=RTP+ol; +- memmove(buf,out,ol); +- +- if (compression == 0) { +- memmove(data,encoded,RTP); +- } +- else { +- if (!call->gsmin) { call->gsmin = gsm_create(); } +- gsm_decode(call->gsmin, encoded, data); +- } +- +- for(i=ol;i 0) { +- if (debug > 4) { fprintf(stderr, "Miax: dtmf %c\n", dtmf_c); } +- iax_send_dtmf(call->session,dtmf_c); +- } +- +- if ( compression == 0) { +- iax_send_voice(call->session, AST_FORMAT_SLINEAR, buf , RTP); +- } +- else { +- if(!call->gsmout) { call->gsmout = gsm_create(); } +- gsm_encode(call->gsmout, (short *) buf, (void *)&fo); +- iax_send_voice(call->session, AST_FORMAT_GSM, (char *)&fo, sizeof(gsm_frame)); +- } +- } +- +- return 1; +- } +- +- +-int bt_modem_init(char *dev) { +- +- char *buf,tmp[1024]; +- int n=0,z=-1; +- +- bt_init(dev); +- +- if ((fd_modem = rfcomm_connect(&src, &dst, btchannel)) < 0) { +- perror("Can't connect RFCOMM channel"); +- return -1; +- } +- +- bt_modem("ATZ\r",tmp); +- bt_modem("ATE1\r",tmp); +- bt_modem("AT+CIND=?\r",tmp); +- buf=strtok(tmp,"("); +- while( buf=strtok(NULL,"))") ) { +- n++; +- if (strstr(buf,"\"call\"")) { call=n; z++;} +- if (strstr(buf,"\"callsetup\"")) { callsetup=n; z++; } +- } +- +- z+=bt_modem("AT+CLIP=1\r",tmp); +- z+=bt_modem("AT+CMER=3,0,0,1\r",tmp); +- fprintf(stderr, "BT modem ready.\n"); +- +- m_status=1; +- +- return fd_modem; +- } +- +-int bt_modem_close() { +- +- char buf[256]; +- int l=0; +- +- if (m_status > 1) { +- m_status=-1; +- bt_modem("AT+CHUP\r",buf); +- l=close(fd_modem); +- } +- +- return l; +- } +- +- +-int bt_modem(char* send, char *receive) { +- +- int l=0; +- fd_set rfds; +- struct timeval tv; +- int retval; +- +- FD_ZERO(&rfds); +- FD_SET(fd_modem, &rfds); +- tv.tv_sec = 1; +- tv.tv_usec = 0; +- +- if (strlen(send)) { write(fd_modem,send,strlen(send)); } +- +- if (m_status >= 0) { +- if (retval = select(fd_modem+1, &rfds, NULL, NULL, &tv) > 0) { +- memset(receive,0,1024); +- l=read(fd_modem,receive,1024); +- if (debug > 3) { fprintf(stderr, "%s\n", receive); } +- } +- } +- +- return l; +- } +- +- +-int bt_modem_loop(int status, char *number) { +- +- char buf[1024], tmp[1024]; +- +- if (m_status < 0) { return -1; } +- +- if (status == 130 && m_status != 3) { +- bt_modem("ATA\r",tmp); +- m_status=3; +- status=0; +- return 100; +- } +- if (status == 100 && m_status != 2) { +- sprintf(buf,"ATDT%s;\r",number); +- bt_modem(buf,tmp); +- status=0; +- m_status=2; +- } +- +- +- if (bt_modem("",buf)) { +- +- sprintf(tmp,"+CIEV: %d,0",callsetup); +- if (strstr(buf,tmp) && m_status != 5) { +- m_status=5; +- return 130; +- } +- +- sprintf(tmp,"+CIEV: %d,0",call); +- if (strstr(buf,tmp)) { return -5; } +- +- if (strstr(buf,"+CLIP:") && m_status != 4) { +- strcpy(tmp,strtok(buf,"\"")); +- strcpy(number,strtok(NULL,"\"")); +- m_status=4; +- return 101; +- } +- if (strstr(buf,"ERROR")) { return 1; } +- if (strstr(buf,"BUSY")) { return -2; } +- if (strstr(buf,"NO DIALTONE")) { return -3; } +- if (strstr(buf,"NO CARRIER")) { return -4; } +- if (strstr(buf,"RING")) { return 2; } +- if (strstr(buf,"OK")) { return 1; } +- } +- +- return 0; +- } +--- a/Makefile ++++ b/Makefile +@@ -1,6 +1,6 @@ + OFLAGS= -02 -g + CFLAGS= -Iiax/ -Igsm/inc $(CPPFLAGS) -DIAXC_IAX2 -DLIBIAX -DPOSIXSLEEP -DLINUX $(OFLAGS) +-SYSLIBS=-lpthread -lm -lbluetooth ++SYSLIBS=-lpthread -lm + + + OBJS=\ +@@ -28,14 +28,13 @@ OBJS=\ + iax/iaxclient_lib.o \ + dtmf.o \ + oss.o \ +- bluetooth.o \ + modem.o \ + miax.o + + all: $(OBJS) + $(CC) $(OBJS) $(CFLAGS) $(LDFLAGS) $(SYSLIBS) -o miax + +-static: $(OBJS) bluetooth.o ++static: $(OBJS) + $(CC) $(OBJS) $(CFLAGS) $(LDFLAGS) $(SYSLIBS) -static -o miax + + clean: +--- a/miax.c ++++ b/miax.c +@@ -130,7 +130,6 @@ void usage() { + fprintf(stderr, " -a audio device\n"); + fprintf(stderr, " -g gsm codec\n"); + fprintf(stderr, " -m modem device\n"); +- fprintf(stderr, " -b bluetooth device\n"); + fprintf(stderr, " -i modem init string\n"); + fprintf(stderr, " -l log level\n"); + fprintf(stderr, " -o log output\n"); +--- a/miax.h ++++ b/miax.h +@@ -23,55 +23,53 @@ + + int debug=0; + int status=0; +-int bt; //bluetooth ++int bt; //bluetooth + int m=0; //modem + char number[1024]; + +-int audio_init(char *dev, int compression) { +- (bt) ? bt_audio_init(dev, compression) : oss_audio_init(dev, compression); ++int audio_init(char *dev, int compression) { ++ oss_audio_init(dev, compression); + } + +-int audio_open() { +- (bt) ? bt_audio_open() : oss_audio_open(); ++int audio_open() { ++ oss_audio_open(); + } + +-int audio_out(struct iaxc_call *call, void *encoded) { +- (bt) ? bt_audio_out(call,encoded) : oss_audio_out(call,encoded) ; ++int audio_out(struct iaxc_call *call, void *encoded) { ++ oss_audio_out(call,encoded) ; + } + +-int audio_in(struct iaxc_call *call) { +- (bt) ? bt_audio_in(call) : oss_audio_in(call) ; ++int audio_in(struct iaxc_call *call) { ++ oss_audio_in(call) ; + } + +-int audio_close () { +- (bt) ? bt_audio_close() : oss_audio_close() ; ++int audio_close () { ++ oss_audio_close() ; + } + +-int modem_init(char *dev) { +- (bt) ? bt_modem_init(dev) : tty_modem_init(dev) ; ++int modem_init(char *dev) { ++ tty_modem_init(dev) ; + } + +-int modem(char *val) { ++int modem(char *val) { + char tmp[1024]; +- +- (bt) ? bt_modem(val, tmp) : tty_modem(val, tmp) ; ++ ++ tty_modem(val, tmp) ; + } + +-int modem_close() { +- (bt) ? bt_modem_close() : tty_modem_close() ; ++int modem_close() { ++ tty_modem_close() ; + } + +-int modem_loop(int status, char *number) { +- if (bt) { return bt_modem_loop(status, number); } +- else { return tty_modem_loop(status, number); } ++int modem_loop(int status, char *number) { ++ return tty_modem_loop(status, number); + } + + int miax_loop(int status, char *number) { +- if (m > 0 && bt > 0) { return bt_modem_loop(status, number); } +- if (m > 0 && bt == 0) { return tty_modem_loop(status, number); } +- if (m == 0) { ++ if (m > 0) { return tty_modem_loop(status, number); } ++ if (m == 0) { + printf("\nMiax console.\t[h] to hangup or quit\n"); +- return console_loop(status, number); ++ return console_loop(status, number); + } + } + #endif diff --git a/net/miax/patches/003-musl-fixes.patch b/net/miax/patches/003-musl-fixes.patch new file mode 100644 index 000000000..86b1c3045 --- /dev/null +++ b/net/miax/patches/003-musl-fixes.patch @@ -0,0 +1,142 @@ +--- a/iax/iax.c ++++ b/iax/iax.c +@@ -45,7 +45,6 @@ + + #ifndef MACOSX + #include +-#include + #endif + + #endif +--- a/miax.c ++++ b/miax.c +@@ -31,26 +31,26 @@ + #include "iaxclient_lib.h" + #include "miax.h" + +-FILE *stderr; ++FILE *_stderr; + + int miax_closeall(int n) { + + int l; + +- if (debug > 5 ) { fprintf(stderr,"Miax: status: %d\nMiax: event: %d\n",status, n); } ++ if (debug > 5 ) { fprintf(_stderr,"Miax: status: %d\nMiax: event: %d\n",status, n); } + + if (status >= 0) { + status=-1; + + if (n < 0) { + iaxc_dump_all_calls(); +- if (debug > 5 ) { fprintf(stderr,"Miax: call dumped.\n"); } ++ if (debug > 5 ) { fprintf(_stderr,"Miax: call dumped.\n"); } + } + audio_close(); +- if (debug > 5 ) { fprintf(stderr,"Miax: audio closed.\n"); } ++ if (debug > 5 ) { fprintf(_stderr,"Miax: audio closed.\n"); } + if (m > 0) { + modem_close(); +- if (debug > 5 ) { fprintf(stderr,"Miax: modem closed.\n"); } ++ if (debug > 5 ) { fprintf(_stderr,"Miax: modem closed.\n"); } + } + } + +@@ -63,7 +63,7 @@ int miax_callback(struct iax_event *e, i + switch(e->etype) { + case 0: //IAX_EVENT_CONNECT + strcpy(number,e->ies.called_number); +- fprintf(stderr, "Miax: %s is looking for %s\n", e->ies.calling_number, number); ++ fprintf(_stderr, "Miax: %s is looking for %s\n", e->ies.calling_number, number); + status=100; + break; + case 2: //IAX_EVENT_HANGUP: +@@ -105,7 +105,7 @@ int console_loop(int status, char *numbe + read(0,buf,sizeof(buf)); + if (status == 100) { return 130; } + if (strstr(buf,"h")) { +- fprintf(stderr, "Miax: hanging up.\n"); ++ fprintf(_stderr, "Miax: hanging up.\n"); + return -1; + } + else { +@@ -119,21 +119,21 @@ int console_loop(int status, char *numbe + + + void usage() { +- fprintf(stderr, "Usage: miax [-hndupsragmbil]\n\n"); +- fprintf(stderr, " -h this help\n"); +- fprintf(stderr, " -n source number\n"); +- fprintf(stderr, " -d destination number\n"); +- fprintf(stderr, " -u username\n"); +- fprintf(stderr, " -p password\n"); +- fprintf(stderr, " -s server\n"); +- fprintf(stderr, " -r register\n"); +- fprintf(stderr, " -a audio device\n"); +- fprintf(stderr, " -g gsm codec\n"); +- fprintf(stderr, " -m modem device\n"); +- fprintf(stderr, " -i modem init string\n"); +- fprintf(stderr, " -l log level\n"); +- fprintf(stderr, " -o log output\n"); +- fprintf(stderr, "\nReport bugs to \n"); ++ fprintf(_stderr, "Usage: miax [-hndupsragmbil]\n\n"); ++ fprintf(_stderr, " -h this help\n"); ++ fprintf(_stderr, " -n source number\n"); ++ fprintf(_stderr, " -d destination number\n"); ++ fprintf(_stderr, " -u username\n"); ++ fprintf(_stderr, " -p password\n"); ++ fprintf(_stderr, " -s server\n"); ++ fprintf(_stderr, " -r register\n"); ++ fprintf(_stderr, " -a audio device\n"); ++ fprintf(_stderr, " -g gsm codec\n"); ++ fprintf(_stderr, " -m modem device\n"); ++ fprintf(_stderr, " -i modem init string\n"); ++ fprintf(_stderr, " -l log level\n"); ++ fprintf(_stderr, " -o log output\n"); ++ fprintf(_stderr, "\nReport bugs to \n"); + exit(1); + } + +@@ -216,7 +216,7 @@ int main(int argc, char **argv) { + + printf("miax@eja.it\n"); + +- stderr=fopen(log_output,"w"); ++ _stderr=fopen(log_output,"w"); + + iaxc_initialize(1); + +@@ -233,13 +233,13 @@ int main(int argc, char **argv) { + if (r > 0) { iaxc_register(username,password,hostname); } + + if ( audio_init(audio_dev, compression) < 0) { +- fprintf(stderr,"Miax: cannot initialize audio device!\n"); ++ fprintf(_stderr,"Miax: cannot initialize audio device!\n"); + return -1; + } + + if (m > 0) { + if (modem_init(modem_dev) < 0) { +- fprintf(stderr,"Miax: cannot initialize modem device!\n"); ++ fprintf(_stderr,"Miax: cannot initialize modem device!\n"); + return -1; + } + if (m == 2) { sprintf(buf,"%s\r",modem_i); modem(buf); } +@@ -252,7 +252,7 @@ int main(int argc, char **argv) { + + iaxc_start_processing_thread(); + +- fprintf(stderr, "Miax: ready.\n"); ++ fprintf(_stderr, "Miax: ready.\n"); + + while(status >= 0) { + n = miax_loop(status, number); +@@ -271,7 +271,7 @@ int main(int argc, char **argv) { + break; + } + } +- fprintf(stderr, "Miax: bye! :)\n\n"); ++ fprintf(_stderr, "Miax: bye! :)\n\n"); + + exit(0); + } diff --git a/net/miax/patches/010-usleep.patch b/net/miax/patches/010-usleep.patch new file mode 100644 index 000000000..fe45b2b41 --- /dev/null +++ b/net/miax/patches/010-usleep.patch @@ -0,0 +1,24 @@ +--- a/modem.c ++++ b/modem.c +@@ -76,10 +76,11 @@ int tty_modem(char* send, char *receive) { + + int l=0, in=0, out=0, timeout=10; + char tmp[4096]; ++ struct timespec h = {0, 100 * 1000 * 1000}; + + if (strlen(send)) { + while ((timeout--) > 0) { +- usleep(100000); ++ nanosleep(&h, NULL); + ioctl(fd_modem,TIOCMGET,&out); + if (out & TIOCM_CTS) { + l=write(fd_modem,send,strlen(send)); +@@ -97,7 +98,7 @@ int tty_modem(char* send, char *receive) { + strncat(receive,tmp,in); + if (strchr(receive,'\r')) { break; } + } +- else { usleep(100000); } ++ else { nanosleep(&h, NULL); } + } + if (strlen(receive) > 0 && debug > 3) { fprintf(stderr, "%s\n", receive); } + diff --git a/net/miax/patches/020-includes.patch b/net/miax/patches/020-includes.patch new file mode 100644 index 000000000..4e667a26a --- /dev/null +++ b/net/miax/patches/020-includes.patch @@ -0,0 +1,79 @@ +--- a/dtmf.c ++++ b/dtmf.c +@@ -22,6 +22,7 @@ + #include + #include + #include ++#include + + #define RATE 8000 + #define BLOCKLEN (RATE/100) +--- a/iax/iax.c ++++ b/iax/iax.c +@@ -344,7 +344,7 @@ static int iax_sched_event(struct iax_event *event, struct iax_frame *frame, int + + sched = (struct iax_sched*)malloc(sizeof(struct iax_sched)); + if (sched) { +- bzero(sched, sizeof(struct iax_sched)); ++ memset(sched, 0, sizeof(struct iax_sched)); + gettimeofday(&sched->when, NULL); + sched->when.tv_sec += (ms / 1000); + ms = ms % 1000; +@@ -872,7 +872,7 @@ int iax_do_event(struct iax_session *session, struct iax_event *event) + + #define MYSNPRINTF snprintf(requeststr + strlen(requeststr), sizeof(buf) - sizeof(struct ast_iax2_full_hdr) - strlen(requeststr), + +- bzero(buf, sizeof(buf)); ++ memset(buf, 0, sizeof(buf)); + + /* Default some things in the frame */ + +@@ -1523,7 +1523,7 @@ int iax_auth_reply(struct iax_session *session, char *password, char *challenge, + MD5Update(&md5, (const unsigned char *) challenge, strlen(challenge)); + MD5Update(&md5, (const unsigned char *) password, strlen(password)); + MD5Final((unsigned char *) reply, &md5); +- bzero(realreply, sizeof(realreply)); ++ memset(realreply, 0, sizeof(realreply)); + convert_reply(realreply, (unsigned char *) reply); + iax_ie_append_str(&ied, IAX_IE_MD5_RESULT, realreply); + } else { +@@ -1546,7 +1546,7 @@ static int iax_regauth_reply(struct iax_session *session, char *password, char * + MD5Update(&md5, (const unsigned char *) challenge, strlen(challenge)); + MD5Update(&md5, (const unsigned char *) password, strlen(password)); + MD5Final((unsigned char *) reply, &md5); +- bzero(realreply, sizeof(realreply)); ++ memset(realreply, 0, sizeof(realreply)); + convert_reply(realreply, (unsigned char *) reply); + iax_ie_append_str(&ied, IAX_IE_MD5_RESULT, realreply); + } else { +--- a/modem.c ++++ b/modem.c +@@ -27,7 +27,7 @@ + #include + #include + #include +-#include ++#include + + static int baudrate=B9600, fd_modem, m_status=0; + extern int debug; +@@ -50,7 +50,7 @@ int tty_modem_init(char *dev) { + char buf[4096]; + struct termios newtio; + +- bzero(&newtio, sizeof(newtio)); ++ memset(&newtio, 0, sizeof(newtio)); + newtio.c_cflag = CRTSCTS | CS8 | CLOCAL | CREAD | O_NDELAY; + if ( fd_modem = open(dev, O_RDWR | O_NOCTTY | O_NONBLOCK) ) { + cfsetispeed(&newtio,baudrate); +--- a/oss.c ++++ b/oss.c +@@ -1,5 +1,8 @@ + #include "iaxclient_lib.h" + #include ++#include ++#include ++#include + #include + + #define RTP 320 diff --git a/net/pcapsipdump/Makefile b/net/pcapsipdump/Makefile new file mode 100644 index 000000000..8770da173 --- /dev/null +++ b/net/pcapsipdump/Makefile @@ -0,0 +1,47 @@ +# +# Copyright (C) 2009-2018 OpenWrt.org +# +# This is free software, licensed under the GNU General Public License v2. +# See /LICENSE for more information. +# + +include $(TOPDIR)/rules.mk + +PKG_NAME:=pcapsipdump + +PKG_SOURCE_PROTO:=svn +PKG_SOURCE_URL:=https://svn.code.sf.net/p/pcapsipdump/code/trunk +PKG_MIRROR_HASH:=563050f47c7962de377cab17478a86d3ea6726a331a7c77be62cb3f5488e519a +PKG_SOURCE_VERSION:=157 +PKG_SOURCE_DATE=2020-03-03 +PKG_RELEASE:=1 + +PKG_LICENSE:=GPL-2.0+ +PKG_LICENSE_FILES:=LICENSE + +include $(INCLUDE_DIR)/package.mk + +define Package/pcapsipdump + SECTION:=net + CATEGORY:=Network + SUBMENU:=Telephony + DEPENDS:=+libstdcpp +USE_GLIBC:libbsd +libpcap + TITLE:=SIP Sessions Dumping Tool + URL:=http://sourceforge.net/projects/pcapsipdump/ +endef + +define Package/pcapsipdump/description + pcapsipdump is a tool for dumping SIP sessions (plus RTP traffic, if + available) to disk in a fashion similar to "tcpdump -w" (format is + exactly the same), but one file per SIP session (even if there are + thousands of concurrent SIP sessions). +endef + +MAKE_FLAGS+=LIBS="-lpcap" + +define Package/pcapsipdump/install + $(INSTALL_DIR) $(1)/usr/bin + $(INSTALL_BIN) $(PKG_BUILD_DIR)/pcapsipdump $(1)/usr/bin/ +endef + +$(eval $(call BuildPackage,pcapsipdump)) diff --git a/net/pcapsipdump/patches/01-use-libc-strlcpy-if-available-v2.patch b/net/pcapsipdump/patches/01-use-libc-strlcpy-if-available-v2.patch new file mode 100644 index 000000000..0e784d3cd --- /dev/null +++ b/net/pcapsipdump/patches/01-use-libc-strlcpy-if-available-v2.patch @@ -0,0 +1,66 @@ +--- a/Makefile ++++ b/Makefile +@@ -2,11 +2,14 @@ LIBS ?= -lpcap -lstdc++ + RELEASEFLAGS ?= -O3 -Wall + #CXXFLAGS ?= --std=c++0x + +-# auto-detect if bsd/strings.h is available +-ifeq ($(shell $(CXX) $(CXXFLAGS) $(LDFLAGS) $(DEFS) -E -o /dev/null \ +- make-checks/libbsd.cpp 2>/dev/null; echo $$?),0) +- BSDSTR_DEFS := -DUSE_BSD_STRING_H +- BSDSTR_LIBS := -lbsd ++# check if libc provides BSD's strlcpy ++ifeq ($(shell $(CXX) $(CXXFLAGS) -D_BSD_SOURCE $(LDFLAGS) $(DEFS) -o /dev/null \ ++ make-checks/strlcpy.cpp 2>/dev/null; echo $$?),0) ++ BSDSTR_DEFS := -D_BSD_SOURCE ++# use libbsd's strlcpy ++else ++ BSDSTR_DEFS != pkg-config --cflags libbsd-overlay ++ BSDSTR_LIBS != pkg-config --libs libbsd-overlay + endif + + # auto-detect rhel/fedora and debian/ubuntu +--- a/pcapsipdump_lib.h ++++ b/pcapsipdump_lib.h +@@ -1,13 +1,5 @@ + #include + +-#ifndef BSD +- #ifdef USE_BSD_STRING_H +- #include +- #else +- #define strlcpy strncpy +- #endif +-#endif +- + // equivalent of "mkdir -p" + int mkdir_p(const char *path, mode_t mode); + +--- a/make-checks/all.mk ++++ b/make-checks/all.mk +@@ -1,5 +1,5 @@ +-make-checks/all: make-checks/cxx make-checks/libpcap make-checks/libbsd ++make-checks/all: make-checks/cxx make-checks/libpcap make-checks/strlcpy + @touch make-checks/all + + make-checks/clean: +- rm -f make-checks/all make-checks/cxx make-checks/libpcap make-checks/libbsd ++ rm -f make-checks/all make-checks/cxx make-checks/libpcap make-checks/strlcpy +--- /dev/null ++++ b/make-checks/strlcpy.cpp +@@ -0,0 +1,6 @@ ++#include ++int main(int argc, char **argv) { ++ char dst[10]; ++ strlcpy(dst, "test", sizeof(dst)); ++ return 0; ++} +--- /dev/null ++++ b/make-checks/strlcpy.mk +@@ -0,0 +1,6 @@ ++CHECK_STRLCPY = $(CXX) $(CXXFLAGS) -D_BSD_SOURCE $(LDFLAGS) make-checks/strlcpy.cpp -o make-checks/strlcpy 2>/dev/null ++ ++make-checks/strlcpy: ++ @$(CHECK_STRLCPY) || (\ ++ echo "*** notice: your libc doesn't provide strlcpy()"; \ ++ true) diff --git a/net/rtpengine/Makefile b/net/rtpengine/Makefile new file mode 100644 index 000000000..d694d4baf --- /dev/null +++ b/net/rtpengine/Makefile @@ -0,0 +1,291 @@ +# +# Copyright (C) 2020 Sebastian Kemper +# +# This is free software, licensed under the GNU General Public License v2. +# See /LICENSE for more information. +# + +include $(TOPDIR)/rules.mk +include $(INCLUDE_DIR)/kernel.mk + +PKG_NAME:=rtpengine +PKG_VERSION:=11.5.1.18 +PKG_RELEASE:=1 + +PKG_SOURCE:=$(PKG_NAME)-mr$(PKG_VERSION).tar.gz +PKG_SOURCE_URL:=https://codeload.github.com/sipwise/rtpengine/tar.gz/mr$(PKG_VERSION)? +PKG_HASH:=d5b0288ec02164b13730c14976425160d9a0b42b1c74796f8d9e59649e705fa6 + +PKG_BUILD_DIR:=$(BUILD_DIR)/$(PKG_NAME)-$(BUILD_VARIANT)/$(PKG_NAME)-mr$(PKG_VERSION) + +PKG_LICENSE:=GPL-3.0 +PKG_LICENSE_FILES:=LICENSE + +PKG_MAINTAINER:=Sebastian Kemper + +# When building in parallel, some files (like streambuf.c or dtmflib.c) +# are generated multiple times by the rtpengine build system. +# Intermittently they then contain garbage, leading to redefinition +# errors. +PKG_BUILD_PARALLEL:=0 + +PKG_BUILD_DEPENDS:=gperf/host perl/host + +# With below variable set, $(PKG_SYMVERS_DIR)/rtpengine.symvers gets generated +# from kernel-module/Module.symvers. +PKG_EXTMOD_SUBDIRS:=kernel-module + +include $(INCLUDE_DIR)/package.mk +include $(INCLUDE_DIR)/nls.mk + +ENGINE_DEPENDS := \ + +glib2 \ + +json-glib \ + +libevent2 \ + +libevent2-pthreads \ + +libhiredis \ + +libip4tc \ + +libmosquitto \ + +libopenssl \ + +libpcap \ + +libpcre2 \ + +libwebsockets-openssl \ + +libopus \ + +xmlrpc-c \ + +xmlrpc-c-client \ + +zlib + +ENGINE_DEPENDS_TRANSCODING := \ + $(ENGINE_DEPENDS) \ + +bcg729 \ + +libffmpeg-full \ + +libmariadb \ + +libspandsp3 + +RECORDING_DEPENDS := \ + +bcg729 \ + +glib2 \ + +libffmpeg-full \ + +libmariadb \ + +libopenssl \ + +libcurl + +RTPENGINE_USERID:=378 +RTPENGINE_GROUPID:=$(RTPENGINE_USERID) +RTPENGINE_USER:=$(PKG_NAME)=$(RTPENGINE_USERID):$(PKG_NAME)=$(RTPENGINE_GROUPID) + +define Package/rtpengine/Default + URL:=https://github.com/sipwise/rtpengine +endef + +define Package/rtpengine/Template +$(call Package/rtpengine/Default) + TITLE:=Sipwise RTP Engine + CATEGORY:=Network + SECTION:=net + SUBMENU:=Telephony + USERID:=$(RTPENGINE_USER) +endef + +define Package/rtpengine/description/Template +The Sipwise NGCP rtpengine is a proxy for RTP traffic and other UDP +based media traffic. It's meant to be used with the Kamailio SIP proxy +and forms a drop-in replacement for any of the other available RTP and +media proxies. +endef + +define Package/rtpengine +$(call Package/rtpengine/Template) + VARIANT:=transcode + DEPENDS := \ + $(patsubst +%,+PACKAGE_rtpengine:%,$(ENGINE_DEPENDS_TRANSCODING)) \ + +IPV6:libip6tc +endef + +define Package/rtpengine/conffiles +/etc/config/rtpengine +/etc/init.d/rtpengine +/etc/rtpengine/rtpengine.conf +endef + +define Package/rtpengine/description +$(call Package/rtpengine/description/Template) + +Please consider installing kmod-ipt-rtpengine. + +endef + +define Package/rtpengine/install + $(INSTALL_DIR) $(1)/usr/bin + $(INSTALL_BIN) $(PKG_BUILD_DIR)/daemon/rtpengine $(1)/usr/bin + + $(INSTALL_DIR) $(1)/etc/init.d + $(INSTALL_BIN) ./files/rtpengine.init $(1)/etc/init.d/rtpengine + + $(INSTALL_DIR) $(1)/etc/config + $(INSTALL_CONF) ./files/rtpengine.conf $(1)/etc/config/rtpengine + + $(INSTALL_DIR) $(1)/etc/rtpengine + $(INSTALL_DATA) $(PKG_BUILD_DIR)/etc/rtpengine.conf \ + $(1)/etc/rtpengine/rtpengine.conf + + $(INSTALL_DIR) $(1)/etc/hotplug.d/iface + $(INSTALL_BIN) ./files/rtpengine.hotplug \ + $(1)/etc/hotplug.d/iface/90-rtpengine +endef + +define Package/rtpengine-no-transcode +$(call Package/rtpengine/Template) + TITLE+= (no transcoding) + VARIANT:=no-transcode + CONFLICTS:=rtpengine + DEPENDS := \ + $(patsubst +%,+PACKAGE_rtpengine-no-transcode:%,$(ENGINE_DEPENDS)) \ + +IPV6:libip6tc +endef + +Package/rtpengine-no-transcode/conffiles=$(Package/rtpengine/conffiles) + +define Package/rtpengine-no-transcode/description +$(call Package/rtpengine/description/Template) + +This package comes without transcoding support. + +Please consider installing kmod-ipt-rtpengine. + +endef + +Package/rtpengine-no-transcode/install=$(Package/rtpengine/install) + +define Package/rtpengine-recording +$(call Package/rtpengine/Default) + TITLE:=Sipwise RTP Recording Daemon + CATEGORY:=Network + SECTION:=net + SUBMENU:=Telephony + USERID:=$(RTPENGINE_USER) + DEPENDS:=$(patsubst +%,+PACKAGE_rtpengine-recording:%,$(RECORDING_DEPENDS)) +endef + +define Package/rtpengine-recording/conffiles +/etc/config/rtpengine-recording +/etc/rtpengine/rtpengine-recording.conf +endef + +define Package/rtpengine-recording/install + $(INSTALL_DIR) $(1)/usr/bin + $(INSTALL_BIN) \ + $(PKG_BUILD_DIR)/recording-daemon/rtpengine-recording \ + $(1)/usr/bin + + $(INSTALL_DIR) $(1)/etc/init.d + $(INSTALL_BIN) ./files/rtpengine-recording.init \ + $(1)/etc/init.d/rtpengine-recording + + $(INSTALL_DIR) $(1)/etc/config + $(INSTALL_CONF) ./files/rtpengine-recording.conf \ + $(1)/etc/config/rtpengine-recording + + $(INSTALL_DIR) $(1)/etc/rtpengine + $(INSTALL_DATA) $(PKG_BUILD_DIR)/etc/rtpengine-recording.conf \ + $(1)/etc/rtpengine/rtpengine-recording.conf +endef + +define Package/iptables-mod-rtpengine +$(call Package/rtpengine/Default) + TITLE:=Sipwise rtpengine iptables extension + CATEGORY:=Network + SECTION:=net + SUBMENU:=Firewall + DEPENDS:=+PACKAGE_iptables-mod-rtpengine:libxtables +endef + +define Package/iptables-mod-rtpengine/install + $(INSTALL_DIR) $(1)/usr/lib/iptables + $(INSTALL_BIN) \ + $(PKG_BUILD_DIR)/iptables-extension/libxt_RTPENGINE.so \ + $(1)/usr/lib/iptables +endef + +define KernelPackage/ipt-rtpengine +$(call Package/rtpengine/Default) + TITLE:=Sipwise rtpengine netfilter module + SUBMENU:=Netfilter Extensions + FILES:=$(PKG_BUILD_DIR)/kernel-module/xt_RTPENGINE.$(LINUX_KMOD_SUFFIX) + AUTOLOAD:=$(call AutoProbe,xt_RTPENGINE) + DEPENDS := \ + +PACKAGE_kmod-ipt-rtpengine:kmod-crypto-aead \ + +PACKAGE_kmod-ipt-rtpengine:kmod-crypto-hash \ + +PACKAGE_kmod-ipt-rtpengine:kmod-ipt-core + MODPARAMS.xt_RTPENGINE := \ + proc_uid=$(RTPENGINE_USERID) \ + proc_gid=$(RTPENGINE_GROUPID) + USERID:=$(RTPENGINE_USER) +endef + +define KernelPackage/ipt-rtpengine/conffiles +/etc/modules.d/ipt-rtpengine +endef + +define KernelPackage/ipt-rtpengine/description +Netfilter kernel module for rtpengine + +endef + +MAKE_VARS+=RTPENGINE_VERSION=$(PKG_VERSION) + +ifeq ($(BUILD_VARIANT),no-transcode) + MAKE_VARS+=with_transcoding=no +endif + +# rtpengine uses Debian's dpkg utility programs if it can find them. But +# we don't want build host flags to leak into our cross-compile. +define Build/Prepare + $(call Build/Prepare/Default) +ifeq ($(QUILT),) + cd "$(PKG_BUILD_DIR)" && \ + $(FIND) . -maxdepth 2 -name "*Makefile" | \ + xargs -I{} $(SED) \ + '/shell which dpkg-/s/dpkg/OpenWrt-has-no-dpkg/' {} && \ + $(SED) 's|#!/usr/bin/perl|#!$(STAGING_DIR_HOSTPKG)/usr/bin/perl|' \ + utils/const_str_hash +endif +endef + +define Build/Configure +endef + +define Build/Compile + +ifneq ($(CONFIG_PACKAGE_kmod-ipt-rtpengine),) + RTPENGINE_VERSION=$(PKG_VERSION) $(MAKE) \ + $(PKG_JOBS) \ + -C $(PKG_BUILD_DIR)/kernel-module \ + KSRC=$(LINUX_DIR) \ + $(KERNEL_MAKE_FLAGS) +endif + +ifneq ($(CONFIG_PACKAGE_iptables-mod-rtpengine),) + $(call Build/Compile/Default,-C $(PKG_BUILD_DIR)/iptables-extension) +endif + +ifneq ($(CONFIG_PACKAGE_rtpengine)$(CONFIG_PACKAGE_rtpengine-no-transcode),) + $(call Build/Compile/Default,-C $(PKG_BUILD_DIR)/daemon) +endif + +ifneq ($(CONFIG_PACKAGE_rtpengine-recording),) + $(call Build/Compile/Default,-C $(PKG_BUILD_DIR)/recording-daemon) +endif + +endef + +define Build/InstallDev +endef + +# KernelPackage calls need to go first, otherwise hooks like +# collect_module_symvers won't get added. +$(eval $(call KernelPackage,ipt-rtpengine)) +$(eval $(call BuildPackage,rtpengine-no-transcode)) +$(eval $(call BuildPackage,iptables-mod-rtpengine)) +$(eval $(call BuildPackage,rtpengine)) +$(eval $(call BuildPackage,rtpengine-recording)) diff --git a/net/rtpengine/files/rtpengine-recording.conf b/net/rtpengine/files/rtpengine-recording.conf new file mode 100644 index 000000000..d0a821814 --- /dev/null +++ b/net/rtpengine/files/rtpengine-recording.conf @@ -0,0 +1,10 @@ +config rtpengine-recording global + option enabled 0 # 0 - disabled, 1 - enabled + +# You can start multiple instances. You must specify a section name from +# "/etc/rtpengine/rtpengine-recording.conf". + +config instance 'instance1' + option section 'rtpengine-recording' + option opts '--log-level=6' # Options passed to rtpengine-recording + # instance. diff --git a/net/rtpengine/files/rtpengine-recording.init b/net/rtpengine/files/rtpengine-recording.init new file mode 100644 index 000000000..cd5badcf3 --- /dev/null +++ b/net/rtpengine/files/rtpengine-recording.init @@ -0,0 +1,51 @@ +#!/bin/sh /etc/rc.common + +START=91 + +NAME=rtpengine-recording +COMMAND="/usr/bin/$NAME" + +USE_PROCD=1 + +#PROCD_DEBUG=1 + +LOGGER="/usr/bin/logger -t $NAME" +LOG_ERR="$LOGGER -p user.err -s" + +run_instance() { + procd_open_instance + procd_set_param command $COMMAND + procd_append_param command \ + --config-file=/etc/rtpengine/$NAME.conf \ + --config-section="$2" \ + $3 \ + -f + # forward all output to logd + procd_set_param stderr 1 + procd_set_param stdout 1 + procd_set_param pidfile "/var/run/$NAME-$1.pid" + procd_set_param user rtpengine + procd_close_instance + + $LOGGER instance "$1" has started +} + +handle_instance() { + config_get opts "$1" opts + config_get section "$1" section + + run_instance "$1" "$section" "$opts" +} + +start_service() { + config_load $NAME + + config_get_bool enabled global enabled 0 + + if [ "$enabled" -eq 1 ]; then + config_foreach handle_instance instance + else + $LOG_ERR service not enabled + $LOG_ERR edit /etc/config/$NAME + fi +} diff --git a/net/rtpengine/files/rtpengine.conf b/net/rtpengine/files/rtpengine.conf new file mode 100644 index 000000000..93d9e20d2 --- /dev/null +++ b/net/rtpengine/files/rtpengine.conf @@ -0,0 +1,17 @@ +config rtpengine global + option enabled 0 # 0 - disabled, 1 - enabled + +# You can start multiple instances. You must specify a section name from +# "/etc/rtpengine/rtpengine.conf". + +config instance 'instance1' + option section 'rtpengine' + option opts '--log-level=6' # Options passed to rtpengine + # instance. + +#config instance 'instance2' + #option section 'rtpengine-testing' + #option opts '' + +config rtpengine 'hotplug' + #option interface 'wan' # uncomment to enable hotplug diff --git a/net/rtpengine/files/rtpengine.hotplug b/net/rtpengine/files/rtpengine.hotplug new file mode 100644 index 000000000..3fa3f0921 --- /dev/null +++ b/net/rtpengine/files/rtpengine.hotplug @@ -0,0 +1,23 @@ +#!/bin/sh + +[ "$ACTION" = ifup ] || exit 0 + +NAME=rtpengine +COMMAND=/etc/init.d/$NAME +LOGGER="/usr/bin/logger -t hotplug" + +$COMMAND enabled || exit 0 + +. /lib/functions.sh + +config_load $NAME + +config_get_bool enabled global enabled 0 +[ $enabled -eq 0 ] && exit 0 + +config_get hotplug_iface hotplug interface + +[ "$INTERFACE" = "$hotplug_iface" ] && { + $LOGGER "Restarting $NAME due to \"$ACTION\" of \"$INTERFACE\"" + $COMMAND restart +} diff --git a/net/rtpengine/files/rtpengine.init b/net/rtpengine/files/rtpengine.init new file mode 100644 index 000000000..d56912a3b --- /dev/null +++ b/net/rtpengine/files/rtpengine.init @@ -0,0 +1,58 @@ +#!/bin/sh /etc/rc.common + +START=90 + +NAME=rtpengine +COMMAND="/usr/bin/$NAME" + +USE_PROCD=1 + +#PROCD_DEBUG=1 + +LOGGER="/usr/bin/logger -t $NAME" +LOG_ERR="$LOGGER -p user.err -s" + +run_instance() { + procd_open_instance + procd_set_param command $COMMAND + procd_append_param command \ + --config-file=/etc/$NAME/$NAME.conf \ + --config-section="$2" \ + $3 \ + -f + # forward all output to logd + procd_set_param stderr 1 + procd_set_param stdout 1 + procd_set_param pidfile "/var/run/$NAME-$1.pid" + procd_set_param user $NAME + procd_close_instance + + $LOGGER instance "$1" has started +} + +handle_instance() { + config_get opts "$1" opts + config_get section "$1" section + + run_instance "$1" "$section" "$opts" +} + +start_service() { + config_load $NAME + + config_get_bool enabled global enabled 0 + + rtp_spool_dir=/var/spool/rtpengine + + if [ "$enabled" -eq 1 ]; then + if ! [ -e "$rtp_spool_dir" ]; then + mkdir -m 0750 -p "$rtp_spool_dir" + [ -d "$rtp_spool_dir" ] && \ + chown $NAME:$NAME "$rtp_spool_dir" + fi + config_foreach handle_instance instance + else + $LOG_ERR service not enabled + $LOG_ERR edit /etc/config/$NAME + fi +} diff --git a/net/rtpengine/patches/04-prevent-systemd-detection.patch b/net/rtpengine/patches/04-prevent-systemd-detection.patch new file mode 100644 index 000000000..33c1727cb --- /dev/null +++ b/net/rtpengine/patches/04-prevent-systemd-detection.patch @@ -0,0 +1,17 @@ +--- a/lib/lib.Makefile ++++ b/lib/lib.Makefile +@@ -35,10 +35,10 @@ ifeq ($(RTPENGINE_VERSION),) + endif + CFLAGS+= -DRTPENGINE_VERSION="\"$(RTPENGINE_VERSION)\"" + +-# look for libsystemd +-ifeq ($(shell pkg-config --exists libsystemd && echo yes),yes) +-have_libsystemd := yes +-endif ++# No libsystemd in OpenWrt, but pkg-config could find build host's. ++#ifeq ($(shell pkg-config --exists libsystemd && echo yes),yes) ++have_libsystemd := no ++#endif + ifeq ($(have_libsystemd),yes) + CFLAGS+= $(shell pkg-config --cflags libsystemd) + CFLAGS+= -DHAVE_LIBSYSTEMD diff --git a/net/rtpengine/patches/05-use-spandsp3.patch b/net/rtpengine/patches/05-use-spandsp3.patch new file mode 100644 index 000000000..1e7535972 --- /dev/null +++ b/net/rtpengine/patches/05-use-spandsp3.patch @@ -0,0 +1,20 @@ +--- a/daemon/Makefile ++++ b/daemon/Makefile +@@ -32,7 +32,7 @@ CFLAGS+= $(shell pkg-config --cflags lib + CFLAGS+= $(shell pkg-config --cflags libavutil) + CFLAGS+= $(shell pkg-config --cflags libswresample) + CFLAGS+= $(shell pkg-config --cflags libavfilter) +-CFLAGS+= $(shell pkg-config --cflags spandsp) ++CFLAGS+= $(shell pkg-config --cflags spandsp3) + CFLAGS+= $(shell pkg-config --cflags opus) + CFLAGS+= -DWITH_TRANSCODING + CFLAGS+= $(shell mysql_config --cflags) +@@ -68,7 +68,7 @@ LDLIBS+= $(shell pkg-config --libs libav + LDLIBS+= $(shell pkg-config --libs libavutil) + LDLIBS+= $(shell pkg-config --libs libswresample) + LDLIBS+= $(shell pkg-config --libs libavfilter) +-LDLIBS+= $(shell pkg-config --libs spandsp) ++LDLIBS+= $(shell pkg-config --libs spandsp3) + LDLIBS+= $(shell pkg-config --libs opus) + LDLIBS+= $(shell mysql_config --libs) + endif diff --git a/net/rtpengine/patches/07-always-dynamically-allocate-buffer-for-kernel-mod.patch b/net/rtpengine/patches/07-always-dynamically-allocate-buffer-for-kernel-mod.patch new file mode 100644 index 000000000..daeb5c381 --- /dev/null +++ b/net/rtpengine/patches/07-always-dynamically-allocate-buffer-for-kernel-mod.patch @@ -0,0 +1,46 @@ +--- a/kernel-module/xt_RTPENGINE.c ++++ b/kernel-module/xt_RTPENGINE.c +@@ -3781,7 +3781,6 @@ static inline ssize_t proc_control_read_ + struct rtpengine_table *t; + int err; + enum rtpengine_command cmd; +- char scratchbuf[512]; + size_t readlen, writelen, writeoffset; + int i; + +@@ -3823,13 +3822,9 @@ static inline ssize_t proc_control_read_ + return -ERANGE; + + // do we need an extra large storage buffer? +- if (buflen > sizeof(scratchbuf)) { +- msg.storage = kmalloc(buflen, GFP_KERNEL); +- if (!msg.storage) +- return -ENOMEM; +- } +- else +- msg.storage = scratchbuf; ++ msg.storage = kmalloc(buflen, GFP_KERNEL); ++ if (!msg.storage) ++ return -ENOMEM; + + // get our table + inode = file->f_path.dentry->d_inode; +@@ -3942,16 +3937,14 @@ static inline ssize_t proc_control_read_ + goto err_free; + } + +- if (msg.storage != scratchbuf) +- kfree(msg.storage); ++ kfree(msg.storage); + + return buflen; + + err_table_free: + table_put(t); + err_free: +- if (msg.storage != scratchbuf) +- kfree(msg.storage); ++ kfree(msg.storage); + return err; + } + static ssize_t proc_control_write(struct file *file, const char __user *ubuf, size_t buflen, loff_t *off) { diff --git a/net/rtpengine/patches/08-no-docs.patch b/net/rtpengine/patches/08-no-docs.patch new file mode 100644 index 000000000..b93af2bf0 --- /dev/null +++ b/net/rtpengine/patches/08-no-docs.patch @@ -0,0 +1,43 @@ +--- a/lib/common.Makefile ++++ b/lib/common.Makefile +@@ -34,12 +34,6 @@ $(DAEMONSRCS) $(HASHSRCS): $(patsubst %, + echo '#line 1' && \ + cat ../daemon/"$@" ) > "$@" + +-%.8: ../docs/%.md +- cat "$<" | sed '/^# /d; s/^##/#/' | \ +- pandoc -s -t man \ +- -M "footer:$(RTPENGINE_VERSION)" \ +- -M "date:$(BUILD_DATE)" \ +- -o "$@" + + resample.c codeclib.strhash.c mix.c packet.c: fix_frame_channel_layout.h + +--- a/daemon/Makefile ++++ b/daemon/Makefile +@@ -93,11 +93,8 @@ LIBASM= mvr2s_x64_avx2.S mvr2s_x64_avx5 + endif + OBJS= $(SRCS:.c=.o) $(LIBSRCS:.c=.o) $(LIBASM:.S=.o) + +-MDS= rtpengine.ronn +-MANS= $(MDS:.ronn=.8) + + include ../lib/common.Makefile + + install: $(TARGET) $(MANS) + install -m 0755 -D $(TARGET) $(DESTDIR)/usr/bin/$(TARGET) +- install -m 0644 -D $(TARGET).8 $(DESTDIR)/usr/share/man/man8/$(TARGET).8 +--- a/recording-daemon/Makefile ++++ b/recording-daemon/Makefile +@@ -39,11 +39,8 @@ LIBSRCS= loglib.c auxlib.c rtplib.c code + LIBASM= mvr2s_x64_avx2.S mvr2s_x64_avx512.S mix_in_x64_avx2.S mix_in_x64_avx512bw.S mix_in_x64_sse2.S + OBJS= $(SRCS:.c=.o) $(LIBSRCS:.c=.o) $(LIBASM:.S=.o) + +-MDS= rtpengine-recording.ronn +-MANS= $(MDS:.ronn=.8) + + include ../lib/common.Makefile + + install: $(TARGET) $(MANS) + install -m 0755 -D $(TARGET) $(DESTDIR)/usr/bin/$(TARGET) +- install -m 0644 -D $(TARGET).8 $(DESTDIR)/usr/share/man/man8/$(TARGET).8 diff --git a/net/rtpproxy/Makefile b/net/rtpproxy/Makefile new file mode 100644 index 000000000..829b99153 --- /dev/null +++ b/net/rtpproxy/Makefile @@ -0,0 +1,128 @@ +# +# Copyright (C) 2014 - 2018 OpenWrt.org +# Copyright (C) 2017 - 2018 Jiri Slachta +# +# This is free software, licensed under the GNU General Public License v2. +# See /LICENSE for more information. +# + +include $(TOPDIR)/rules.mk + +PKG_NAME:=rtpproxy + +PKG_SOURCE_PROTO:=git +PKG_SOURCE_URL:=https://github.com/sippy/rtpproxy.git +PKG_SOURCE_DATE=2019-10-02 +PKG_SOURCE_VERSION:=aa1f179e09097f467bc4726e3300014c1e35246f +PKG_RELEASE:=4 +PKG_MIRROR_HASH:=36ecff6b69b580db5fe7e34e1d6764f111aa26ce81999743cea1f3c80ffa545c + +PKG_BUILD_PARALLEL:=1 +PKG_INSTALL:=1 + +PKG_FIXUP:=autoreconf + +PKG_LICENSE:=BSD-2-Clause +PKG_LICENSE_FILES:=LICENSE +PKG_MAINTAINER:=Jiri Slachta + +include $(INCLUDE_DIR)/package.mk + +define Package/rtpproxy/Default + SECTION:=net + CATEGORY:=Network + SUBMENU:=Telephony + URL:=http://www.rtpproxy.org/ +endef + +define Package/rtpproxy +$(call Package/rtpproxy/Default) + DEPENDS:=+libatomic +libpthread +librt + TITLE:=RTP (Realtime Transport Protocol) proxy + MENU:=1 +endef + +define Package/rtpproxy/conffiles +/etc/init.d/rtpproxy +/etc/config/rtpproxy +endef + +define Package/rtpproxy-mod-acct-csv +$(call Package/rtpproxy/Default) + DEPENDS:=rtpproxy + TITLE:=RTPproxy CSV accounting module +endef + +define Package/rtpproxy-mod-acct-rtcp-hep +$(call Package/rtpproxy/Default) + DEPENDS:=rtpproxy + TITLE:=RTPproxy RTCP HEP accounting module +endef + +CONFIGURE_ARGS += \ + --without-xsltproc + +# Otherwise OpenWrt's CPPFLAGS are ignored +TARGET_CFLAGS+=$(TARGET_CPPFLAGS) + +define Package/rtpproxy/install + $(INSTALL_DIR) $(1)/usr/bin + $(INSTALL_BIN) $(PKG_INSTALL_DIR)/usr/bin/rtpproxy $(1)/usr/bin + + $(INSTALL_DIR) $(1)/etc/init.d + $(INSTALL_BIN) ./files/rtpproxy.init $(1)/etc/init.d/rtpproxy + + $(INSTALL_DIR) $(1)/etc/config + $(INSTALL_CONF) ./files/rtpproxy.conf $(1)/etc/config/rtpproxy + + $(INSTALL_DIR) $(1)/etc/hotplug.d/iface + $(INSTALL_BIN) ./files/rtpproxy.hotplug $(1)/etc/hotplug.d/iface/90-rtpproxy +endef + +define Package/rtpproxy/postinst +#!/bin/sh +if [ -z "$${IPKG_INSTROOT}" ]; then + echo + echo "o-------------------------------------------------------------------o" + echo "| RTPProxy note |" + echo "o-------------------------------------------------------------------o" + echo "| Edit /etc/config/rtpproxy to change basic init configuration. |" + echo "o-------------------------------------------------------------=^_^=-o" + echo +fi +exit 0 +endef + +define Package/rtpproxy-mod-acct-csv/install + $(INSTALL_DIR) $(1)/usr/lib/rtpproxy + $(INSTALL_BIN) $(PKG_INSTALL_DIR)/usr/lib/rtpproxy/rtpp_acct_csv.so \ + $(1)/usr/lib/rtpproxy +endef + +define Package/rtpproxy-mod-acct-rtcp-hep/install + $(INSTALL_DIR) $(1)/usr/lib/rtpproxy + $(INSTALL_BIN) \ + $(PKG_INSTALL_DIR)/usr/lib/rtpproxy/rtpp_acct_rtcp_hep.so \ + $(1)/usr/lib/rtpproxy +endef + +define Package/$(PKG_NAME)/Util + define Package/$(PKG_NAME)-util-$(1) + $(call Package/$(PKG_NAME)/Default) + DEPENDS:= $(PKG_NAME) $(patsubst +%,+PACKAGE_$(PKG_NAME)-util-$(1):%,$(2)) + TITLE:=RTPproxy $(1) utility + endef + + define Package/$(PKG_NAME)-util-$(1)/install + $$(INSTALL_DIR) $$(1)/usr/bin + $$(INSTALL_BIN) $$(PKG_INSTALL_DIR)/usr/bin/$(1) $$(1)/usr/bin + endef + + $$(eval $$(call BuildPackage,$(PKG_NAME)-util-$(1))) +endef + +$(eval $(call BuildPackage,rtpproxy)) +$(eval $(call BuildPackage,rtpproxy-mod-acct-csv)) +$(eval $(call BuildPackage,rtpproxy-mod-acct-rtcp-hep)) +$(eval $(call Package/$(PKG_NAME)/Util,extractaudio,+bcg729 +libsndfile +libsrtp2)) +$(eval $(call Package/$(PKG_NAME)/Util,makeann,+bcg729)) diff --git a/net/rtpproxy/files/rtpproxy.conf b/net/rtpproxy/files/rtpproxy.conf new file mode 100644 index 000000000..afcf1b2f1 --- /dev/null +++ b/net/rtpproxy/files/rtpproxy.conf @@ -0,0 +1,23 @@ +config rtpproxy global + option enabled 0 # 0 - disabled, 1 - enabled + +config instance 'site1' + option socket 'udp:127.0.0.1:7723' # socket + option ipaddr '127.0.0.1' # IPv4 address + option ip6addr '2001:0db8:0000:0000:0000:0000:1428:57ab' # IPv6 address + option user 'nobody' # userid to run rtpproxy instance from + option log_level 'INFO' # DBUG, INFO, WARN, ERR or CRIT + option opts '' # additional options for rtpproxy instance + +config instance 'site2' + option socket 'udp:127.0.0.1:7724' + option ipaddr 'lan/wan' # Bridge mode. 'lan' and 'wan' will be + option user 'nobody' # translated to IPv4 addresses by init + option log_level 'DBUG' # script. Handy if using dynamic IPs. Can + option opts '' # also be used with single interfaces. + # Translation for both 'ipaddr' and + # 'ip6addr' supported. + +config rtpproxy 'hotplug' + #option interface 'wan' # uncomment to enable hotplug + diff --git a/net/rtpproxy/files/rtpproxy.hotplug b/net/rtpproxy/files/rtpproxy.hotplug new file mode 100644 index 000000000..dfa69818d --- /dev/null +++ b/net/rtpproxy/files/rtpproxy.hotplug @@ -0,0 +1,24 @@ +#!/bin/sh + +[ "$ACTION" = ifup ] || exit 0 + +NAME=rtpproxy +COMMAND=/etc/init.d/$NAME +LOGGER="/usr/bin/logger -t hotplug" + +$COMMAND enabled || exit 0 + +. /lib/functions.sh + +config_load $NAME + +config_get_bool enabled global enabled 0 +[ $enabled -eq 0 ] && exit 0 + +config_get hotplug_iface hotplug interface + +[ "$INTERFACE" = "$hotplug_iface" ] && { + $LOGGER "Restarting $NAME due to \"$ACTION\" of \"$INTERFACE\"" + $COMMAND restart +} + diff --git a/net/rtpproxy/files/rtpproxy.init b/net/rtpproxy/files/rtpproxy.init new file mode 100644 index 000000000..4c94ba255 --- /dev/null +++ b/net/rtpproxy/files/rtpproxy.init @@ -0,0 +1,133 @@ +#!/bin/sh /etc/rc.common +# Copyright (C) 2014 CESNET, z.s.p.o +# Copyright (C) 2018 OpenWrt.org + +START=90 + +NAME=rtpproxy +COMMAND="/usr/bin/$NAME" + +USE_PROCD=1 + +#PROCD_DEBUG=1 + +LOGGER="/usr/bin/logger -t $NAME" +LOG_ERR="$LOGGER -p user.err -s" + +run_instance() { + procd_open_instance + procd_set_param command $COMMAND + procd_append_param command \ + $1 \ + -p "/var/run/$NAME-$2.pid" \ + -f + # forward stderr to logd + procd_set_param stderr 1 + procd_close_instance + + $LOGGER instance $2 has started +} + +check_ip() { + local tmp_addr + + if [ "$1" = "ipaddr" ]; then + network_get_ipaddr tmp_addr "$2" || tmp_addr="$2" + else + network_get_ipaddr6 tmp_addr "$2" || tmp_addr="$2" + fi + + echo "$tmp_addr" +} + +check_ipaddr() { + local value="$1" + local type="$2" + local param="$3" + local one two + + [ -z "$value" ] && { + $LOG_ERR empty $type entry + return 1 + } + + # Bail if more than 1 slash. + [ $(echo "$value" | awk -F "/" '{print NF-1}') -gt 1 ] && { + $LOG_ERR init script does not understand $type entry \""$value"\" + return 1 + } + + IFS="/" read one two << EOF +$value +EOF + + one="$(check_ip "$type" "$one")" + if [ -n "$two" ]; then + two="$(check_ip "$type" "$two")" + rtpproxy_options=$rtpproxy_options" $param $one/$two" + else + rtpproxy_options=$rtpproxy_options" $param $one" + fi +} + +check_param() { + local param="$1" + local value="$2" + local default_value="$3" + + if [ "$value" != "" ]; then + rtpproxy_options=$rtpproxy_options" $param $value" + else + if [ "$default_value" != "" ]; then + rtpproxy_options=$rtpproxy_options" $param $default_value" + fi + fi +} + +check_special_param() { + local param="$1" + + if [ "$param" != "" ]; then + rtpproxy_options=$rtpproxy_options" $param" + fi +} + +handle_instance() { + local site="$1" + local socket opts ipaddr ip6addr rtpproxy_options log_level + + config_get socket "$site" socket + config_get opts "$site" opts + config_get ipaddr "$site" ipaddr + config_get ip6addr "$site" ip6addr + config_get user "$site" user + config_get log_level "$site" log_level + + check_param "-s" "$socket" + check_param "-u" "$user" "nobody" + check_param "-d" "$log_level" "DBUG" + + check_special_param "$opts" + + [ -n "$ipaddr" ] && check_ipaddr "$ipaddr" ipaddr '-l' + [ -n "$ip6addr" ] && check_ipaddr "$ip6addr" ip6addr '-6' + + run_instance "$rtpproxy_options" "$site" +} + +start_service() { + local enabled + + config_load $NAME + + config_get_bool enabled global enabled 0 + + if [ "$enabled" -eq 1 ]; then + . /lib/functions/network.sh + config_foreach handle_instance instance + else + $LOG_ERR service not enabled + $LOG_ERR edit /etc/config/$NAME + fi +} + diff --git a/net/rtpproxy/patches/102-don-t-build-rtpproxy_debug.patch b/net/rtpproxy/patches/102-don-t-build-rtpproxy_debug.patch new file mode 100644 index 000000000..ba0ff6c32 --- /dev/null +++ b/net/rtpproxy/patches/102-don-t-build-rtpproxy_debug.patch @@ -0,0 +1,32 @@ +--- a/src/Makefile.am ++++ b/src/Makefile.am +@@ -5,7 +5,7 @@ include $(top_srcdir)/autosrc/Makefile.a + + UCL_DIR=$(top_srcdir)/external/libucl + +-bin_PROGRAMS=rtpproxy rtpproxy_debug ++bin_PROGRAMS=rtpproxy + noinst_PROGRAMS = rtpp_rzmalloc_perf rtpp_fintest + + if BUILD_OBJCK +--- a/modules/acct_csv/Makefile.am ++++ b/modules/acct_csv/Makefile.am +@@ -1,6 +1,6 @@ + include $(top_srcdir)/m4/memdeb.ami + +-pkglib_LTLIBRARIES = rtpp_acct_csv.la rtpp_acct_csv_debug.la ++pkglib_LTLIBRARIES = rtpp_acct_csv.la + + rtpp_acct_csv_la_SOURCES = rtpp_acct_csv.c + rtpp_acct_csv_la_LDFLAGS = -avoid-version -module -shared -export-dynamic +--- a/modules/acct_rtcp_hep/Makefile.am ++++ b/modules/acct_rtcp_hep/Makefile.am +@@ -3,7 +3,7 @@ include $(top_srcdir)/m4/memdeb.ami + HEPSRCDIR=$(top_srcdir)/hepconnector + UCLSRCDIR=$(top_srcdir)/external/libucl + +-pkglib_LTLIBRARIES = rtpp_acct_rtcp_hep.la rtpp_acct_rtcp_hep_debug.la ++pkglib_LTLIBRARIES = rtpp_acct_rtcp_hep.la + + noinst_PROGRAMS = rtcp2json_test + rtcp2json_test_SOURCES = rtcp2json_test.c rtpp_sbuf.c rtcp2json.c diff --git a/net/rtpproxy/patches/103-fix-rtp-crypto-setup.patch b/net/rtpproxy/patches/103-fix-rtp-crypto-setup.patch new file mode 100644 index 000000000..b7ec0daad --- /dev/null +++ b/net/rtpproxy/patches/103-fix-rtp-crypto-setup.patch @@ -0,0 +1,76 @@ +commit aa43d358634ab9bf66250babab743a846e2bd689 +Author: Sebastian Kemper +Date: Thu Oct 3 19:58:08 2019 +0200 + + Fix RTP crypto setup + + RTPProxy's configure script checks for both libsrtp and libsrtp2. When + both are available the configure script ends up setting + + LIBS_SRTP="-lsrtp2" + + and defining both ENABLE_SRTP and ENABLE_SRTP2. But the below + preprocessor macro in extractaudio/eaud_crypto.c can only deal with one + or the other, not both: + + #if ENABLE_SRTP + # include + # define srtp_crypto_policy_set_rtp_default crypto_policy_set_rtp_default + # define srtp_crypto_policy_set_rtcp_default crypto_policy_set_rtcp_default + # define srtp_sec_serv_t sec_serv_t + # define srtp_err_status_ok err_status_ok + #elif ENABLE_SRTP2 + # include + #else + # error "One of srtp or srtp2 must be configured." + #endif + + So it chooses a setup which would be valid for libsrtp and not libsrtp2. + But afterward the build system tries to link against libsrtp2 (because + of LIBS_SRTP="-lsrtp2") and the compile fails: + + /home/sk/tmp/openwrt/staging_dir/toolchain-mips_24kc_gcc-7.4.0_musl/lib/gcc/mips-openwrt-linux-musl/7.4.0/../../../../mips-openwrt-linux-musl/bin/ld: extractaudio-eaud_crypto.o: in function `eaud_crypto_getopt_parse': + eaud_crypto.c:(.text+0xc8): undefined reference to `crypto_policy_set_rtp_default' + /home/sk/tmp/openwrt/staging_dir/toolchain-mips_24kc_gcc-7.4.0_musl/lib/gcc/mips-openwrt-linux-musl/7.4.0/../../../../mips-openwrt-linux-musl/bin/ld: eaud_crypto.c:(.text+0xd0): undefined reference to `crypto_policy_set_rtcp_default' + collect2: error: ld returned 1 exit status + make[4]: *** [Makefile:567: extractaudio] Error 1 + + Fix this by checking for libsrtp only if libsrtp2 is not found. + + Signed-off-by: Sebastian Kemper + +--- a/configure.ac ++++ b/configure.ac +@@ -140,22 +140,22 @@ then + AC_DEFINE([ENABLE_SNDFILE], 1, [Define if you have libsndfile library installed])) + fi + +-# libsrtp +-AC_CHECK_HEADER(srtp/srtp.h, found_libsrtp=yes) +-if test "$found_libsrtp" = yes +-then +- AC_CHECK_LIB(srtp, srtp_init, +- LIBS_SRTP="-lsrtp" +- AC_DEFINE([ENABLE_SRTP], 1, [Define if you have libsrtp library installed])) +-fi +- +-# libsrtp2 ++# libsrtp2 (preferred) + AC_CHECK_HEADER(srtp2/srtp.h, found_libsrtp2=yes) + if test "$found_libsrtp2" = yes + then + AC_CHECK_LIB(srtp2, srtp_init, + LIBS_SRTP="-lsrtp2" + AC_DEFINE([ENABLE_SRTP2], 1, [Define if you have libsrtp2 library installed])) ++else ++ # libsrtp ++ AC_CHECK_HEADER(srtp/srtp.h, found_libsrtp=yes) ++ if test "$found_libsrtp" = yes ++ then ++ AC_CHECK_LIB(srtp, srtp_init, ++ LIBS_SRTP="-lsrtp" ++ AC_DEFINE([ENABLE_SRTP], 1, [Define if you have libsrtp library installed])) ++ fi + fi + + # libelperiodic diff --git a/net/rtpproxy/patches/104-Resolve-build-breakage-after-ekt-member-of-the-polic.patch b/net/rtpproxy/patches/104-Resolve-build-breakage-after-ekt-member-of-the-polic.patch new file mode 100644 index 000000000..0640e4f44 --- /dev/null +++ b/net/rtpproxy/patches/104-Resolve-build-breakage-after-ekt-member-of-the-polic.patch @@ -0,0 +1,23 @@ +From f6c1f9e5924246216a05c295f450989ad9c80104 Mon Sep 17 00:00:00 2001 +From: Maksym Sobolyev +Date: Thu, 13 May 2021 11:42:29 -0700 +Subject: [PATCH] Resolve build breakage after ekt member of the policy struct + has been deprecated by the libsrtp. We have not been using that member to do + anything meaningful anyhow and the struct is inied to \0, so it should have + no adverse effect. + +--- + extractaudio/eaud_crypto.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/extractaudio/eaud_crypto.c ++++ b/extractaudio/eaud_crypto.c +@@ -153,7 +153,7 @@ eaud_crypto_getopt_parse(char *optarg) + srtp_crypto_policy_set_rtp_default(&rval->policy.rtp); + srtp_crypto_policy_set_rtcp_default(&rval->policy.rtcp); + rval->policy.key = (uint8_t *)rval->key; +- rval->policy.ekt = NULL; rval->policy.next = NULL; ++ rval->policy.next = NULL; + rval->policy.window_size = 128; + rval->policy.allow_repeat_tx = 0; + rval->policy.rtp.auth_tag_len = suite->tag_size; diff --git a/net/sipgrep/Makefile b/net/sipgrep/Makefile new file mode 100644 index 000000000..f8a2fca44 --- /dev/null +++ b/net/sipgrep/Makefile @@ -0,0 +1,54 @@ +# +# Copyright (C) 2016 - 2018 Daniel Engberg +# Copyright (C) 2018 OpenWrt.org +# +# This is free software, licensed under the GNU General Public License v2. +# See /LICENSE for more information. +# + +include $(TOPDIR)/rules.mk + +PKG_NAME:=sipgrep +PKG_MAINTAINER:=Sebastian Kemper +PKG_LICENSE:=GPL-3.0 +PKG_LICENSE_FILES:=COPYING + +PKG_SOURCE_PROTO:=git +PKG_SOURCE_URL:=https://github.com/sipcapture/sipgrep.git +PKG_SOURCE_VERSION:=1cc00079cd80310f7e8b1a696e9a02b8a2b25e04 +PKG_SOURCE_DATE=2019-06-27 +PKG_RELEASE:=3 +PKG_MIRROR_HASH:=2c90b4e262be7270bcc9a2de975adbe8f67dee5ff0c30b397036f2e69229f515 + +PKG_BUILD_PARALLEL:=1 +PKG_FIXUP:=autoreconf + +PKG_INSTALL:=1 + +PKG_CONFIG_DEPENDS:=CONFIG_IPV6 + +include $(INCLUDE_DIR)/package.mk + +define Package/sipgrep + SECTION:=utils + CATEGORY:=Utilities + SUBMENU:=Telephony + DEPENDS:=+libpcap +libpcre2 + TITLE:=Command line tool to sniff, capture, display SIP messages + URL:=https://github.com/sipcapture/sipgrep +endef + +define Package/sipgrep/description +Powerful pcap-aware command line tool to sniff, capture, display and +troubleshoot SIP signaling over IP networks, allowing the user to +specify extended regular expressions matching against SIP headers. +endef + +CONFIGURE_ARGS+=$(if $(CONFIG_IPV6),--enable-ipv6) + +define Package/sipgrep/install + $(INSTALL_DIR) $(1)/usr/bin + $(INSTALL_BIN) $(PKG_INSTALL_DIR)/usr/bin/sipgrep $(1)/usr/bin +endef + +$(eval $(call BuildPackage,sipgrep)) diff --git a/net/sipgrep/patches/001-Move-to-PCRE2-from-PCRE.patch b/net/sipgrep/patches/001-Move-to-PCRE2-from-PCRE.patch new file mode 100644 index 000000000..524ae07e1 --- /dev/null +++ b/net/sipgrep/patches/001-Move-to-PCRE2-from-PCRE.patch @@ -0,0 +1,199 @@ +From fea1a27f5fbef28243620fa66909d2d04c81e140 Mon Sep 17 00:00:00 2001 +From: Christian Marangi +Date: Thu, 2 Nov 2023 21:16:07 +0100 +Subject: [PATCH] Move to PCRE2 from PCRE + +Move to PCRE2 as PCRE is EOL and won't receive any security updates +anymore. + +Convert each function to PCRE2 equivalent and update configure.ac to +USE_PCRE2. + +Signed-off-by: Christian Marangi +--- + configure.ac | 20 +++++++++--------- + src/config.h.in | 4 ++-- + src/sipgrep.c | 56 ++++++++++++++++++++++++++++++------------------- + 3 files changed, 47 insertions(+), 33 deletions(-) + +--- a/configure.ac ++++ b/configure.ac +@@ -26,8 +26,8 @@ AC_ARG_ENABLE(ssl, + AC_MSG_RESULT([$SSL]) + AC_SUBST([SSL]) + +-usePCRE=yes +-AC_SUBST([PCRE]) ++usePCRE2=yes ++AC_SUBST([PCRE2]) + + useNCURSES=no + AC_MSG_CHECKING([whether to use ncurses]) +@@ -169,15 +169,15 @@ AC_SUBST(PCAP_LIBS) + + + dnl +-dnl check for pcre library ++dnl check for pcre2 library + dnl + +-# Checks for libpcre +-AC_CHECKING([for pcre Library and Header files]) +-AC_CHECK_HEADER([pcre.h], ,AC_MSG_ERROR([Could not find pcre headers !])) +-AC_CHECK_LIB([pcre], [pcre_compile], ,[AC_MSG_ERROR([libpcre required])]) +-AC_DEFINE(USE_PCRE, 1, [Use PCRE library]) +-AC_SUBST(PCRE_LIBS) ++# Checks for libpcre2 ++AC_CHECKING([for pcre2 Library and Header files]) ++AC_CHECK_HEADER([pcre2.h], ,AC_MSG_ERROR([Could not find pcre2 headers !]), [#define PCRE2_CODE_UNIT_WIDTH 8]) ++AC_CHECK_LIB([pcre2-8], [pcre2_compile_8], ,[AC_MSG_ERROR([libpcre2 required])]) ++AC_DEFINE(USE_PCRE2, 1, [Use PCRE2 library]) ++AC_SUBST(PCRE2_LIBS) + + + dnl +@@ -271,6 +271,6 @@ echo Ncurses support............. : $use + + echo + echo Build with REDIS............ : $useRedis +-echo Build with PCRE............. : $usePCRE ++echo Build with PCRE............. : $usePCRE2 + echo + +--- a/src/config.h.in ++++ b/src/config.h.in +@@ -152,8 +152,8 @@ + /* Use NCURSES library */ + #undef USE_NCURSES + +-/* Use PCRE library */ +-#undef USE_PCRE ++/* Use PCRE2 library */ ++#undef USE_PCRE2 + + /* Use REDIS library */ + #undef USE_REDIS +--- a/src/sipgrep.c ++++ b/src/sipgrep.c +@@ -88,7 +88,8 @@ + + #include + +-#include ++#define PCRE2_CODE_UNIT_WIDTH 8 ++#include + + /* reasambling */ + #include "include/ipreasm.h" +@@ -149,17 +150,18 @@ struct statistics_table *statstable = NU + * GNU PCRE + */ + +-int32_t err_offset; +-char *re_err = NULL; ++PCRE2_UCHAR re_err[128]; ++PCRE2_SIZE err_offset; ++uint32_t err_code; + +-pcre *pattern = NULL; +-pcre_extra *pattern_extra = NULL; ++pcre2_code *pattern = NULL; + + /* + * Matching + */ + +-char *match_data = NULL, *bin_data = NULL; ++PCRE2_SPTR match_data = NULL; ++char *bin_data = NULL; + uint16_t match_len = 0; + int8_t (*match_func) () = &blank_match_func; + +@@ -550,13 +552,13 @@ main (int argc, char **argv) + + if (match_data) { + +- uint32_t pcre_options = PCRE_UNGREEDY; ++ uint32_t pcre2_options = PCRE2_UNGREEDY; + + if (re_ignore_case) +- pcre_options |= PCRE_CASELESS; ++ pcre2_options |= PCRE2_CASELESS; + + if (re_multiline_match) +- pcre_options |= PCRE_DOTALL; ++ pcre2_options |= PCRE2_DOTALL; + + if (re_match_word) { + char *word_regex = malloc (strlen (match_data) * 3 + strlen (WORD_REGEX)); +@@ -564,14 +566,21 @@ main (int argc, char **argv) + match_data = word_regex; + } + +- pattern = pcre_compile (match_data, pcre_options, (const char **) &re_err, &err_offset, 0); ++ pattern = pcre2_compile (match_data, PCRE2_ZERO_TERMINATED, pcre2_options, &err_code, &err_offset, NULL); + + if (!pattern) { ++ pcre2_get_error_message (err_code, re_err, 128); + fprintf (stderr, "compile failed: %s\n", re_err); + clean_exit (-1); + } + +- pattern_extra = pcre_study (pattern, 0, (const char **) &re_err); ++ err_code = pcre2_jit_compile (pattern, PCRE2_JIT_COMPLETE); ++ ++ if (err_code < 0) { ++ pcre2_get_error_message(err_code, re_err, 128); ++ fprintf (stderr, "compile failed: %s\n", re_err); ++ clean_exit (-1); ++ } + + match_func = &re_match_func; + +@@ -1653,21 +1662,28 @@ dump_packet (struct pcap_pkthdr *h, u_ch + int8_t + re_match_func (unsigned char *data, uint32_t len) + { ++ pcre2_match_data *match_data; ++ ++ match_data = pcre2_match_data_create_from_pattern(pattern, NULL); + +- switch (pcre_exec (pattern, 0, (char *)data, (int32_t) len, 0, 0, 0, 0)) { +- case PCRE_ERROR_NULL: +- case PCRE_ERROR_BADOPTION: +- case PCRE_ERROR_BADMAGIC: +- case PCRE_ERROR_UNKNOWN_NODE: +- case PCRE_ERROR_NOMEMORY: ++ switch (pcre2_match (pattern, (PCRE2_SPTR)data, len, 0, 0, match_data, 0)) { ++ case PCRE2_ERROR_NULL: ++ case PCRE2_ERROR_BADOPTION: ++ case PCRE2_ERROR_BADMAGIC: ++ case PCRE2_ERROR_INTERNAL: ++ case PCRE2_ERROR_NOMEMORY: ++ pcre2_match_data_free(match_data); + perror ("she's dead, jim\n"); + clean_exit (-2); + break; + +- case PCRE_ERROR_NOMATCH: ++ case PCRE2_ERROR_NOMATCH: ++ pcre2_match_data_free(match_data); + return 0; + } + ++ pcre2_match_data_free(match_data); ++ + if (max_matches) + matches++; + +@@ -2125,9 +2141,7 @@ clean_exit (int32_t sig) + printf ("exit\n"); + + if (pattern) +- pcre_free (pattern); +- if (pattern_extra) +- pcre_free (pattern_extra); ++ pcre2_code_free (pattern); + + if (bin_data) + free (bin_data); diff --git a/net/sipp/Makefile b/net/sipp/Makefile new file mode 100644 index 000000000..1c2a32867 --- /dev/null +++ b/net/sipp/Makefile @@ -0,0 +1,57 @@ +# +# Copyright (C) 2013-2015 OpenWrt.org +# +# This is free software, licensed under the GNU General Public License v2. +# See /LICENSE for more information. +# + +include $(TOPDIR)/rules.mk + +PKG_NAME:=sipp +PKG_VERSION:=3.7.2 +PKG_RELEASE:=1 + +PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.gz +PKG_SOURCE_URL:=https://github.com/SIPp/sipp/releases/download/v$(PKG_VERSION) +PKG_HASH:=7c3a9864b3a966ac9f7a3205255a2fc328490de324b7a27636f9582879f0526e + +PKG_LICENSE:=GPL-2.0+ BSD-3-Clause Zlib +PKG_LICENSE_FILES:=LICENSE.txt + +include $(INCLUDE_DIR)/package.mk +include $(INCLUDE_DIR)/cmake.mk + +CMAKE_INSTALL:=1 + +define Package/sipp + SECTION:=net + CATEGORY:=Network + SUBMENU:=Telephony + DEPENDS:=+libstdcpp +libncurses +libpcap +libpthread + TITLE:=test tool / traffic generator for the SIP protocol + URL:=http://sipp.sourceforge.net/ +endef + +define Package/sipp/description + SIPp is a free Open Source test tool / traffic generator for the SIP + protocol. It includes a few basic SipStone user agent scenarios (UAC and + UAS) and establishes and releases multiple calls with the INVITE and BYE + methods. +endef + +# Otherwise OpenWrt's CPPFLAGS are ignored +TARGET_CFLAGS += $(TARGET_CPPFLAGS) + +# Use "common" options, see build.sh (we don't have gsl though) +CMAKE_OPTIONS += \ + -DUSE_GSL= \ + -DUSE_PCAP=1 \ + -DUSE_SCTP= \ + -DUSE_SSL= + +define Package/sipp/install + $(INSTALL_DIR) $(1)/usr/bin + $(INSTALL_BIN) $(PKG_INSTALL_DIR)/usr/bin/sipp $(1)/usr/bin +endef + +$(eval $(call BuildPackage,sipp)) diff --git a/net/sipp/patches/01-locale-include.patch b/net/sipp/patches/01-locale-include.patch new file mode 100644 index 000000000..5562297f7 --- /dev/null +++ b/net/sipp/patches/01-locale-include.patch @@ -0,0 +1,10 @@ +--- a/src/screen.cpp ++++ b/src/screen.cpp +@@ -18,6 +18,7 @@ + */ + + #include ++#include + + #include "screen.hpp" + #include "sipp.hpp" diff --git a/net/siproxd/Makefile b/net/siproxd/Makefile new file mode 100644 index 000000000..0c35ac7d5 --- /dev/null +++ b/net/siproxd/Makefile @@ -0,0 +1,125 @@ +# +# Copyright (C) 2014-2018 OpenWrt.org +# +# This is free software, licensed under the GNU General Public License v2. +# See /LICENSE for more information. +# + +include $(TOPDIR)/rules.mk + +PKG_NAME:=siproxd +PKG_RELEASE:=2 + +PKG_SOURCE_PROTO:=git +PKG_SOURCE_URL:=https://github.com/hb9xar/siproxd.git +PKG_SOURCE_DATE:=2022-02-18 +PKG_SOURCE_VERSION:=4750bea4ffedb4543a404dafc979c2b16b53e523 +PKG_MIRROR_HASH:=9b2fa84b4c05d68f758a35070af970c852ff4cb8beea3d7f93663b10a17e1df8 + +PKG_FIXUP:=autoreconf +PKG_INSTALL:=1 +PKG_BUILD_PARALLEL:=1 + +PKG_CONFIG_DEPENDS:=CONFIG_SIPROXD_MAX_CLIENTS + +PKG_LICENSE:=GPL-2.0+ +PKG_LICENSE_FILES:=COPYING +PKG_MAINTAINER:=Tony Ambardar + +include $(INCLUDE_DIR)/package.mk + +define Package/siproxd/Default + SECTION:=net + CATEGORY:=Network + SUBMENU:=Telephony + URL:=http://siproxd.sourceforge.net/ +endef + +define Package/siproxd + $(call Package/siproxd/Default) + DEPENDS:=+libltdl +libpthread +libosip2 + TITLE:=SIP (Session Initiation Protocol) proxy + MENU:=1 +endef + +define Package/siproxd/description + Siproxd is a proxy/masquerading daemon for the SIP protocol. Refer to https://openwrt.org/docs/guide-user/services/voip/siproxd for configuration details and examples. +endef + +define Package/siproxd/conffiles +/etc/config/siproxd +endef + +define Package/siproxd/config + config SIPROXD_MAX_CLIENTS + int "Max supported clients" + default 32 + depends on PACKAGE_siproxd + help + Default 32 is sufficient for home environments. Larger values + consume more memory (e.g. RSS of 17 MB with upstream default 512). +endef + +CONFIGURE_ARGS+= \ + --enable-reproducible-build \ + --with-libosip-prefix="$(STAGING_DIR)/usr" \ + --without-included-ltdl \ + --disable-doc + +MAKE_FLAGS+= \ + SUBDIRS="src scripts contrib" + +TARGET_CFLAGS+= \ + -Wno-unused-const-variable + +URLMAP:=$(CONFIG_SIPROXD_MAX_CLIENTS) +RTPPROXY:=$(shell expr $(URLMAP) \* 2) + +define Build/Configure + $(call Build/Configure/Default) + $(ESED) 's;^(#define[[:space:]]+URLMAP_SIZE).*$$$$;\1 $(URLMAP);' \ + -e 's;^(#define[[:space:]]+RTPPROXY_SIZE).*$$$$;\1 $(RTPPROXY);' \ + $(PKG_BUILD_DIR)/src/siproxd.h +endef + +define Package/siproxd/install + $(INSTALL_DIR) $(1)/usr/sbin + $(INSTALL_BIN) $(PKG_INSTALL_DIR)/usr/sbin/siproxd $(1)/usr/sbin + $(INSTALL_DIR) $(1)/etc/config + $(INSTALL_CONF) ./files/siproxd.config $(1)/etc/config/siproxd + $(INSTALL_DIR) $(1)/etc/init.d + $(INSTALL_BIN) ./files/siproxd.init $(1)/etc/init.d/siproxd +endef + +define BuildPlugin + define Package/siproxd-mod-$(subst _,-,$(1)) + $$(call Package/siproxd/Default) + TITLE:= siproxd $(1) plugin + DEPENDS:=siproxd $(2) + endef + + define Package/siproxd-mod-$(subst _,-,$(1))/install + $(INSTALL_DIR) $$(1)/usr/lib/siproxd + $(INSTALL_BIN) $(PKG_INSTALL_DIR)/usr/lib/siproxd/plugin_$(1).so \ + $$(1)/usr/lib/siproxd + endef + + $$(eval $$(call BuildPackage,siproxd-mod-$(subst _,-,$(1)))) +endef + +$(eval $(call BuildPackage,siproxd)) +$(eval $(call BuildPlugin,blacklist,+libsqlite3)) +$(eval $(call BuildPlugin,codecfilter)) +$(eval $(call BuildPlugin,defaulttarget)) +$(eval $(call BuildPlugin,demo)) +$(eval $(call BuildPlugin,fix_bogus_via)) +$(eval $(call BuildPlugin,fix_DTAG)) +$(eval $(call BuildPlugin,fix_fbox_anoncall)) +$(eval $(call BuildPlugin,logcall)) +$(eval $(call BuildPlugin,prefix)) +$(eval $(call BuildPlugin,regex)) +$(eval $(call BuildPlugin,shortdial)) +$(eval $(call BuildPlugin,stats)) +$(eval $(call BuildPlugin,stripheader)) +$(eval $(call BuildPlugin,stun)) +$(eval $(call BuildPlugin,siptrunk)) diff --git a/net/siproxd/files/siproxd.config b/net/siproxd/files/siproxd.config new file mode 100644 index 000000000..49b16ad86 --- /dev/null +++ b/net/siproxd/files/siproxd.config @@ -0,0 +1,25 @@ +config siproxd general + # Custom options allow using OpenWRT network names, and defaults should + # work out-of-the-box. If your SIP devices do not REGISTER externally, + # you may also need to open firewall ports: tcp/udp 5060, udp 7070-7089. + option interface_inbound lan + option interface_outbound wan + +# All other documented siproxd configuration directives are supported. Use +# a UCI 'option' for single-instance directives, and UCI 'list' entries for +# directives that allow multiple instances, per the examples below. + + # Define low-level network devices, overriding interface_in/outbound: +# option if_inbound eth0 +# option if_outbound ppp0 + + # Enable DEBUG logging for configuration messages: +# option debug_level 0x00000100 +# option silence_log 0 + + # Load two plugins: one that logs SIP call details to syslog, and one + # that strips out G.729, GSM codecs: +# list load_plugin 'plugin_logcall.so' +# list load_plugin 'plugin_codecfilter.so' +# list plugin_codecfilter_blacklist G729 +# list plugin_codecfilter_blacklist GSM diff --git a/net/siproxd/files/siproxd.init b/net/siproxd/files/siproxd.init new file mode 100644 index 000000000..0ff636bd6 --- /dev/null +++ b/net/siproxd/files/siproxd.init @@ -0,0 +1,176 @@ +#!/bin/sh /etc/rc.common +# Copyright (C) 2008 Alina Friedrichsen +# Copyright (C) 2011 OpenWrt.org + +START=50 + +USE_PROCD=1 + +PROG="/usr/sbin/siproxd" +CONF_DIR="/var/etc/siproxd" +REG_DIR="/var/lib/siproxd" +PID_DIR="/var/run/siproxd" +PLUGIN_DIR="/usr/lib/siproxd/" +SIPROXD_UID="nobody" +SIPROXD_GID="nogroup" + +# Some options need special handling or conflict with procd/jail setup. +append CONF_SKIP "interface_inbound interface_outbound chrootjail" +append CONF_SKIP "daemonize user plugindir registration_file pid_file" + + +# Check if a UCI option is set, or else apply a provided default. + +default_conf() { + local opt="$1" + local default="$2" + local val + + config_get "$opt" "$sec" "$opt" + eval "val=\"\${$opt}\"" + + [ -z "$val" ] || return 0 + [ -n "$default" ] || return 0 + config_set "$sec" "$opt" "$default" + append_conf "$opt" = "$default" +} + +append_conf() { + echo $* >> "$CONF_DIR/siproxd-$sec.conf" +} + +# Resolve network device by layer 3 first, then layer 2 + +siproxd_get_device() { + network_get_device $1 $2 || network_get_physdev $1 $2 +} + +# Use user-friendly network names (e.g. "wan", "lan") from options +# 'interface_inbound' and 'interface_outbound', but use standard siproxd +# parameters 'if_inbound' and 'if_outbound' if explicitly set. + +setup_networks() { + local sec="$1" + local _int_inbound _int_outbound + local _dev_inbound _dev_outbound + + config_get _int_inbound "$sec" interface_inbound + config_get _int_outbound "$sec" interface_outbound + + siproxd_get_device _dev_inbound $_int_inbound + siproxd_get_device _dev_outbound $_int_outbound + + default_conf if_inbound $_dev_inbound + default_conf if_outbound $_dev_outbound +} + +# Apply default values to key options if unset in user's UCI config. + +apply_defaults() { + local sec="$1" + + default_conf sip_listen_port 5060 + default_conf autosave_registrations 300 + default_conf rtp_port_low 7070 + default_conf rtp_port_high 7089 + default_conf rtp_timeout 300 + default_conf rtp_dscp 46 + default_conf tcp_timeout 600 + default_conf tcp_keepalive 20 + default_conf default_expires 600 + default_conf daemonize 0 + default_conf user "$SIPROXD_UID" + default_conf registration_file "$REG_DIR/siproxd-$sec.reg" + default_conf plugindir "$PLUGIN_DIR" +} + +# Handle activities at start of a new 'siproxd' section. +# Initialize section processing and save section name. + +section_start() { + local sec="$1" + + rm -f "$CONF_DIR/siproxd-$sec.conf" + append_conf "# config auto-generated from /etc/config/siproxd" +} + +# Handle activities at close of a 'siproxd' section. +# Parse OpenWRT interface names (e.g. "wan"), apply defaults and +# set up procd jail. + +section_end() { + local sec="$1" + + local conf_file="$CONF_DIR/siproxd-$sec.conf" + local pid_file="$PID_DIR/siproxd-$sec.pid" + local reg_file plugin_dir + + setup_networks "$sec" + apply_defaults "$sec" + + config_get plugin_dir "$sec" plugindir + config_get reg_file "$sec" registration_file + + procd_open_instance "$sec" + procd_set_param command "$PROG" --config "$conf_file" + procd_set_param pidfile "$pid_file" + procd_set_param respawn + procd_add_jail siproxd log + procd_add_jail_mount /etc/passwd /etc/group /etc/TZ /dev/null + procd_add_jail_mount "$conf_file" + [ -d "$plugin_dir" ] && procd_add_jail_mount "$plugin_dir" + # Ensure registration file exists for jail + [ -f "$reg_file" ] || touch "$reg_file" + chown "$SIPROXD_UID:$SIPROXD_GID" "$reg_file" + procd_add_jail_mount_rw "$reg_file" + procd_close_instance +} + +# Setup callbacks for parsing siproxd sections, options, and lists. +# This avoids hardcoding all supported siproxd configuration parameters. + +siproxd_cb() { + config_cb() { + # Section change: close any previous section. + [ -n "$cur_sec" ] && section_end "$cur_sec" + + case "$1" in + # New 'siproxd' section: begin processing. + "siproxd") + cur_sec="$2" + section_start "$cur_sec" + ;; + # Config end or unknown section: ignore. + *) + cur_sec="" + ;; + esac + } + + option_cb() { + local sec="$cur_sec" + + [ -z "$sec" ] && return + list_contains CONF_SKIP "$1" && return + [ -n "$2" ] && append_conf "$1" = "$2" + } + + list_cb() { + option_cb "$@" + } +} + +service_triggers() +{ + procd_add_reload_trigger "siproxd" +} + +start_service() { + mkdir -p "$CONF_DIR" "$REG_DIR" "$PID_DIR" + chmod 755 "$CONF_DIR" "$REG_DIR" "$PID_DIR" + chown "$SIPROXD_UID:$SIPROXD_GID" "$REG_DIR" + + . /lib/functions/network.sh + siproxd_cb + config_load 'siproxd' +} diff --git a/net/sngrep/Makefile b/net/sngrep/Makefile new file mode 100644 index 000000000..d889df8bf --- /dev/null +++ b/net/sngrep/Makefile @@ -0,0 +1,100 @@ +# +# Copyright (C) 2016 Daniel Engberg +# +# This is free software, licensed under the GNU General Public License v2. +# See /LICENSE for more information. +# + +include $(TOPDIR)/rules.mk + +PKG_NAME:=sngrep + +PKG_VERSION:=1.6.0 +PKG_RELEASE:=1 + +PKG_MAINTAINER:=Sebastian Kemper +PKG_LICENSE:=GPL-3.0+ +PKG_LICENSE_FILES:=COPYING + +PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.gz +PKG_SOURCE_URL:=https://github.com/irontec/sngrep/releases/download/v$(PKG_VERSION) +PKG_HASH:=fd80964d6560f2ff57b4f5bef2353d1a6f7c48d2f1a5f0a167c854bd2e801999 + +PKG_FIXUP:=autoreconf +PKG_BUILD_PARALLEL:=1 +PKG_INSTALL:=1 + +PKG_CONFIG_DEPENDS:= \ + CONFIG_IPV6 \ + CONFIG_SNGREP_ENABLE_EEP \ + CONFIG_SNGREP_WITH_PCRE \ + CONFIG_SNGREP_WITH_ZLIB + +include $(INCLUDE_DIR)/package.mk + +define Package/sngrep + SECTION:=utils + CATEGORY:=Utilities + SUBMENU:=Telephony + DEPENDS:= \ + +libncursesw \ + +libopenssl \ + +libpcap \ + +SNGREP_WITH_PCRE:libpcre2 \ + +SNGREP_WITH_ZLIB:zlib + TITLE:=Ncurses SIP messages flow viewer + URL:=https://github.com/irontec/sngrep +endef + +define Package/sngrep/description +sngrep is a tool for displaying SIP calls message flows from terminal. + +It supports live capture to display realtime SIP packets and can also be +used as PCAP viewer. +endef + +define Package/sngrep/conffiles +/etc/sngreprc +endef + +define Package/sngrep/config + menu "sngrep configuration" + depends on PACKAGE_sngrep + + config SNGREP_ENABLE_EEP + bool "EEP/HEP support" + default y + help + Enable EEP/HEP support + + config SNGREP_WITH_PCRE + bool "PCRE support" + default y + help + Enable Perl compatible regular expressions + + config SNGREP_WITH_ZLIB + bool "zlib support" + default y + help + Add support for opening gzip compressed input files + endmenu +endef + +CONFIGURE_ARGS += \ + --$(if $(CONFIG_SNGREP_ENABLE_EEP),en,dis)able-eep \ + --$(if $(CONFIG_IPV6),en,dis)able-ipv6 \ + --enable-unicode \ + --with-openssl \ + --without-pcre \ + --with$(if $(CONFIG_SNGREP_WITH_PCRE),,out)-pcre2 \ + --with$(if $(CONFIG_SNGREP_WITH_ZLIB),,out)-zlib + +define Package/sngrep/install + $(INSTALL_DIR) $(1)/etc + $(INSTALL_CONF) $(PKG_INSTALL_DIR)/etc/sngreprc $(1)/etc + $(INSTALL_DIR) $(1)/usr/bin + $(INSTALL_BIN) $(PKG_INSTALL_DIR)/usr/bin/sngrep $(1)/usr/bin +endef + +$(eval $(call BuildPackage,sngrep)) diff --git a/net/yate/Makefile b/net/yate/Makefile new file mode 100644 index 000000000..a672b6031 --- /dev/null +++ b/net/yate/Makefile @@ -0,0 +1,303 @@ +# +# Copyright (C) 2006-2018 OpenWrt.org +# Copyright (C) 2006-2011 SMBPhone +# +# This is free software, licensed under the GNU General Public License v2. +# See /LICENSE for more information. +# + +include $(TOPDIR)/rules.mk + +PKG_NAME:=yate +PKG_VERSION:=6.4.0-1 +PKG_RELEASE:=3 + +PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.gz +PKG_SOURCE_URL:=http://yate.null.ro/tarballs/yate6/ +PKG_HASH:=8c23dc6bffbf8d478db3a85964b5019771c8f6c9acf5220f3465516a748a03b0 + +PKG_LICENSE:=GPL-2.0 +PKG_LICENSE_FILES:=COPYING +PKG_MAINTAINER:=Jiri Slachta + +PKG_FIXUP:=autoreconf +# Sporadic build failures on the build bots +PKG_BUILD_PARALLEL:=0 +PKG_INSTALL:=1 + +PKG_BUILD_DEPENDS:=HOST_OS_MACOS:fakeuname/host + +# Yate currently does not compile with FORTIFY_SOURCE enabled +PKG_FORTIFY_SOURCE:=0 + +PKG_CONFIG_DEPENDS:= \ + CONFIG_PACKAGE_$(PKG_NAME)-mod-faxchan \ + CONFIG_PACKAGE_$(PKG_NAME)-mod-g722webrtc \ + CONFIG_PACKAGE_$(PKG_NAME)-mod-ilbccodec \ + CONFIG_PACKAGE_$(PKG_NAME)-mod-ilbcwebrtc \ + CONFIG_PACKAGE_$(PKG_NAME)-mod-isaccodec \ + CONFIG_PACKAGE_$(PKG_NAME)-mod-mysqldb \ + CONFIG_PACKAGE_$(PKG_NAME)-mod-openssl \ + CONFIG_PACKAGE_$(PKG_NAME)-mod-pgsqldb \ + CONFIG_PACKAGE_$(PKG_NAME)-mod-speexcodec \ + CONFIG_PACKAGE_$(PKG_NAME)-mod-sqlitedb \ + CONFIG_PACKAGE_$(PKG_NAME)-mod-zapcard \ + CONFIG_PACKAGE_$(PKG_NAME)-mod-zlibcompress \ + CONFIG_SOFT_FLOAT + +include $(INCLUDE_DIR)/package.mk +include $(INCLUDE_DIR)/nls.mk +ifeq ($(CONFIG_HOST_OS_MACOS),y) + include $(TOPDIR)/feeds/packages/utils/fakeuname/fakeuname.mk +endif + +TAR_OPTIONS+= --strip-components 1 +TAR_CMD=$(HOST_TAR) -C $(1) $(TAR_OPTIONS) + +define Package/$(PKG_NAME)/Default + SUBMENU:=Telephony + SECTION:=net + CATEGORY:=Network + URL:=http://yate.null.ro/ +endef + +define Package/$(PKG_NAME) + $(call Package/yate/Default) + DEPENDS:=+libpthread +libstdcpp + TITLE:=Yet Another Telephony Engine + MENU:=1 +endef + +define Package/$(PKG_NAME)/conffiles +/etc/yate/yate.conf +/etc/init.d/yate +endef + +define Package/$(PKG_NAME)/Default/description + Is a next-generation telephony engine focused on the VoIP and PSTN. It does + SIP, H.323, IAX, PSTN, and more. +endef + +define Package/$(PKG_NAME)-scripts-perl + $(call Package/yate/Default) + DEPENDS += $(PKG_NAME) \ + +PACKAGE_$(PKG_NAME)-scripts-perl:$(PKG_NAME)-mod-extmodule \ + +PACKAGE_$(PKG_NAME)-scripts-perl:perlbase-data \ + @!arc + TITLE:= Perl module for Yate +endef + +define Package/$(PKG_NAME)-sounds + $(call Package/yate/Default) + DEPENDS += $(PKG_NAME) + TITLE := Sounds for Yate +endef + +# Otherwise yate ignores CPPFLAGS +TARGET_CFLAGS += $(TARGET_CPPFLAGS) + +CONFIGURE_VARS+= \ + $(if $(CONFIG_HOST_OS_MACOS),PATH=$(FAKEUNAME_PATH):$(TARGET_PATH_PKG)) + +CONFIGURE_ARGS+= \ + --disable-sctp \ + --disable-tdmcard \ + --disable-wanpipe \ + --disable-wpcard \ + --without-amrnb \ + --without-coredumper \ + --without-doxygen \ + --without-kdoc \ + --without-libgsm \ + --without-libqt4 \ + --without-openh323 \ + --without-pwlib \ + --without-qtstatic \ + --without-wphwec \ + $(if $(CONFIG_x86_64),--enable-sse2) \ + $(if $(CONFIG_PACKAGE_$(PKG_NAME)-mod-faxchan),--with-spandsp="$(STAGING_DIR)/usr/include",--without-spandsp) \ + $(if $(CONFIG_PACKAGE_$(PKG_NAME)-mod-g722webrtc),--enable-g722-webrtc,--disable-g722-webrtc) \ + $(if $(CONFIG_PACKAGE_$(PKG_NAME)-mod-ilbccodec),--enable-ilbc,--disable-ilbc) \ + $(if $(CONFIG_PACKAGE_$(PKG_NAME)-mod-ilbcwebrtc),--enable-ilbc-webrtc,--disable-ilbc-webrtc) \ + $(if $(CONFIG_PACKAGE_$(PKG_NAME)-mod-mysqldb),--with-mysql=yes,--without-mysql) \ + $(if $(CONFIG_PACKAGE_$(PKG_NAME)-mod-openssl),--with-openssl,--without-openssl) \ + $(if $(CONFIG_PACKAGE_$(PKG_NAME)-mod-pgsqldb),--with-libpq="$(STAGING_DIR)/usr",--without-libpq) \ + $(if $(CONFIG_PACKAGE_$(PKG_NAME)-mod-speexcodec),--with-libspeex="$(STAGING_DIR)/usr/include",--without-libspeex) \ + $(if $(CONFIG_PACKAGE_$(PKG_NAME)-mod-sqlitedb),--with-sqlite,--without-sqlite) \ + $(if $(CONFIG_PACKAGE_$(PKG_NAME)-mod-zapcard),,--disable-dahdi --disable-zaptel) \ + $(if $(CONFIG_PACKAGE_$(PKG_NAME)-mod-zlibcompress),--with-zlib="$(STAGING_DIR)/usr",--without-zlib) + +# The regexp implementation of musl 1.1.24 is not fully compatible with yate +CONFIGURE_ARGS+= \ + --enable-internalregex + +ifneq ($(CONFIG_PACKAGE_$(PKG_NAME)-mod-isaccodec),) +CONFIGURE_ARGS+=$(if $(CONFIG_SOFT_FLOAT),--disable-isac-float --enable-isac-fixed,--disable-isac-fixed --enable-isac-float) +else +CONFIGURE_ARGS+= \ + --disable-isac-fixed \ + --disable-isac-float +endif + +define Package/$(PKG_NAME)/install + $(INSTALL_DIR) $(1)/usr/lib + + for yatelib in "" asn sig mgcp jabber script; do \ + $(CP) $(PKG_INSTALL_DIR)/usr/lib/libyate$$$${yatelib}.so* $(1)/usr/lib ;\ + done + + $(INSTALL_DIR) $(1)/usr/bin + $(INSTALL_BIN) $(PKG_INSTALL_DIR)/usr/bin/yate $(1)/usr/bin/ + $(INSTALL_DIR) $(1)/etc/$(PKG_NAME) + $(INSTALL_CONF) $(PKG_INSTALL_DIR)/etc/yate/yate.conf $(1)/etc/$(PKG_NAME)/yate.conf + $(INSTALL_DIR) $(1)/etc/init.d + $(INSTALL_BIN) ./files/yate.init $(1)/etc/init.d/yate +endef + +define Package/$(PKG_NAME)-scripts-perl/install + $(INSTALL_DIR) $(1)/usr/share/yate/scripts + $(INSTALL_DATA) $(PKG_INSTALL_DIR)/usr/share/yate/scripts/Yate.pm $(1)/usr/share/yate/scripts/ + $(INSTALL_BIN) ./files/banbrutes.pl $(1)/usr/share/yate/scripts/ +endef + +define Package/$(PKG_NAME)-sounds/install + $(INSTALL_DIR) $(1)/usr/share/yate/sounds + $(CP) $(PKG_INSTALL_DIR)/usr/share/yate/sounds/ $(1)/usr/share/yate/ +endef + +define Build/InstallDev + $(INSTALL_DIR) $(STAGING_DIR)/usr/include + $(CP) $(PKG_INSTALL_DIR)/usr/include/* $(STAGING_DIR)/usr/include/ + $(INSTALL_DIR) $(STAGING_DIR)/usr/lib + $(CP) $(PKG_INSTALL_DIR)/usr/lib/* $(STAGING_DIR)/usr/lib/ +endef + +define BuildPlugin + define Package/$(PKG_NAME)-mod-$(subst _,-,$(1)) + $(call Package/yate/Default) + DEPENDS:= $(PKG_NAME) $(patsubst +%,+PACKAGE_$(PKG_NAME)-mod-$(subst _,-,$(1)):%,$(4)) + TITLE:=$(3) + endef + + define Package/$(PKG_NAME)-mod-$(subst _,-,$(1))/conffiles +$(if $(6),/etc/yate/$(1).conf) + endef + + define Package/$(PKG_NAME)-mod-$(subst _,-,$(1))/description + $(3) module for $(PKG_NAME) + endef + + define Package/$(PKG_NAME)-mod-$(subst _,-,$(1))/install + $$(INSTALL_DIR) $$(1)/usr/lib/yate/$(2) + $$(INSTALL_BIN) $$(PKG_INSTALL_DIR)/usr/lib/yate/$(2)/$(1).yate $$(1)/usr/lib/yate/$(2)/$(1).yate + if [ -f $$(PKG_INSTALL_DIR)/etc/yate/$(1).conf ]; then \ + $$(INSTALL_DIR) $$(1)/etc/yate ;\ + $$(INSTALL_CONF) $$(PKG_INSTALL_DIR)/etc/yate/$(1).conf $$(1)/etc/yate/ ;\ + fi + $(if $(5),$(foreach extra_file,$(5),\ + $(INSTALL_DIR) $$(1)$(dir $(extra_file)) ; \ + $(CP) $(PKG_INSTALL_DIR)$(extra_file) $$(1)$(extra_file) ; \ + ),) + endef + + $$(eval $$(call BuildPackage,$(PKG_NAME)-mod-$(subst _,-,$(1)))) +endef + +$(eval $(call BuildPackage,$(PKG_NAME))) +$(eval $(call BuildPackage,$(PKG_NAME)-scripts-perl)) +$(eval $(call BuildPackage,$(PKG_NAME)-sounds)) + +############################ +# 1: plugin +# 2: client, server or empty +# 3: description +# 4: depends +# 5: extra files +# 6: has a config sample (y) +# ########################## +$(eval $(call BuildPlugin,accfile,server,SIP or H.323 client (from file),,,y)) +$(eval $(call BuildPlugin,alsachan,client,ALSA Sound Channel,+alsa-lib)) +$(eval $(call BuildPlugin,amrnbcodec,,AMR-NB Codec,@BROKEN)) # Missing amr-nb library +$(eval $(call BuildPlugin,analog,server,Analog (e.g. POTS) Channel,,,y)) +$(eval $(call BuildPlugin,analogdetect,server,Analog Data Detector,)) +$(eval $(call BuildPlugin,analyzer,,Test Call Generator and AQ Analyzer,)) +$(eval $(call BuildPlugin,cache,server,CNAM and LNP memory caches,,,y)) +$(eval $(call BuildPlugin,callcounters,server,Count Active Call Legs,,,y)) +$(eval $(call BuildPlugin,callfork,,Call Forker,,,y)) +$(eval $(call BuildPlugin,callgen,,Call Generator,)) +$(eval $(call BuildPlugin,camel_map,sig,MAP/CAMEL TCAP <-> XML translators,,,y)) +$(eval $(call BuildPlugin,ccongestion,server,Accept Status from Installed Engine Monitors,,,y)) +$(eval $(call BuildPlugin,cdrbuild,,Call Detail Record Builder,,,y)) +$(eval $(call BuildPlugin,cdrcombine,,Call Detail Records per call instead of per call leg,)) +$(eval $(call BuildPlugin,cdrfile,,Call Detail Record to File,,,y)) +$(eval $(call BuildPlugin,ciscosm,server,SS7 Support,,,y)) +$(eval $(call BuildPlugin,clustering,server,Clustering Server Support,,,y)) +$(eval $(call BuildPlugin,conference,,Conference Room Mixer,)) +$(eval $(call BuildPlugin,cpuload,server,Monitor CPU load and Inform Yate,,,y)) +$(eval $(call BuildPlugin,dbpbx,server,PBX IVR and Multi-routing from Database,,,y)) +$(eval $(call BuildPlugin,dbwave,server,Wav Media for DB Storage,+$(PKG_NAME)-mod-wavefile)) +$(eval $(call BuildPlugin,dumbchan,,Dummy Channel,)) +$(eval $(call BuildPlugin,enumroute,,ENUM Routing,,,y)) +$(eval $(call BuildPlugin,eventlogs,server,Write events and alarms to log files,,,y)) +$(eval $(call BuildPlugin,extmodule,,External Module Handler,,/usr/share/yate/scripts/echo.sh,y)) +$(eval $(call BuildPlugin,faxchan,,Spandsp Fax Channel,+libspandsp)) +$(eval $(call BuildPlugin,fileinfo,,File Info Holder,,,y)) +$(eval $(call BuildPlugin,filetransfer,,File Transfer Driver,,,y)) +$(eval $(call BuildPlugin,g722webrtc,,G.722 codec using library based on WebRTC project,)) +$(eval $(call BuildPlugin,gvoice,,Google Voice support,,,y)) +$(eval $(call BuildPlugin,heartbeat,server,Linux-HA compatible heartbeat,,,y)) +$(eval $(call BuildPlugin,ilbccodec,,iLBC Codec,)) +$(eval $(call BuildPlugin,ilbcwebrtc,,iLBC Codec from the WebRTC project,)) +$(eval $(call BuildPlugin,isaccodec,,internet Speech Audio Codec,)) +$(eval $(call BuildPlugin,isupmangler,sig,ISUP parameter mangling in a STP,,,y)) +$(eval $(call BuildPlugin,jabberclient,client,Jabber Client,,,y)) +$(eval $(call BuildPlugin,jabberserver,jabber,Jabber Server,,,y)) +$(eval $(call BuildPlugin,javascript,,Routing using the embedded Javascript language,,,y)) +$(eval $(call BuildPlugin,jbfeatures,jabber,Jabber Server Features,,,y)) +$(eval $(call BuildPlugin,lateroute,server,Last Chance Routing,,,y)) +$(eval $(call BuildPlugin,mgcpca,server,Media Gateway Control Protocol Agent,,,y)) +$(eval $(call BuildPlugin,mgcpgw,server,Media Gateway Control Protocol Gateway,,,y)) +$(eval $(call BuildPlugin,moh,,On Hold (music) Generator,,,y)) +$(eval $(call BuildPlugin,monitoring,server,Monitoring/gathering Information,,,y)) +$(eval $(call BuildPlugin,mrcpspeech,server,MRCP v2 Voice/Tone Detector and Synthesizer,)) +$(eval $(call BuildPlugin,msgsniff,,Sample Message Sniffer,)) +$(eval $(call BuildPlugin,mux,,Data Multiplexor,,,y)) +$(eval $(call BuildPlugin,mysqldb,server,MySQL Backend DB,+libmysqlclient-r,,y)) +$(eval $(call BuildPlugin,openssl,,Encrypted transport (OpenSSL),+libopenssl,,y)) +$(eval $(call BuildPlugin,osschan,client,OSS Sound Channel,)) +$(eval $(call BuildPlugin,park,server,Call Parking,)) +$(eval $(call BuildPlugin,pbx,,PBX Message Handlers,)) +$(eval $(call BuildPlugin,pbxassist,server,Full featured PBX and IVR,,,y)) +$(eval $(call BuildPlugin,pgsqldb,server,PostgrestSQL Backend DB,+libpq)) +$(eval $(call BuildPlugin,presence,server,Presence,,,y)) +$(eval $(call BuildPlugin,queues,server,Call Distribution and Queues from Database,,,y)) +$(eval $(call BuildPlugin,queuesnotify,server,Notify when queued call status changes,,,y)) +$(eval $(call BuildPlugin,regexroute,,Regular Expression Based Routing,,,y)) +$(eval $(call BuildPlugin,regfile,server,Registration based on users in file,,,y)) +$(eval $(call BuildPlugin,register,server,Call Detail Record to a database,,,y)) +$(eval $(call BuildPlugin,rmanager,,Yate Remote Management,,,y)) +$(eval $(call BuildPlugin,sigtransport,server,SIGTRAN (SS7 over IP) connection provider,,,y)) +$(eval $(call BuildPlugin,sip_cnam_lnp,sip,Query CNAM and LNP databases using SIP INVITE,,,y)) +$(eval $(call BuildPlugin,sipfeatures,server,SIP Features (SUBSCRIBE/NOTIFY),,,y)) +$(eval $(call BuildPlugin,speexcodec,,Speex codec module written by Olaf Conradi,+libspeex)) +$(eval $(call BuildPlugin,sqlitedb,server,SQLite Support,+libsqlite3,,y)) +$(eval $(call BuildPlugin,ss7_lnp_ansi,sig,Query LNP Databases,,,y)) +$(eval $(call BuildPlugin,subscription,server,Subcription handler and presence notifier,,,y)) +$(eval $(call BuildPlugin,tdmcard,server,TDM Cards Signalling and Data Driver,@BROKEN)) # Missing TDM libraries +$(eval $(call BuildPlugin,tonedetect,,Detectors for Various Tones,)) +$(eval $(call BuildPlugin,tonegen,,Tones Generator,,,y)) +$(eval $(call BuildPlugin,users,server,Users,,,y)) +$(eval $(call BuildPlugin,wavefile,,Wav file Record and Playback,)) +$(eval $(call BuildPlugin,wiresniff,,Capture interface for YATE messages,,,y)) +$(eval $(call BuildPlugin,wpcard,server,Wanpipe PRI cards Signalling and Data Driver,@BROKEN)) # Mising wanpipe and PRI libraries +$(eval $(call BuildPlugin,yiaxchan,,IAX Channel,,,y)) +$(eval $(call BuildPlugin,yjinglechan,,Jingle Channel,,,y)) +$(eval $(call BuildPlugin,yradius,server,RADIUS Client,,,y)) +$(eval $(call BuildPlugin,yrtpchan,,RTP Channel and Other Data Helper,,,y)) +$(eval $(call BuildPlugin,ysigchan,server,SS7/ISDN Protocols - Yate Signalling Library,,,y)) +$(eval $(call BuildPlugin,ysipchan,,SIP Channel,,,y)) +$(eval $(call BuildPlugin,ysnmpagent,server,SNMP Protocol Agent,,/usr/share/yate/data/NULL-TEAM-MIB.txt /usr/share/yate/data/snmp_mib.conf /usr/share/yate/data/YATE-MIB.txt,y)) +$(eval $(call BuildPlugin,ysockschan,,SOCKS Channel,,,y)) +$(eval $(call BuildPlugin,ystunchan,,STUN Support,,,y)) +$(eval $(call BuildPlugin,zapcard,server,Zaptel PRI/TDM/FXS/FXO cards,@!aarch64 +kmod-dahdi,,y)) +$(eval $(call BuildPlugin,zlibcompress,,Zlib Compression,+zlib,,y)) diff --git a/net/yate/files/banbrutes.pl b/net/yate/files/banbrutes.pl new file mode 100755 index 000000000..aefaa5eb3 --- /dev/null +++ b/net/yate/files/banbrutes.pl @@ -0,0 +1,86 @@ +#!/usr/bin/perl + +# This yate script will monitor authentication requests and update an +# nftables set with IP addresses of users who consistently fail to +# authenticate. The nftables set can then be used in OpenWrt's +# firewall configuration to block these IP addresses. +# +# The nftables set has to exist before launching yate. +# +# Here's an example configuration that creates an nftables set, where +# entries expire after 12 hours, and configures the OpenWrt firewall +# to drop packets where the source IP address is in the set. Put this +# in /etc/nftables.d/99-yate.nft: +# +# set yate_denylist { +# type ipv4_addr +# timeout 12h +# } +# +# chain yate_filter { +# type filter hook input priority -1; policy accept; +# ip saddr @yate_denylist counter drop comment "Drop packets from bad SIP clients" +# } +# +# +# To enable this script in yate, add it to the [scripts] section in +# /etc/yate/extmodule.conf. +# +# You can tweak how tolerant this script should be by modifying the +# constants below. + +# A user's IP address will be added to the nftables set if there are +# more than MAX_AUTH_FAILURES consecutive authentication failures in +# MAX_AUTH_FAILURES_TIME_PERIOD seconds. +my $MAX_AUTH_FAILURES = 5; +my $MAX_AUTH_FAILURES_TIME_PERIOD = 3600; # seconds + +# The name of the nftables table and set where IP addresses are added. +my $NFTABLES_TABLE = 'inet fw4'; +my $NFTABLES_SET = 'yate_denylist'; + + +use strict; +use warnings; +use lib '/usr/share/yate/scripts'; +use Yate; + +my %ip_auth_failures = (); + +sub OnAuthenticationRequest($) { + my $yate = shift; + + # Forget any expired failed authentications + foreach my $ip (keys(%ip_auth_failures)) { + my $failures = \@{$ip_auth_failures{$ip}}; + while (@$failures && + time() - @$failures[0] > $MAX_AUTH_FAILURES_TIME_PERIOD) { + shift(@$failures); + } + + if (!@$failures) { + delete $ip_auth_failures{$ip}; + } + } + + my $remote_ip = $yate->param('ip_host'); + my $remote_device = $yate->param('device') || ''; + + if ($yate->header('processed') eq 'true') { + $yate->output("banbrutes: Successful authentication from $remote_ip"); + delete $ip_auth_failures{$remote_ip}; + return; + } + + $yate->output("banbrutes: Failed authentication from $remote_ip"); + push(@{$ip_auth_failures{$remote_ip}}, time()); + if (scalar(@{$ip_auth_failures{$remote_ip}}) > $MAX_AUTH_FAILURES) { + $yate->output("banbrutes: Adding $remote_ip to nftables set $NFTABLES_SET (remote device: $remote_device)"); + `nft add element $NFTABLES_TABLE $NFTABLES_SET { $remote_ip }`; + delete $ip_auth_failures{$remote_ip}; + } +} + +my $yate = new Yate(); +$yate->install_watcher("user.auth", \&OnAuthenticationRequest); +$yate->listen(); diff --git a/net/yate/files/yate.init b/net/yate/files/yate.init new file mode 100644 index 000000000..4fe8c58c0 --- /dev/null +++ b/net/yate/files/yate.init @@ -0,0 +1,25 @@ +#!/bin/sh /etc/rc.common +# Copyright (C) 2013 OpenWrt.org +START=50 + +SERVICE_USE_PID=1 + +YATE_BINARY="/usr/bin/yate" +YATE_LOG_FILE="" +YATE_OPTIONS="-d -s -p /var/run/yate.pid" + +start() { + if [ -n "$YATE_LOG_FILE" ]; then + YATE_OPTIONS="$YATE_OPTIONS -r -l $YATE_LOG_FILE" + fi + + service_start $YATE_BINARY $YATE_OPTIONS +} + +stop() { + service_stop $YATE_BINARY +} + +reload() { + service_reload $YATE_BINARY +} diff --git a/net/yate/patches/100-non-gnu-mutex-type.patch b/net/yate/patches/100-non-gnu-mutex-type.patch new file mode 100644 index 000000000..e0f990512 --- /dev/null +++ b/net/yate/patches/100-non-gnu-mutex-type.patch @@ -0,0 +1,24 @@ +--- a/engine/Mutex.cpp ++++ b/engine/Mutex.cpp +@@ -30,6 +30,10 @@ typedef HANDLE HSEMAPHORE; + #include + #include + ++#ifndef PTHREAD_MUTEX_RECURSIVE_NP ++#define PTHREAD_MUTEX_RECURSIVE_NP PTHREAD_MUTEX_RECURSIVE ++#endif ++ + #ifdef MUTEX_HACK + extern "C" { + #if defined(__FreeBSD__) || defined(__OpenBSD__) || defined(__NetBSD__) || defined(__APPLE__) +--- a/configure.ac ++++ b/configure.ac +@@ -264,7 +264,7 @@ AC_TRY_COMPILE([ + #include + ],[ + pthread_mutexattr_t attr; +-pthread_mutexattr_settype(&attr,PTHREAD_MUTEX_RECURSIVE_NP); ++pthread_mutexattr_settype(&attr,PTHREAD_MUTEX_RECURSIVE); + ], + have_mutex_settype="yes", + have_mutex_settype="no" diff --git a/net/yate/patches/120-increase-sip-message-size.patch b/net/yate/patches/120-increase-sip-message-size.patch new file mode 100644 index 000000000..b254d315b --- /dev/null +++ b/net/yate/patches/120-increase-sip-message-size.patch @@ -0,0 +1,11 @@ +--- a/conf.d/ysipchan.conf.sample ++++ b/conf.d/ysipchan.conf.sample +@@ -80,7 +80,7 @@ + + ; maxpkt: int: Maximum received UDP packet size, 524 to 65528, default 1500 + ; This parameter is applied on reload and can be overridden in UDP listener sections +-;maxpkt=1500 ++maxpkt=8192 + + ; buffer: int: Requested size of UDP socket's receive buffer, 0 to use default + ; This can be overridden in UDP listener sections diff --git a/net/yate/patches/130-fix-ilbc-flags.patch b/net/yate/patches/130-fix-ilbc-flags.patch new file mode 100644 index 000000000..7bf636c0f --- /dev/null +++ b/net/yate/patches/130-fix-ilbc-flags.patch @@ -0,0 +1,11 @@ +--- a/libs/ilbc/Makefile.in ++++ b/libs/ilbc/Makefile.in +@@ -6,7 +6,7 @@ AR := ar + SED := sed + DEFS := + INCLUDES := -I@top_srcdir@ +-CFLAGS := @CFLAGS@ -O3 -funroll-loops -fomit-frame-pointer -fsigned-char @MODULE_CFLAGS@ ++CFLAGS := @CFLAGS@ -fsigned-char @MODULE_CFLAGS@ + LDFLAGS:= @LDFLAGS@ + + PROGS= diff --git a/net/yate/patches/140-warning-unknown-architecture.patch b/net/yate/patches/140-warning-unknown-architecture.patch new file mode 100644 index 000000000..8a8590f79 --- /dev/null +++ b/net/yate/patches/140-warning-unknown-architecture.patch @@ -0,0 +1,20 @@ +--- a/libs/miniwebrtc/typedefs.h ++++ b/libs/miniwebrtc/typedefs.h +@@ -101,7 +101,7 @@ + #endif + + #else +-#error Please add support for your architecture in typedefs.h ++#warning : Please add support for your architecture in typedefs.h + #endif + + #if defined(__SSE2__) || defined(_MSC_VER) +@@ -160,7 +160,7 @@ + #define WEBRTC_LITTLE_ENDIAN + + #else +- #error "No platform defined for WebRTC type definitions (typedefs.h)" ++ #warning : "No platform defined for WebRTC type definitions (typedefs.h)" + #endif + + #endif // WEBRTC_TYPEDEFS_H_