emphasize / DoorPi

OpenSource VoIP Door-Intercomstation
https://www.doorpi.org/forum/
Other
6 stars 2 forks source link

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

Open emphasize opened 2 years ago

emphasize commented 2 years ago

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:

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 commented 2 years ago

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 commented 2 years ago

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
rookie10 commented 1 year ago

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.