Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Build] PJSUA2 / Asterisk (video-spezifisch) #5

Open
emphasize opened this issue Apr 24, 2022 · 3 comments
Open

[Build] PJSUA2 / Asterisk (video-spezifisch) #5

emphasize opened this issue Apr 24, 2022 · 3 comments

Comments

@emphasize
Copy link
Owner

emphasize commented Apr 24, 2022

Base: RaspiOS Bulleseye 32-Bit (2022-04-07) + Doorpi (branch bugfix/setuptools)

Da noch nicht im Setupscript verankert hier ein Rezept für eine laufende PJSUA/Asterisk konfiguration

Das ganze stützt sich auf 4 Komponenten:

  • Pjproject
  • SDL
  • Asterisk
  • FFmpeg
    (es wird nur pjproject und openh264 kompiliert)

System Dependenzen:

libtool pkg-config libasound2-dev libpulse-dev libaudio-dev libjack-dev \
libx11-dev libxext-dev libxrandr-dev libxcursor-dev libxfixes-dev libxi-dev \
libxinerama-dev libxxf86vm-dev libxss-dev libgl1-mesa-dev libdbus-1-dev \
libudev-dev libgles2-mesa-dev libegl1-mesa-dev libibus-1.0-dev \
fcitx-libs-dev libsamplerate0-dev libsndio-dev libwayland-dev \
libxkbcommon-dev libdrm-dev libgbm-dev libraspberrypi0 libraspberrypi-bin libraspberrypi-dev \
libzrtpcpp-dev libxext-dev libpcre3-dev libtool libccrtp-dev libdbus-c++-dev libcommoncpp2-dev \
libdbus-1-dev libyaml-dev swig libsamplerate0-dev libspeexdsp-dev libspeex-dev libv4l-dev libx264-dev libcelt-dev \
libgmp3-dev libmpfr-dev libmpfr-doc libmpc-dev libffi-dev libmp3lame-dev libvorbis-dev libtheora-dev yasm nasm \
libopencore-amrwb-dev libopencore-amrnb-dev libvo-amrwbenc-dev libgsm1-dev opus-tools libopus-dev \
libass-dev libfreetype6-dev libva-dev libvdpau-dev libvorbis-dev libxcb1-dev libxcb-shm0-dev \
libxcb-xfixes0-dev meson ninja-build texinfo wget zlib1g-dev libsdl2-dev vpx-tools libvpx-dev libvpx6 x264

Swap Anpassung (Kompilierung von pjsua hat eine gewisse ohne die der Prozess abbricht)

#notwendig sind 1.5Gb für (pjsua2) Kompilierung
MINMEM=1572864
SWAP=$(cat /proc/meminfo | grep SwapTotal | awk '{print $2}')
MEM=$(cat /proc/meminfo | grep MemTotal | awk '{print $2}')
TOTALMEM=$(expr $SWAP + $MEM)
if [ $TOTALMEM -lt $MINMEM ] ; then
   sudo dphys-swapfile swapoff
   SWAPNEEDED=$(expr $(expr $MINMEM - $MEM) / 1000)
   sudo sed -i "s/CONF_SWAPSIZE=.*/CONF_SWAPSIZE=${SWAPNEEDED}/g" /etc/dphys-swapfile
   sudo dphys-swapfile setup
   sudo dphys-swapfile swapon
   sudo reboot
fi
O264_PACKAGE="v2.2.0.tar.gz"
PJSIP_PACKAGE="2.12.tar.gz"
O264_VER=$(echo ${O264_PACKAGE%".tar.gz"} | cut -c 2-)
PJSIP_VER=${PJSIP_PACKAGE%".tar.gz"}

Openh264

cd ~ && wget https://github.com/cisco/openh264/archive/refs/tags/${O264_PACKAGE} && tar xvfz ${O264_PACKAGE} && cd openh264-${O264_VER} 
make -j`nproc` && sudo make install
cd ~ && rm -rf openh264-${O264_VER} && rm ${O264_PACKAGE}
sudo ldconfig

Pjproject

cd ~
wget https://github.com/pjsip/pjproject/archive/refs/tags/${PJSIP_PACKAGE}
tar xvfz ${PJSIP_PACKAGE} && cd pjproject-${PJSIP_VER}
echo '#define PJMEDIA_AUDIO_DEV_HAS_ALSA      1
#define PJMEDIA_AUDIO_DEV_HAS_PORTAUDIO 0
#define PJMEDIA_HAS_VIDEO       1' > pjlib/include/pj/config_site.h
Raspberry Pi -mtune -mfpu -march
Zero /1 A+/1 B+ arm1176jzf-s vfp armv6
2 B cortex-a7 neon-vfpv4 armv7
3 B cortex-a53 neon-vfpv4 armv7
3 B+ /4 B cortex-a72 neon-fp-armv8 armv8

vielleicht noch einmal genauer nachschauen, da es in jeder Generation zwischenmodelle gibt

echo "export CFLAGS += -march=armv7 -mtune=cortex-a53 -mfpu=neon-vfpv4 -mfloat-abi=hard -mlittle-endian -munaligned-access 
-ffast-math
export LDFLGS +=" > user.mak
nano third_party/build/os-auto.mak.in

Die webrtc sektion mit folgender überschreiben:

ifneq (@ac_no_webrtc@,1)
ifeq (@ac_external_webrtc@,1)
# External webrtc
else
DIRS += webrtc
WEBRTC_OTHER_CFLAGS = -fexceptions -DWEBRTC_POSIX=1 @ac_webrtc_cflags@
#ifneq ($(findstring sse2,@ac_webrtc_instset@),)
#    WEBRTC_SRC = \
#             modules/audio_processing/aec/aec_core_sse2.o               \
#             modules/audio_processing/aec/aec_rdft_sse2.o               \
#             modules/audio_processing/aecm/aecm_core_c.o                \
#             modules/audio_processing/ns/nsx_core_c.o                   \
#             system_wrappers/source/cpu_features.o
#else ifneq ($(findstring neon,@ac_webrtc_instset@),)
    WEBRTC_SRC = \
              modules/audio_processing/aec/aec_core_neon.o               \
              modules/audio_processing/aec/aec_rdft_neon.o               \
              modules/audio_processing/aecm/aecm_core_c.o                \
              modules/audio_processing/aecm/aecm_core_neon.o             \
              modules/audio_processing/ns/nsx_core_c.o                   \
              modules/audio_processing/ns/nsx_core_neon.o                \
              common_audio/signal_processing/cross_correlation_neon.o    \
              common_audio/signal_processing/downsample_fast_neon.o      \
              common_audio/signal_processing/min_max_operations_neon.o
    WEBRTC_OTHER_CFLAGS += -DWEBRTC_HAS_NEON
#else ifneq ($(findstring mips,@ac_webrtc_instset@),)
#    WEBRTC_SRC = \
#              modules/audio_processing/aec/aec_core_mips.o               \
#             modules/audio_processing/aec/aec_rdft_mips.o               \
#             modules/audio_processing/aecm/aecm_core_mips.o             \
#             modules/audio_processing/ns/nsx_core_mips.o                \
#             common_audio/signal_processing/cross_correlation_mips.o    \
#             common_audio/signal_processing/downsample_fast_mips.o      \
#             common_audio/signal_processing/min_max_operations_mips.o
#
#    WEBRTC_OTHER_CFLAGS += -DMIPS_FPU_LE
#else # Generic fixed point
#    WEBRTC_SRC = \
#             modules/audio_processing/aecm/aecm_core_c.o                \
#             modules/audio_processing/ns/nsx_core_c.o                   \
#             common_audio/signal_processing/complex_fft.o
#endif
endif
endif
./configure --enable-shared
make dep && make -j`nproc`
sudo make install
cd pjsip-apps/src/swig/python
make
sudo pip install .
cd ~ && sudo rm -rf pjproject-${PJSIP_VER} && rm ${PJSIP_PACKAGE}
sudo ldconfig
@emphasize
Copy link
Owner Author

Asterisk (PJSIP Realtime configuration)

System Dependenzen:

sudo apt-get install asterisk mariadb-server unixodbc unixodbc-dev python3-mysqldb
sudo pip install alembic

odbc(mariadb)

#wenn libmyodbc - momentan nur auf "Sid"(testing) - verfügbar ist kann man auf mysql umschwenken
#Asterisk wird nicht kompiliert, allerdings auf die contrib Verzeichnisse zurückgegriffen 
cd ~ && git clone https://github.com/asterisk/asterisk
git clone https://github.com/mariadb-corporation/mariadb-connector-odbc
cd mariadb-connector-odbc && git checkout tags/3.1.15
mkdir build
cd build
if [ "$(uname -m)" = "aarch64" ]; then
    DDM_DIR=/usr/lib/aarch64-linux-gnu
else
    DDM_DIR=/usr/lib/arm-linux-gnueabihf
fi
cmake ../ -LH -DCMAKE_BUILD_TYPE=Release -DCMAKE_INSTALL_PREFIX=/usr/local -DWITH_SSL=OPENSSL\
 -DDM_DIR="${DDM_DIR}" -DCMAKE_C_FLAGS_RELEASE:STRING="-w"
cmake --build . --config Release
sudo make install
cd ~ && sudo rm -rf mariadb-connector-odbc
sudo ldconfig

Datenbank einrichten

rootpasswd="xxx"
PASSWDDB="xxx"
MAINDB="asterisk"
DBUSER="asterisk" 
sudo mysql -uroot -p${rootpasswd} -e "CREATE DATABASE ${MAINDB} /*\!40100 DEFAULT CHARACTER SET utf8 */;"
sudo mysql -uroot -p${rootpasswd} -e "CREATE USER ${DBUSER}@localhost IDENTIFIED BY '${PASSWDDB}';"
sudo mysql -uroot -p${rootpasswd} -e "GRANT ALL PRIVILEGES ON $MAINDB.* TO '$DBUSER'@'localhost';"
sudo mysql -uroot -p${rootpasswd} -e "FLUSH PRIVILEGES;"
LIBPATH1=$(sudo find / -name libmaodbc.so | awk '{print $1}')
LIBPATH2=$(sudo find / -name libodbcmyS.so | awk '{print $1}')

#1 Befehl
echo "[MariaDB]
Description=ODBC for MariaDB
Driver=$LIBPATH1
Setup=$LIBPATH2
UsageCount=1" | sudo tee /etc/odbcinst.ini
SOCKPATH=$(sudo find / -name mysqld.sock | awk '{print $1}')

# 1 Befehl
echo "[${DBUSER}]
Description = MySQL connection to 'asterisk' database
Driver = MariaDB
Database = ${MAINDB}
Server = localhost
Port = 3306
Socket = $SOCKPATH" | sudo tee -a /etc/odbc.ini
sudo sed -i "0,/^enabled.*/{s/^enabled.*/enabled = yes/g}" /etc/asterisk/res_odbc.conf
sudo sed -i "s/^;username.*/username = $DBUSER/g" /etc/asterisk/res_odbc.conf
sudo sed -i "s/^;password.*/password = $PASSWDDB/g" /etc/asterisk/res_odbc.conf
sudo sed -i "s/^;logging.*/logging => yes/g" /etc/asterisk/res_odbc.conf

Tabellen der Datenbank bestücken

cd ~/asterisk/contrib/ast-db-manage/
mv config.ini.sample config.ini
sed -i "s/^sqlalchemy.url.*/sqlalchemy.url = mysql:\/\/$DBUSER:$PASSWDDB@localhost\/$MAINDB/g" config.ini
sudo alembic -c config.ini upgrade head
# 1 Befehl
echo "
[res_pjsip] ; Realtime PJSIP configuration wizard
endpoint=realtime,ps_endpoints
auth=realtime,ps_auths
aor=realtime,ps_aors
domain_alias=realtime,ps_domain_aliases
contact=realtime,ps_contacts
 
[res_pjsip_endpoint_identifier_ip]
identify=realtime,ps_endpoint_id_ips" | sudo tee -a /etc/asterisk/sorcery.conf
sudo sed -i "s/^;ps_endpoints.*/ps_endpoints => odbc,asterisk/g" /etc/asterisk/extconfig.conf
sudo sed -i "s/^;ps_auths.*/ps_auths => odbc,asterisk/g" /etc/asterisk/extconfig.conf
sudo sed -i "s/^;ps_aors.*/ps_aors => odbc,asterisk/g" /etc/asterisk/extconfig.conf
sudo sed -i "s/^;ps_domain_aliases.*/ps_domain_aliases => odbc,asterisk/g" /etc/asterisk/extconfig.conf
sudo sed -i "s/^;ps_endpoint_id_ips.*/ps_endpoint_id_ips => odbc,asterisk/g" /etc/asterisk/extconfig.conf
echo "ps_contacts => odbc,asterisk" | sudo tee -a /etc/asterisk/extconfig.conf
sudo sed -i "s/^;preload => res_odbc.so/preload => res_odbc.so/g" /etc/asterisk/modules.conf
sudo sed -i "s/^noload => res_config_odbc.so/;noload => res_config_odbc.so/g" /etc/asterisk/modules.conf
sudo sed -i "s/^;preload => res_config_odbc.so/preload => res_config_odbc.so/g" /etc/asterisk/modules.conf
sudo sed -i '/; Module names listed in "global".*/i\; Prevent the old chan_sip channel driver from loading, if you are only worried about PJSIP.\n;\nnoload => chan_sip.so\n;' /etc/asterisk/modules.conf
sudo sed -i "s/^;\[transport-udp\]/[transport-udp]/g" /etc/asterisk/pjsip.conf
sudo sed -i "0,/^;type=transport.*/{s/^;type=transport.*/type=transport/g}" /etc/asterisk/pjsip.conf
sudo sed -i "0,/^;protocol=udp.*/{s/^;protocol=udp.*/protocol=udp    ;udp,tcp,tls,ws,wss/g}" /etc/asterisk/pjsip.conf
sudo sed -i "0,/^;bind=0.0.0.0.*/{s/^;bind=0.0.0.0.*/bind=0.0.0.0/g}" /etc/asterisk/pjsip.conf

Videosupport

sudo sed -i "0,/^;videosupport=yes.*/{s/^;videosupport=yes.*/videosupport=yes                ; Turn on support for SIP video. You need to turn this/g}" /etc/asterisk/sip.conf

Hier muss geklärt werden, wie viele stationen man besitzt/konfigurieren will (und welche nummern vergibt; hier:620), im Grundsatz:

sudo mysql -u${DBUSER} -p${PASSWDDB} -e "INSERT INTO ${MAINDB}.ps_aors (id, max_contacts) VALUES (620, 5);"
sudo mysql -u${DBUSER} -p${PASSWDDB} -e "INSERT INTO ${MAINDB}.ps_auths (id, auth_type, password, username) VALUES (620, 'userpass', <passwordnumber>, 620);"
# testing kann hier umbennant werden, muss dann aber auch im "dialplan" geändert
sudo mysql -u${DBUSER} -p${PASSWDDB} -e "INSERT INTO ${MAINDB}.ps_endpoints (id, transport, aors, auth, context, disallow, allow, direct_media) values (620, 'transport-udp', '620', '620', 'testing', 'all', 'ulaw;alaw;gsm;g726;g722;h264;h263;vp8;vp9', 'no');"

Dialplan (falls der name eben geändert wurde, auch hier ändern, ebenso exten => _6XX je nach nummernvergabe

echo "
[testing]
exten => _6XX,1,NoOp()
same => n,Dial(PJSIP/${EXTEN})" | sudo tee -a /etc/asterisk/extensions.conf

@emphasize
Copy link
Owner Author

emphasize commented Apr 24, 2022

Doorpi-config (unter sipphone)

server.password = <Passwort der Asterisk-Doorpi Verbindung> 
server.username = <Nummer der Asterisk-Doorpi Verbindung> 
server.realm = asterisk
server.server = <IP>
video.enabled = true
type = pjsua2

Wer (zusätzlich) einen Videoserver nutzt muss eventuell

video.device = <ID>

einstellen, wobei ID in den logs

[INFO]          [doorpi.sipphone.from_pjsua2.config] Video Devices:
[INFO]          [doorpi.sipphone.from_pjsua2.config]    ID:0 v4l2:VirtualDoorpiCam #0  <----- this is the (default) loopback device

zu finden ist. Mehr zu Videoserver findet man in der (Web)-Configuration sektion "videoserver"
unter http://<IP>:50317/


So, damit das ganze aber im Videomodus funktioniert, muss man Doorpi in einer Xsession laufen lassen:

sudo xinit /usr/local/bin/doorpi --configfile /usr/local/etc/doorpi/conf/doorpi.ini &

um doorpi (testweise) zu loggen

touch log.log
sudo xinit /usr/local/bin/doorpi --configfile /usr/local/etc/doorpi/conf/doorpi.ini > /home/pi/log.log 2>&1 &
tail -f log.log

Optional, wenn man über ssh testen will

#--- DEBUG: x session über ssh zulassen
if [ -f /etc/X11/Xwrapper.config ]; then
    sudo sed -i "s/allowed_users=.*/allowed_users=anybody/g" /etc/X11/Xwrapper.config
else
    echo "allowed_users=anybody" | sudo tee /etc/X11/Xwrapper.config
fi

@emphasize emphasize changed the title [Build] PJSUA / Asterisk [Build] PJSUA2 / Asterisk (video-spezifisch) Apr 24, 2022
@rookie10
Copy link

rookie10 commented Sep 16, 2022

Hallo @emphasize ,

Hättest du nicht Lust dein Project im Doorpi Forum zu announcen. Es wäre wirklich schade für die Riesen Arbeit die du dir gemacht hast, nicht dem Doorpi Gemeinde zur Verfügung zu stellen.
Die aktuelle Doorpi Variante mit Pyton 2.x, ist nur noch unter erschwerten Bedingungen zu installieren abgesehen das die Version von dir doch einige Zusatzfeatures bereit hält.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants