Linphone-SDK Ubuntu 22.04 Dockerイメージの作成とアプリのビルド(IPv6対応)

Linphone-SDK Dockerイメージの作成(Ubuntu 22.04)

Linphone-SDKのDockerコンテナ内でLinphoneアプリやflexisipサーバをビルドするため、Linphone-SDKのDockerイメージを作成します。必要なのは下記でダウンロードした docker-files ディレクトリです。

$ git clone https://gitlab.linphone.org/BC/public/linphone-sdk.git

docker-files ディレクトリ内の bc-dev-ubuntu-rolling を参考にして Ubuntu 22.04 に対応した新規ファイルを作成します。

How to Switch to Ubuntu Rolling Rhino: A Rolling Release Version of Ubuntu

bc-dev-ubuntu-22-04-lts

FROM ubuntu:22.04

MAINTAINER Takanobu Fuse <[email protected]>

# Configure locale
RUN apt-get update && \
    apt-get install -y locales && \
    apt-get clean && \
    echo "en_US.UTF-8 UTF-8" > /etc/locale.gen && \
    locale-gen
ENV LANG='en_US.UTF-8' LANGUAGE='en_US:en' LC_ALL='en_US.UTF-8'
ENV TZ=Europe/Paris
RUN ln -snf /usr/share/zoneinfo/$TZ /etc/localtime && echo $TZ > /etc/timezone
ARG DEBIAN_FRONTEND=noninteractive

ENV SHELL=/bin/bash
#ENV PS1='\[\e[33m\]\u@bc-dev-ubuntu-22-04-lts>\[\e[0m\] '

# Install common general tools
RUN apt-get update && \
    apt-get install -y nano sudo vim && \
    apt-get clean

# Install development tools
RUN apt-get update && \
    apt-get install -y alien at autoconf bison ccache clang cmake doxygen elfutils g++ gdb git graphviz intltool libtool lsb-release make nasm ninja-build openssh-client patch python3-pip python3-pystache python-six yasm && \
    apt-get clean

# Install linphone & flexisip dependencies development packages
RUN apt-get update && \
    apt-get install -y libasound2-dev libavcodec-dev libavutil-dev libbsd-dev libegl1-mesa-dev libglew-dev libgsm1-dev libjansson-dev libmariadb-dev-compat libmbedtls-dev libopus-dev libpq-dev libprotobuf-dev libpulse-dev libqt5svg5-dev libsnmp-dev libspeex-dev libspeexdsp-dev libsqlite3-dev libsrtp2-dev libssl-dev libswscale-dev libturbojpeg0-dev libv4l-dev libvpx-dev libxerces-c-dev libxml2-dev libxv-dev protobuf-compiler qt3d5-dev qtbase5-dev qtbase5-dev-tools qtchooser qt5-qmake qtconnectivity5-dev qtdeclarative5-dev qtdeclarative5-dev-tools qtdeclarative5-dev-tools qtquickcontrols2-5-dev qttools5-dev qttools5-dev-tools xsdcxx && \
    apt-get clean

# Configure user bc
RUN useradd -ms /bin/bash bc && \
    echo 'bc:cotcot' | chpasswd && \
    echo 'bc ALL=(ALL) NOPASSWD:ALL' >> /etc/sudoers

USER bc
WORKDIR /home/bc
COPY --chown=bc rpmmacros /home/bc/.rpmmacros
CMD bash

Makefikeの編集(Ubuntu 22.04のセクション追加)

.....
.....
ubuntu-22.04-LTS:
	docker build -f bc-dev-ubuntu-22-04-lts -t $(BASE_NAME)/bc-dev-ubuntu:22.04 --rm .
.....
.....

ビルド(直接 docker build コマンドでビルドしても構いません)

$ make ubuntu-22.04-LTS

Dockerイメージの確認

$ docker images
REPOSITORY                                                      TAG          IMAGE ID       CREATED          SIZE
gitlab.linphone.org:4567/bc/public/linphone-sdk/bc-dev-ubuntu   22.04        6ee9dee48674   47 minutes ago   2.28GB

任意のフォルダ(Linphoneまたはflexisipをビルドするフォルダ)内で上記イメージによるコンテナを起動

$ docker run --name linphone-sdk -v $PWD:/home/bc -it gitlab.linphone.org:4567/bc/public/linphone-sdk/bc-dev-ubuntu:22.04
bc@616cdfa4bb84:~$

Linphone-Desktopのビルド

ホストマシンの環境に依存しないAppImageフォーマットでアプリを作成します。

Linphone-SDKコンテナの起動

上記投稿記事のイメージからコンテナを起動します。FUSE を使用するための管理者権限オプションを付与する必要があります。

$ docker run --device /dev/fuse --cap-add SYS_ADMIN --security-opt apparmor:unconfined --name linphone-sdk -v $PWD:/home/bc -it gitlab.linphone.org:4567/bc/public/linphone-sdk/bc-dev-ubuntu:22.04

AppImages require FUSE version 2 to run. Filesystem in Userspace (FUSE) is a system that lets non-root users mount filesystems.

linphone-sdk コンテナ内で以下のコマンドを実行

$ pip install pystache six
$ eval "$(qtchooser -print-env)"
$ export Qt5_DIR=${QTLIBDIR}/cmake/Qt5
$ export PATH=${QTTOOLDIR}:$PATH

ビルドに必要な追加パッケージをインストール

$ sudo apt install wget fuse libfuse2
$ sudo apt install qml-module-qt-labs-folderlistmodel qml-module-qt-labs-platform qml-module-qt-labs-settings qml-module-qtgraphicaleffects qml-module-qtqml qml-module-qtqml-models2 qml-module-qtquick-controls qml-module-qtquick-controls2 qml-module-qtquick-dialogs qml-module-qtquick-layouts qml-module-qtquick-privatewidgets qml-module-qtquick-shapes qml-module-qtquick-templates2 qml-module-qtquick-window2 qml-module-qtquick2

qml-module については、以下のLinphone Desktop バグレポートも参照して下さい。
https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=978108

Qtドキュメント
https://doc.qt.io/

QML Modules
https://doc.qt.io/qt-5/qtqml-modules-topic.html

Qt Product Map

Qtオープンソース

ターミナルまたはスクリプトによりインストール

$ sudo apt install -y qtcreator qtbase5-dev qt5-qmake cmake

ソースのダウンロード・Makeファイルの作成・ビルド

AppImageパッケージを出力するため -DENABLE_APP_PACKAGING=YES を指定

$ git clone https://gitlab.linphone.org/BC/public/linphone-desktop.git --recursive
$ cd linphone-desktop
$ mkdir build
$ cd build
$ cmake .. -DENABLE_APP_PACKAGING=YES -DCMAKE_BUILD_PARALLEL_LEVEL=10 -DCMAKE_BUILD_TYPE=RelWithDebInfo
$ cmake --build . --target install --parallel 10 --config RelWithDebInfo

RelWithDebInfo

以下のディレクトリ・ファイル名でAppImageが作成されます。
実行権は付与されているので、これを任意の場所へ移動してダブルクリックして起動します。
build/OUTPUT/Packages/Linphone-5.1.0-alpha.40+e198f5f7.AppImage

シェルから起動することで各種ログを確認することが出来ます。

$ ./Linphone-5.1.0-alpha.40+e198f5f7.AppImage

下記も参照して下さい。

Flexisipのビルド・DEBパッケージの作成

引き続き linphone-sdk コンテナを利用します。
初めにコンテナ内で flexisip のソースと関連パッケージをダウンロードします。

$ git clone https://gitlab.linphone.org/BC/public/flexisip --recursive -b <branch_name>

Replace <branch_name> by one of the following:

  • A release tag name if you want a specific release (e.g. “2.0.0”).
  • A release branch name if you want a specific release plus all post release fixes (e.g. “release/2.0”)
  • “master” if you want the development version.

次に flexisip のビルドに必要なパッケージを、以下ファイルを参考に追加インストール・ビルドインストールします。

注)flexisipをビルドするための開発環境は、flexisip/docker内のOS別Dockerfileからイメージを作成することでコンテナとして構築できます。

$ cd docker/container
$ docker build -f bc-dev-ubuntu-22-04 -t bc-dev-ubuntu:22-04 --rm .
$ docker images
REPOSITORY                                                      TAG                       IMAGE ID       CREATED             SIZE
bc-dev-ubuntu                                                   22-04                     6c4a54ac8b6a   About an hour ago   1.94GB

プロジェクトフォルダーへ移動し上記イメージからコンテナ起動

$ cd ../../
$ docker run --name flexisip-sdk -v $PWD:/home/bc -it bc-dev-ubuntu:22-04

下記ビルドプロセスを実行します。


追加パッケージ

$ sudo apt install file llvm libboost-dev libboost-system-dev libboost-thread-dev libhiredis-dev libjsoncpp-dev mariadb-server libnghttp2-dev redis-server

追加ビルド・インストールパッケージ(スクリプトによりビルド・インストール)

$ cd flexisip/docker
$ sudo ./libnghttp2_asio_install.sh 1.43.0

上記の準備ができたら以下のフローで flexisip をビルドして下さい。

$ mkdir build
$ cd build
$ cmake .. -DCMAKE_INSTALL_PREFIX=/opt/belledonne-communications -DCMAKE_BUILD_TYPE=RelWithDebInfo -DSYSCONF_INSTALL_DIR=/etc -DCPACK_GENERATOR=DEB
$ make package

問題なければ以下2種類のパッケージが作成されます。

bc-flexisip_2.3.0-0.*_amd64.deb
bc-flexisip-dbgsym_2.3.0-0.*_amd64.ddeb


OS別flexisip公式レポジトリのインストール

CentOS, RockyLinux, Ubuntu, Debian対応。flexisipをビルドせずにレポジトリを登録し、新規にflexisipDockerイメージを作成する場合は以下を参照して下さい。

Supported distributions

CentOS 7 RockyLinux 8 RockyLinux 9 Debian 8 (Jessie) Debian 9 (Stretch) Debian 10 (Buster) Debian 11 (Bullseye) Debian 12 (Bookworm) Ubuntu 18.04 LTS (Bionic Beaver) Ubuntu 22.04 LTS (Jammy Jellyfish)
Flexisip 2.0
Flexisip 2.1
Flexisip 2.2 Deprecated
Flexisip 2.3 (beta) Deprecated Deprecated Deprecated Deprecated
Flexisip 2.4 (alpha) Deprecated Deprecated Deprecated Deprecated

/etc/apt/sources.list.d/belledonne.list

# For Ubuntu 22.04 LTS
deb [arch=amd64] http://linphone.org/snapshots/ubuntu jammy stable # hotfix beta alpha
# For Ubuntu
$ wget https://www.linphone.org/snapshots/ubuntu/pubkey.gpg -O - | sudo apt-key add -
# Not doing this can result in the following error : "[SOCI] connection pool open error: Failed to find shared library for backend mysql"
$ sudo apt install libmariadb-dev
# Update & Install
$ sudo apt update
$ sudo apt install bc-flexisip

上記レポジトリを利用したイメージファイルを作成するためのDockerfile

flex-from-ubuntu-apt-repo

FROM ubuntu:22.04
MAINTAINER  Takanobu Fuse <[email protected]>

# Prepare dependencies
RUN apt-get update
RUN apt-get install -y nano xsdcxx gdb libmariadb3 snmp-mibs-downloader snmp snmpd iproute2 iptables wget gnupg2
RUN echo 'deb [arch=amd64] http://linphone.org/snapshots/ubuntu jammy stable' > /etc/apt/sources.list.d/belledonne.list
RUN wget https://www.linphone.org/snapshots/ubuntu/pubkey.gpg -O - | apt-key add -
RUN apt-get update && apt-get install -y bc-flexisip

# Add it to the default path
ENV PATH=$PATH:/opt/belledonne-communications/bin

WORKDIR /opt/belledonne-communications

# Generate a default configuration
RUN flexisip --dump-default all > /etc/flexisip/flexisip.conf

VOLUME /etc/opt/belledonne-communications/flexisip
VOLUME /var/opt/belledonne-communications/log/flexisip
COPY flexisip-entrypoint.sh /
COPY backtrace.gdb /
RUN chmod a+x /flexisip-entrypoint.sh

# Script to wait db before launch flexisip [Licence Apache2]
ADD https://github.com/ufoscout/docker-compose-wait/releases/download/2.2.1/wait /wait
RUN chmod +x /wait

ENTRYPOINT ["/flexisip-entrypoint.sh"]
CMD flexisip

上記Dockerfileからflexisipレポジトリを取り込んでflexisipをインストールしたイメージファイルを作成

$ docker build -f flex-from-ubuntu-apt-repo --pull --no-cache -t flex-from-ubuntu-apt-repo:22.04 --rm .

コンテナ起動

$ docker run -d --network host --name ubuntu-flexisip-repo flex-from-ubuntu-apt-repo:22.04 --server proxy

参考)

Flexisip Dockerイメージの作成

前記事で作成した flexisip のパッケージを利用して Flexisip Dockerイメージ を作成します。

deb,ddeb パッケージを以下のフォルダにコピーして作業します。

flex-from-deb を参考にUbuntu 22.04ベースのDockerfile flex-from-ubuntu-deb を作成しMakefileにビルドコマンドを追加します。(snmp-mibs-downloader snmp snmpd のインストールはオプション。SNMPによりflexisipの設定ファイル内の各セクションの設定事項の確認と書換えが行えます。)

flex-from-ubuntu-deb

FROM ubuntu:22.04
MAINTAINER  Takanobu Fuse <[email protected]>

# Prepare dependencies
RUN apt-get update
RUN apt-get install -y nano xsdcxx gdb libmariadb3 snmp-mibs-downloader snmp snmpd iproute2

# Get flexisip package
COPY *.deb *.ddeb deb-packages/
RUN apt-get install -y /deb-packages/*
RUN rm -rf /deb-packages

# Add it to the default path
ENV PATH=$PATH:/opt/belledonne-communications/bin

WORKDIR /opt/belledonne-communications

# Generate a default configuration
RUN flexisip --dump-default all > /etc/flexisip/flexisip.conf

VOLUME /etc/opt/belledonne-communications/flexisip
VOLUME /var/opt/belledonne-communications/log/flexisip
COPY flexisip-entrypoint.sh /
COPY backtrace.gdb /
RUN chmod a+x /flexisip-entrypoint.sh

# Script to wait db before launch flexisip [Licence Apache2]
ADD https://github.com/ufoscout/docker-compose-wait/releases/download/2.2.1/wait /wait
RUN chmod +x /wait

ENTRYPOINT ["/flexisip-entrypoint.sh"]
CMD flexisip

Makefile 注)追加部分のみ記載

.....
.....

# For Ubuntu 22.04
flexisip-ubuntu-deb-before:
	$(eval DOCKER_FILE = flex-from-ubuntu-deb)
	# forcing context to .
	# at the moment of the condition above being executed, $DOCKER_FILE doesn't have the right value
	$(eval CONTEXT = .)
	$(eval DOCKER_TAG = $(DOCKER_TAG)-deb)

.....
.....
.....

# For Ubuntu 22.04
flexisip-ubuntu-deb-build: flexisip-ubuntu-deb-before flexisip-build

flexisip-ubuntu-deb-push: flexisip-ubuntu-deb-before flexisip-push

flexisip-ubuntu-deb-clean: flexisip-ubuntu-deb-before flexisip-clean

.....

ビルド
注)flexisip-entrypoint.sh"ulimit -c unlimited*" を修正。'*'を削除。

$ make flexisip-ubuntu-deb-build

イメージファイルの確認

$ docker images
REPOSITORY                                                      TAG                            IMAGE ID       CREATED       SIZE
gitlab.linphone.org:4567/bc/public/flexisip                     2.3.0-alpha-29-gb19a1ce5-deb   b3e1a47e3efd   9 hours ago   775MB

コンテナ起動
設定ファイルを定義していないため、このイメージから起動できるのはプロキシモードのみとなります。設定ファイル flexisip.conf を出力するためプロキシモードでコンテナを起動して下さい。

$ docker run -d --network host --name ubuntu-flexisip <IMAGE_ID> --server proxy
$ docker ps
CONTAINER ID   IMAGE          COMMAND                  CREATED       STATUS       PORTS     NAMES
0fd6f8e90621   b3e1a47e3efd   "/flexisip-entrypoin…"   9 hours ago   Up 9 hours             ubuntu-flexisip

ログ確認

$ docker logs ubuntu-flexisip
Flexisip docker params : flexisip --server proxy
--server param found, starting only one Flexisip instance

設定ファイル flexisip.conf をコピー

$ docker cp ubuntu-flexisip:/etc/flexisip/flexisip.conf ./

設定ファイル : flexisip.conf

グローバル設定

flexisip.confのセクションごとにポイントを纏めます。

[global]

user-errors-logs=true

transports=sip:ficus-home.duckdns.org:5060;maddr=172.16.0.6 sips:ficus-home.duckdns.org:5061;maddr=172.16.0.6

tls-certificates-file=/etc/letsencrypt/live/sip.example.com/fullchain.pem

tls-certificates-private-key=/etc/letsencrypt/live/sip.example.com/privkey.pem

tls-certificates-ca-file=/etc/letsencrypt/live/sip.example.com/cert.pem

[event-logs]

enabled=true

[presence-server]

rls-database-connection=db='flexisip_presence' user='flexisip' password='flexisip' host='flexisip-mariadb'

rls-database-max-thread=20

[conference-server]

conference-factory-uris=sip:[email protected]

conference-focus-uris=

local-domains=ficus-home.duckdns.org

database-connection-string=db='flexisip_conference' user='flexisip' password='flexisip' host='flexisip-mariadb'

[regevent-server]

transport=sip:172.16.0.6:6065;transport=tcp

[b2bua-server] pending

#transport=sip:127.0.0.1:6067;transport=tcp

#outbound-proxy=sip:127.0.0.1:5060;transport=tcp

[b2bua-server::trenscrypter] pending

#outgoing-enc-regex=

#outgoing-srtp-regex=

[module::DoSProtection]

white-list=ficus-home.duckdns.org sip.linphone.org

[module::NatHelper]

# documentation here : https://wiki.linphone.org/xwiki/wiki/public/view/Flexisip/Configuration/Filter%20syntax/
# Default: 
filter=!(user-agent contains 'No NatHelper')

[module::Authentication]

enabled=true

#trusted-hosts=

auth-domains=ficus-home.duckdns.org localhost

available-algorithms=SHA-256 MD5

db-implementation=soci

soci-connection-string=db='flexisip' user='flexisip' password='flexisip' host='flexisip-mariadb'

soci-password-request=select passwords.password, passwords.algorithm from accounts inner join passwords on accounts.id=passwords.account_id where username = :id and domain = :domain

soci-poolsize=25

[module::RegEvent]

regevent-server=sip:172.16.0.6:6065;transport=tcp

[module::B2bua] pending

#enabled=false

# documentation here : https://wiki.linphone.org/xwiki/wiki/public/view/Flexisip/Configuration/Filter%20syntax/
#filter=

# A sip uri where to send all the relevent requests.
# Default: sip:127.0.0.1:6067;transport=tcp
#b2bua-server=sip:127.0.0.1:6067;transport=tcp

[module::Presence] pending

enabled=true

# A SIP URI where to send all presence related requests.
# Default: sip:127.0.0.1:5065;transport=tcp
#presence-server=sip:127.0.0.1:5065;transport=tcp

[module::Registrar]

reg-domains=ficus-home.duckdns.org localhost

db-implementation=redis

redis-server-domain=redis
 
redis-auth-password=xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx

[module::Router] pending

#message-database-enabled=false

#message-database-backend=mysql

#message-database-connection-string=db='mydb' user='myuser' password='mypass' host='myhost.com'

[module::MediaRelay]

# The minimal value of SDP port range
# Default: 1024
sdp-port-range-min=10000

# The maximal value of SDP port range
# Default: 65535
sdp-port-range-max=10050

[module::Forward]

route=<sip:172.16.0.6;transport=tcp>

ワンドメインでの設定ファイル例


SOCI

Supported Backends and Features

Features - SOCI (master)

Follow the links to learn more about each backend and detailed supported features.

Oracle PostgreSQL MySQL SQLite3 Firebird ODBC DB2
Binding by Name YES YES (≥8.0) YES YES YES YES YES
Dynamic Binding YES YES YES YES YES YES
Bulk Operations YES YES YES YES YES YES YES
Transactions YES YES YES (≥4.0) YES YES YES YES
BLOB Data Type YES YES YES (mapped to std::string) YES YES NO NO
RowID Data Type YES YES NO NO NO NO NO
Nested Statements YES NO NO NO NO NO YES
Stored Procedures YES YES NO (but stored functions, YES) NO YES NO YES

SNMP (Simple Network Management Protocol)

flexisipの設定ファイルでsnmpを有効にした場合、snmpコマンドによりflexisipの設定事項の確認と書換えが行えます。必要なパッケージは snmp-mibs-downloader, snmp, snmpd の3つです。

注) 特に必要なければ、このオプションは無効のままで構いません。念の為、FlexisipDockerイメージ作成時に上記パッケージを予めインストールしておきましょう。

下記flexisipsnmpを参考に snmpd.conf に必要な項目を追加・変更します。

追加・変更項目

agentAddress  udp:127.0.0.1:161
master agentx
agentXPerms  0660 0550 root root
rocommunity public localhost
rwcommunity private localhost

/etc/snmp/snmpd.conf

###########################################################################
#
# snmpd.conf
# An example configuration file for configuring the Net-SNMP agent ('snmpd')
# See snmpd.conf(5) man page for details
#
###########################################################################
# SECTION: System Information Setup
#

# syslocation: The [typically physical] location of the system.
#   Note that setting this value here means that when trying to
#   perform an snmp SET operation to the sysLocation.0 variable will make
#   the agent return the "notWritable" error code.  IE, including
#   this token in the snmpd.conf file will disable write access to
#   the variable.
#   arguments:  location_string
sysLocation    Sitting on the Dock of the Bay
sysContact     Me <[email protected]>

# sysservices: The proper value for the sysServices object.
#   arguments:  sysservices_number
sysServices    72



###########################################################################
# SECTION: Agent Operating Mode
#
#   This section defines how the agent will operate when it
#   is running.

# master: Should the agent operate as a master agent or not.
#   Currently, the only supported master agent type for this token
#   is "agentx".
#   
#   arguments: (on|yes|agentx|all|off|no)

master  agentx
agentXPerms  0660 0550 root root
# agentaddress: The IP address and port number that the agent will listen on.
#   By default the agent listens to any and all traffic from any
#   interface on the default SNMP port (161).  This allows you to
#   specify which address, interface, transport type and port(s) that you
#   want the agent to listen on.  Multiple definitions of this token
#   are concatenated together (using ':'s).
#   arguments: [transport:]port[@interface/address],...

agentaddress  udp:127.0.0.1:161



###########################################################################
# SECTION: Access Control Setup
#
#   This section defines who is allowed to talk to your running
#   snmp agent.

# Views 
#   arguments viewname included [oid]

#  system + hrSystem groups only
view   systemonly  included   .1.3.6.1.2.1.1
view   systemonly  included   .1.3.6.1.2.1.25.1


# rocommunity: a SNMPv1/SNMPv2c read-only access community name
#   arguments:  community [default|hostname|network/bits] [oid | -V view]

# Read-only access to everyone to the systemonly view
rocommunity public localhost
rwcommunity private localhost

rocommunity  public default -V systemonly
rocommunity6 public default -V systemonly

# SNMPv3 doesn't use communities, but users with (optionally) an
# authentication and encryption string. This user needs to be created
# with what they can view with rouser/rwuser lines in this file.
#
# createUser username (MD5|SHA|SHA-512|SHA-384|SHA-256|SHA-224) authpassphrase [DES|AES] [privpassphrase]
# e.g.
# createuser authPrivUser SHA-512 myauthphrase AES myprivphrase
#
# This should be put into /var/lib/snmp/snmpd.conf 
#
# rouser: a SNMPv3 read-only access username
#    arguments: username [noauth|auth|priv [OID | -V VIEW [CONTEXT]]]
rouser authPrivUser authpriv -V systemonly

# include a all *.conf files in a directory
includeDir /etc/snmp/snmpd.conf.d

snmpデーモンの起動

# /etc/init.d/snmpd start

flexisipmibの作成

# mkdir -p ~/.snmp/mibs
# flexisip --dump-mibs > ~/.snmp/mibs/fleximib.txt

flexisipmib出力
注) flexisip.conf内でコメントアウトしているデフォルト項目が全てアンコメントになります。

# snmpwalk -m FLEXISIP-MIB  -v 2c -c public -Of localhost FLEXISIP-MIB::flexisipMIB
.iso.org.dod.internet.private.enterprises.flexisipMIB.flexisip.notif.msg.0 = ""
.iso.org.dod.internet.private.enterprises.flexisipMIB.flexisip.notif.source.0 = ""
.iso.org.dod.internet.private.enterprises.flexisipMIB.flexisip.global.runtimeError.0 = ""
.iso.org.dod.internet.private.enterprises.flexisipMIB.flexisip.global.versionNumber.0 = STRING: "2.3.0-alpha-29-gb19a1ce5"
.iso.org.dod.internet.private.enterprises.flexisipMIB.flexisip.global.dumpCorefiles.0 = INTEGER: false(0)
.iso.org.dod.internet.private.enterprises.flexisipMIB.flexisip.global.countIncomingResponse401.0 = Counter64: 0
.iso.org.dod.internet.private.enterprises.flexisipMIB.flexisip.global.countIncomingResponse603.0 = Counter64: 0
.iso.org.dod.internet.private.enterprises.flexisipMIB.flexisip.global.logDirectory.0 = STRING: "/var/opt/belledonne-communications/log/flexisip"
.iso.org.dod.internet.private.enterprises.flexisipMIB.flexisip.global.tlsCertificatesPrivateKey.0 = ""
.iso.org.dod.internet.private.enterprises.flexisipMIB.flexisip.global.countReply408.0 = Counter64: 0
.iso.org.dod.internet.private.enterprises.flexisipMIB.flexisip.global.maxLogSize.0 = STRING: "-1"
.iso.org.dod.internet.private.enterprises.flexisipMIB.flexisip.global.countReplyUnknown.0 = Counter64: 0
.iso.org.dod.internet.private.enterprises.flexisipMIB.flexisip.global.keepaliveInterval.0 = INTEGER: 1800
.iso.org.dod.internet.private.enterprises.flexisipMIB.flexisip.global.countIncomingRequestUnknown.0 = Counter64: 0
.iso.org.dod.internet.private.enterprises.flexisipMIB.flexisip.global.countReply101.0 = Counter64: 0
.iso.org.dod.internet.private.enterprises.flexisipMIB.flexisip.global.rtpBindAddress.0 = STRING: "0.0.0.0 ::0"
.iso.org.dod.internet.private.enterprises.flexisipMIB.flexisip.global.enableSnmp.0 = INTEGER: true(1)
.iso.org.dod.internet.private.enterprises.flexisipMIB.flexisip.global.syslogLevel.0 = STRING: "debug"
.......
.......
.......

上記の特定の項目のみ出力

# snmpget -m FLEXISIP-MIB -v 2c -c public -Of localhost FLEXISIP-MIB::flexisipMIB.flexisip.global.syslogLevel.0
.iso.org.dod.internet.private.enterprises.flexisipMIB.flexisip.global.syslogLevel.0 = STRING: "debug"

設定項目を変更(systemlogLeveldebugからerrorへ変更)

# snmpset -m FLEXISIP-MIB  -v 2c -c private localhost FLEXISIP-MIB::flexisipMIB.flexisip.global.syslogLevel.0 s "error"

YouTube SNMP Operation

Certbot DockerコンテナによるSSL認証手続き

flexisipによるシステム運用にはSSL(TLS)認証は不可欠です。Dockerコンテナにより事前に取得しておくことによりnginxflexisipの設定に反映させて下さい。以下の記事も参照願います。

Alternative 1: Docker
Get Certbot — Certbot 2.6.0 documentation

注) $PWDはコマンドを実行するディレクトリ

$ docker run -it --rm --name certbot -v "$PWD/letsencrypt:/etc/letsencrypt" -p 80:80 certbot/certbot certonly --standalone -d www.example.com

Setting up automated renewal
User Guide — Certbot 2.6.0 documentation

ホストマシンのクロンジョブに以下のCertbot Dockerコンテナによるrenewコマンドを追加
注) ディレクトリには絶対パスを指定すること。

$ docker run -it --rm --name certbot -v "/??/??/.../letsencrypt:/etc/letsencrypt" -p 80:80 certbot/certbot renew

証明書の期限は90日のため60日毎の更新手続きを推奨しています。

flexisip.conf での設定は以下のようにします。

tls-certificates-file=/etc/letsencrypt/live/sip.example.com/fullchain.pem
tls-certificates-private-key=/etc/letsencrypt/live/sip.example.com/privkey.pem
tls-certificates-ca-file=/etc/letsencrypt/live/sip.example.com/cert.pem

flexisip-account-managerの導入

flexisip-account-manager(以下 fam )のデザインは Laravel (PHPフレームワーク)によるものです。Docker Compose ファイルで使用するサービスの一つとして、専用のイメージをビルドするための Docker ファイル : php-fpm-alpine-laravel を作成します。

ComposerPHP機能拡張のインストールには、DockerHubのPHP公認ページが推奨している以下の docker-php-extension-installer を利用します。

php-fpm-alpine-laravel

FROM php:fpm-alpine

# Set working directory
WORKDIR /var/www/html

RUN apk add --no-cache bash nano libpng-dev freetype-dev libjpeg-turbo-dev libxml2-dev

# Install Composer and PHP extensions
RUN curl -sSLf \
        -o /usr/local/bin/install-php-extensions \
        https://github.com/mlocati/docker-php-extension-installer/releases/latest/download/install-php-extensions && \
    chmod +x /usr/local/bin/install-php-extensions && \
    install-php-extensions redis mysqli xmlrpc pdo_mysql @composer && \
    IPE_GD_WITHOUTAVIF=1 install-php-extensions gd

# Installing Laravel
RUN chown -R www-data:www-data /var/www/html
RUN composer global require laravel/installer \
    && ln -s /root/.config/composer/vendor/laravel/installer/bin/laravel /usr/local/bin/laravel

ダウンロード:GitHub

Docker Composeファイル(IPv6対応)の作成

docker-compose.yml

version: '3.5'

services:
##### redis-server
  redis:
    container_name: redis
    image: redis:alpine
    volumes:
        - ./redis:/etc/redis
    # need to download default config file:redis.conf from https://redis.io/topics/config
    # then modify it to enable the auth access(password), and input it into /redis/etc directory.
    command: ["redis-server", "/etc/redis/redis.conf"]
    privileged: true
    restart: always
    networks: 
      proxy-tier:

##### nginx
  nginx:
    container_name: nginx
    image: nginx:alpine
    tty: true
    ports:
      - "80:80"
      - "443:443"
    volumes:
      # nginx config
      - ./nginx:/etc/nginx/conf.d
      # certbot letsencrypt certification. Created by docker_hub certbot/certbot
      # $ docker run -it --rm --name certbot -v "$PWD/letsencrypt:/etc/letsencrypt" -p 80:80 certbot/certbot certonly --standalone -d www.example.com
      # Add the below cronjob into the host crontab.
      # docker run -it --rm --name certbot -v "/??/??/.../letsencrypt:/etc/letsencrypt" -p 80:80 certbot/certbot renew
      - ./letsencrypt:/etc/letsencrypt
      # shared the directory /flexisip-account-manager in php-fpm-laravel container
      - ./flexisip-account-manager/flexiapi:/var/www/html/flexiapi
      # shared the directory /var/www/html in phpmysql-fpm container
      - phpmyadmin:/var/www/html/phpmyadmin
    restart: always
    networks: 
      proxy-tier:     

##### mariadb
  flexisip-mariadb:
    container_name: flexisip-mariadb
    image: mariadb
    restart: always
    volumes:
      - ./db:/var/lib/mysql
    environment:
      - MYSQL_ROOT_PASSWORD=${MYSQL_ROOT_PASSWORD}
      - MYSQL_DATABASE=${MYSQL_DATABASE}
      - MYSQL_USER=${MYSQL_USER}
      - MYSQL_PASSWORD=${MYSQL_PASSWORD}
    networks: 
      proxy-tier:

### flexisip
  ubuntu-flexisip:
    container_name: ubuntu-flexisip
    image: gitlab.linphone.org:4567/bc/public/flexisip:2.3.0-alpha-29-gb19a1ce5-deb  
    volumes:
      - ./letsencrypt:/etc/letsencrypt
      # previously need to add "flexisip" directory and input "flexisip.conf" into it.
      - ./flexisip_conf:/etc/flexisip
      # for conference server linphone db directory
      - ./linphone:/root/.local/share/linphone
    extra_hosts:
      - "sip.example.com:192.168.xx.xx"
    depends_on:
      - redis
      - nginx
      - flexisip-mariadb
    restart: always
    # https://github.com/BelledonneCommunications/flexisip/blob/master/docker/flexisip-entrypoint.sh
    # for starting only "proxy" server
    command: ["--server","proxy"]
    # for starting "proxy, presence, conference" servers
    #command: [""]
        ## allow the privilege of network to the container
    cap_add:
      - NET_ADMIN
      - SYS_RESOURCE
    network_mode: "host"
    
##### phpmyadmin-fpm
  phpmyadmin-fpm:
    container_name: phpmyadmin-fpm
    image: phpmyadmin/phpmyadmin:fpm-alpine
    tty: true
    expose: 
      - "9000"
    environment:
      - PMA_HOST=flexisip-mariadb
      - PMA_PORT=3306
      - PMA_ABSOLUTE_URI=http://localhost/phpmyadmin
    volumes:
      - phpmyadmin:/var/www/html
      - /sessions
    depends_on:
      - flexisip-mariadb
    restart: always
    networks: 
      proxy-tier:
        
##### php-fpm-laravel
  php-fpm-laravel:
    container_name: php-fpm-laravel
    build: 
      context: ./docker_files
      dockerfile: php-fpm-alpine-laravel      
    tty: true
    expose: 
      - "9000"
    # "php artisan serve" commmand default port
    ports:
      - 8000:8000
    volumes:
      # for laravel php framework
      - ./flexisip-account-manager/flexiapi:/var/www/html/flexiapi
      # provisioning config
      - ./xmlrpc:/opt/belledonne-communications/share/flexisip-account-manager/xmlrpc
      # Flexisip-account-manager log
      - ./log:/var/opt/belledonne-communications/log
    depends_on:
      - ubuntu-flexisip
    restart: always
    networks: 
      proxy-tier:

networks:
  proxy-tier:
    name: containers-network-ipv6
    external: true

### $ docker volume create phpmyadmin  
volumes:
  phpmyadmin:
    external: true

備 考)

  • Dockerネットワークとphpmyadminボリュームは予め作成すること。

    ブリッジネットワーク

    $ docker network create --gateway 172.xx.0.1 --gateway fdxx:xxxx:xxxx:1::1 --subnet 172.xx.0.0/24 -- subnet fdxx:xxxx:xxxx:1::0/80 --ipv6 containers-network-ipv6
    

    ボリュームの作成

    $ docker volume create phpmyadmin
    
  • redis設定ファイルは上記記述したサイトからダウンロードして下さい。
    bindにはコンテナに割当てられるIPも追加してください。

    bind 127.0.0.1 172.xx.xx.xx ::1 fdxx:xxxx:xxxx:1::xx
    
  • mariadb で定義するデータベース名、ユーザ名、パスワードは .env ファイルで明示して下さい。

  • flexisipcommand: [""]proxyサーバだけを起動する場合には command: ["--server", "proxy"] とします。指定しない場合には、proxy, presence, conference の3サーバが同時に起動します。

  • :bangbang: 重要)flexisipコンテナのネットワークにはホストを指定します。RTP用に常時ある程度多いポート数を確保する必要があるため、ここをブリッジとすると全体のパフォーマンスが大きく低下します。

  • :bangbang: 重要)flexisipコンテナ内でドメイン名とローカルIPアドレスを紐付けます(/etc/hostsへ登録)。これを行わないとSIP接続が迷走します。

    extra_hosts :link:

    extra_hosts:
        - "sip.example.com:192.168.xx.xx"
    
  • TLS認証はCerbotコンテナでflexisipを起動する前に行います。

    $ docker run -it --rm --name certbot -v "$PWD/letsencrypt:/etc/letsencrypt" -p 80:80 certbot/certbot certonly --standalone -d www.example.com
    

    更新する際もCertbotコンテナを利用しますが、ホストマシンのクローンジョブに以下のコマンドを登録する必要があります。

    $ docker stop nginx && docker run -it --rm --name certbot -v "/??/??/.../letsencrypt:/etc/letsencrypt" -p 80:80 certbot/certbot renew && docker start nginx
    

システム起動後のコンテナ内での操作

php-fpm-laravel コンテナ内で以下の作業を行います。

$ docker compose exec php-fpm-laravel sh
# cd flexiapi

flexisip-account-manager に必要な依存パッケージのダウンロード

# composer install --no-dev

.env ファイルを作成しセキュリティキーを適用。認証用SMTPメールサーバ、データベースなどの設定を .env ファイル内で行います。

# cp .env.example .env
# php artisan key:generate

Linphone のアカウント用データベースを作成します。

# php artisan migrate

④ サイトディレクトリの所有者をwww-dataへ変更し、ウェブフロントエンドからユーザ登録します。

# chown -R www-data:www-data ./

⑤ 管理者ユーザの設定。登録したユーザを flexisip-account-manager の管理者とします。

# php artisan accounts:set-admin {account_id}

Note)

# php artisan --help
# php artisan cache:clear

注) フロントエンドは Laravel で作成された flexisip-accont-manager/flexiapi ディレクトリで構成されています( flexisip-accont-manager/xmlrpc ディレクトリは必要はありません)。

設定ファイルは flexisip-accont-manager/flexiapi/config ディレクトリに格納されています。この設定ファイルの変数を上書きするために .env ファイルが利用されます。

エラー対応

conferenceサーバ起動時のエラーログ

2023-03-26 02:42:39:281 liblinphone-error-Could not find a suitable soundcard with capabilities : 2
2023-03-26 02:42:39:281 liblinphone-error-Could not find a suitable soundcard with capabilities : 2
2023-03-26 02:42:39:281 liblinphone-error-Could not find a suitable soundcard with capabilities : 1
2023-03-26 02:42:39:281 liblinphone-error-Could not find a suitable soundcard with capabilities : 2
2023-03-26 02:42:39:328 bctbx-error-bctbx_file_open: Error open No such file or directory
2023-03-26 02:42:39:328 liblinphone-error-Error in the opening zrtp_cache_db_file(/root/.local/share/linphone/zrtp-secrets.db): unable to open database file.

① ハードウェア(サウンドカード)認識エラー

liblinphone-error-Could not find a suitable soundcard with capabilities

Docker Composeファイルにデバイスオプション追加—>検証中—>現状グループチャットのみの対応であることと、参加者の中継サーバとしての機能のためsoundcardは不必要。エラー表示のバグ?

デバックモードで確認
原因:プラグインエラー

2023-04-06 13:15:10:876 mediastreamer-message-Loading ms plugins from [/opt/belledonne-communications/lib/mediastreamer/plugins]
2023-04-06 13:15:10:876 mediastreamer-message-Cannot open directory /opt/belledonne-communications/lib/mediastreamer/plugins: No such file or directory
2023-04-06 13:15:10:876 liblinphone-error-Could not find a suitable soundcard with capabilities : 2
2023-04-06 13:15:10:876 liblinphone-error-Could not find a suitable soundcard with capabilities : 2
2023-04-06 13:15:10:876 liblinphone-error-Could not find a suitable soundcard with capabilities : 1
2023-04-06 13:15:10:876 liblinphone-error-Could not find a suitable soundcard with capabilities : 2

sqlite3データベース作成エラー

bctbx-error-bctbx_file_open: Error open No such file or directory
liblinphone-error-Error in the opening zrtp_cache_db_file(/root/.local/share/linphone/zrtp-secrets.db): unable to open database file.

以下参照し、新規にディレクトリを作成

イメージ作成時に以下のコマンドを追加。

# mkdir -p /root/.local/share/linphone

またはDocker Composeファイルにボリューム追加。

Volumes:
  # for conference server linphone db directory
  - ./linphone:/root/.local/share/linphone

flexisip-account-manager表示エラー

ログイン前の各ページの幅縮小表示で上部メニューバーが隠れてしまう不具合

修正前

以下該当するメインページのクラス指定を navbar-expand-lg から navbar-expand へ変更

flexiapi/resources/views/layouts/main.blade.php

@if (config('app.web_panel'))
    <nav class="navbar navbar-expand">
        <div class="collapse navbar-collapse" >

修正後

プロビジョニング

INIフォーマットまたはXMLフォーマットによる設定ファイルリスト(Android)

デフォルトのプロビジョニングファイルの設定

fleiapi/.env

# Account provisioning
ACCOUNT_PROVISIONING_RC_FILE=/opt/belledonne-communications/share/flexisip-account- 
manager/xmlrpc/default.rc
ACCOUNT_PROVISIONING_OVERWRITE_ALL=true

ex) default.rc

[proxy_default_values]
reg_identity=sip:[email protected]
reg_proxy=<sip:sip.example.com;transport=tls>
reg_sendregister=1
nat_policy_ref=nat_policy_default_values
realm=sip.example.com
conference_factory_uri=sip:[email protected]
audio_video_conference_factory_uri=sip:[email protected]

[nat_policy_default_values]
stun_server=sip.example.com
protocols=stun,ice

以下のURLをLinphoneのアシスタント—>”リモート設定を取得”に入力して設定を書換えることが出来ます。

https://sip.example.com/provisioning

<config xmlns="http://www.linphone.org/xsds/lpconfig.xsd">
<section name="proxy_default_values">
<entry name="reg_identity" overwrite="true">sip:[email protected]</entry>
<entry name="reg_proxy" overwrite="true"><sip:sip.example.com</entry>
<entry name="reg_sendregister" overwrite="true">1</entry>
<entry name="nat_policy_ref" overwrite="true">nat_policy_default_values</entry>
<entry name="realm" overwrite="true">sip.example.com</entry>
<entry name="conference_factory_uri" overwrite="true">sip:[email protected]</entry>
<entry name="audio_video_conference_factory_uri" overwrite="true">sip:[email protected]</entry>
</section>
<section name="nat_policy_default_values">
<entry name="stun_server" overwrite="true">sip.example.com</entry>
<entry name="protocols" overwrite="true">stun,ice</entry>
</section>
<section name="misc">
<entry name="contacts-vcard-list" overwrite="true">https://sip.example.com/contacts/vcard</entry>
</section>
</config>

Flexisip firewall rules - XWiki

First, create a specific chain for Flexisip rules.

# iptables -N flexisip-input-rules

UDP/TCP on port 5060

# iptables -A flexisip-input-rules -p udp -m udp --dport 5060 -j ACCEPT

TLS on port 5061

# iptables -A flexisip-input-rules -p tcp -m tcp --dport 5061 -j ACCEPT

STUN on port 3478

# iptables -A flexisip-input-rules -p udp -m udp --dport 3478 -j ACCEPT

RTP (if media relay is enabled)

# iptables -A flexisip-input-rules -p udp -m udp --dport 10000:20000 -j ACCEPT

And then, add the new table into the INPUT chain, either by adding it at the end:

# iptables -A INPUT -j flexisip-input-rules

or by inserting just before a given rule:

inserting before the fourth rules

# iptables -I INPUT 4 -j flexisip-input-rules

IPv6アドレスによるメディアリレイ

音声ビデオ通話に関わる設定は以下のモジュールが担います。一人のクライアントで音声2ポート、ビデオ2ポートを消費します。2者間ビデオ通話で合計8ポートが必要です。IPv6でこれを割り当てるためには、クライアント側でICEを有効にする必要があります。

[module::MediaRelay]

# Indicate whether the module is activated.
# Default: true
enabled=true

# A request/response enters module if the boolean filter evaluates
# to true. Ex: from.uri.domain contains 'sip.linphone.org', from.uri.domain
# in 'a.org b.org c.org', (to.uri.domain in 'a.org b.org c.org')
# && (user-agent == 'Linphone v2'). You can consult the full filter
# documentation here : https://wiki.linphone.org/xwiki/wiki/public/view/Flexisip/Configuration/Filter%20syntax/
# Default: 
#filter=

# The name of the SDP attribute to set by the first proxy to forbid
# subsequent proxies to provide relay. Use 'disable' to disable.
# Default: nortpproxy
#nortpproxy=nortpproxy

# The minimal value of SDP port range
# Default: 1024
sdp-port-range-min=1024

# The maximal value of SDP port range
# Default: 65535
sdp-port-range-max=65535

# Sends a ACK and BYE to 200Ok for INVITEs not belonging to any
# established call. This is to solve the race condition that happens
# when two callees answer the same call at the same time. According
# to RFC3261, the caller is expected to send an ACK followed by
# a BYE to the loser callee. This is not the case in RFC2543, where
# the proxy was supposed to do this. When set to true, the MediaRelay
# module will implement the RFC2543 behavior. Note that it may sound
# inappropriate to bundle this property with the media relay feature.
# However the MediaRelay module is the only one in Flexisip that
# has the visibility of SIP dialogs, which is necessary to implement
# this feature.
# Default: false
#bye-orphan-dialogs=false

# Maximum concurrent calls processed by the media-relay. Calls arriving
# when the limit is exceed will be rejected. A value of 0 means
# no limit.
# Default: 0
#max-calls=0

# When true, the 'c=' line and port number are set to the relay
# ip/port even if ICE candidates are present in the request, while
# the standard behavior is to leave the c= line and port number
# as they are in the original offer sent by the client. This variation
# allows callees that do not support ICE at all to benefit from
# the media relay service.
# Default: true
force-relay-for-non-ice-targets=false

# Prevent media-relay ports to loop between them, which can cause
# 100% cpu on the media relay thread. You need to set this property
# to false if you are running test calls from clients running on
# the same IP address as the flexisip server
# Default: true
#prevent-loops=true

# In case multiples '183 Early media' responses are received for
# a call, only the first one will have RTP streams forwarded back
# to caller. This feature prevents the caller to receive 'mixed'
# streams, but it breaks scenarios where multiple servers play early
# media announcement in sequence.
# Default: true
#early-media-relay-single=true

# Maximum number of relayed early media streams per call. This is
# useful to limit the cpu usage due to early media relaying on embedded
# systems. A value of 0 stands for unlimited.
# Default: 0
#max-early-media-per-call=0

# Period of time in seconds, after which a relayed call without
# any activity is considered as no longer running. Activity counts
# RTP/RTCP packets exchanged through the relay and SIP messages.
# Default: 3600
#inactivity-period=3600

# Force the media relay to use the public address of Flexisip to
# relay calls. It not enabled, Flexisip will deduce a suitable IP
# address by basing on data from SIP messages, which could fail
# in tricky situations e.g. when Flexisip is behind a TCP proxy.
# Default: false
force-public-ip-for-sdp-masquerading=true

RFC 4566: SDP: Session Description Protocol

Connection Data (“c=”)

  c=<nettype> <addrtype> <connection-address>

The “c=” field contains connection data.

A session description MUST contain either at least one “c=” field in
each media description or a single “c=” field at the session level.
It MAY contain a single session-level “c=” field and additional “c=”
field(s) per media description, in which case the per-media values
override the session-level settings for the respective media.

Presenceサーバ、Conferenceサーバのデバック

docker compose ファイル内のubuntu-flexisipcmdオプションで "--server proxy" を指定してproxyのみを起動してから、コンテナubuntu-flexisip内で下記サーバのいずれかを --debug オプションを指定して起動。各サーバの動作を確認。

注) どちらもポート(5065, 6064)も外部(インターネット)に開放する必要はありません。

Presence server

$ docker compose exec ubuntu-flexisip bash
# flexisip --server presence --debug
......
......
......

Conference server

$ docker compose exec ubuntu-flexisip bash
# flexisip --server conference --debug
......
......
......

Update Flexisip Server on Ubuntu 22.04 with Docker Compose Containers

Vonage SMS

SMS Notifications

Laravel Vonage Notification Channel

LaravelのデフォルトSMS送信ベンダー

アカウント取得(2ユーロまでのトライアルSMS送信サービス付き。トライアルではクレジットカードの登録は必要ありません)

登録するとAPIキーとAPIシークレットが付与されるので、これを .env ファイルに記載します。

.env

# Vonage SMS API
VONAGE_KEY=xxxxxxxxxx
VONAGE_SECRET=xxxxxxxxxxxxxxx
VONAGE_SMS_FROM=1234567890 (トライアルでは任意の番号)

必要なパッケージを composer によりインストール

# composer require laravel/vonage-notification-channel

Notification クラスを拡張したSMS送信メッセージ用新規クラス VonageSMS の作成

# php artisan make:notification VonageSMS

新規ファイル

app/Notifications/VonageSMS.php

<?php

namespace App\Notifications;

use Illuminate\Notifications\Notification;
use Illuminate\Notifications\Messages\VonageMessage;


class VonageSMS extends Notification
{

    /**
     * Create a new notification instance.
     *
     * @return void
     */
    public function __construct(private string $validateMessage)
    {
        //
    }

    /**
     * Get the notification's delivery channels.
     *
     * @param  mixed  $notifiable
     * @return array
     */
    public function via($notifiable)
    {
        return ['vonage'];
    }

    /**
     * Get the Vonage / SMS representation of the notification.
     *
     * @param  mixed  $notifiable
     * @param mixed $alias
     * @return \Illuminate\Notifications\Messages\VonageMessage
     */
    public function toVonage($notifiable)
    {
        return (new VonageMessage())
            ->content($this->validateMessage);
    } 

    /**
     * Get the array representation of the notification.
     *
     * @param  mixed  $notifiable
     * @return array
     */
    public function toArray($notifiable)
    {
        return [
            //
        ];
    }
}

内容追加・書換ファイル

app/Alias.php

namespace App;

use Illuminate\Database\Eloquent\Model;
use Illuminate\Notifications\Notifiable;

class Alias extends Model
{
    use Notifiable;
    protected $table = 'aliases';
    public $timestamps = false;

    public function account()
    {
        return $this->belongsTo('App\Account');
    }

    public function routeNotificationForVonage($notification)
    {
        return $this->alias;
    }
}

app/PhoneChangeCode.php

namespace App;

use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Notifications\Notifiable;

class PhoneChangeCode extends Model
{
    use Notifiable;
    use HasFactory;

    public function account()
    {
        return $this->belongsTo('App\Account');
    }

    public function routeNotificationForVonage($notification)
    {
        return $this->phone;
    }

}

app/Http/Controllers/Account/RegisterController.php

.....
.....
// use App\Libraries\OvhSMS;
use App\Notifications\VonageSMS;
.....
.....
        //$ovhSMS = new OvhSMS;
        //$ovhSMS->send($request->get('phone'), 'Your ' . config('app.name') . ' validation code is ' . $account->confirmation_key);
        //$alias->notify(new VonageSMS('Your ' . config('app.name') . ' validation code is ' . $account->confirmation_key));
        Notification::send($alias, new VonageSMS('Your ' . config('app.name') . ' validation code is ' . $account->confirmation_key));
.....
.....

app/Http/Controllers/Account/AuthenticateController.php

.....
.....
// use App\Libraries\OvhSMS;
use App\Notifications\VonageSMS;
.....
.....
        // $ovhSMS = new OvhSMS;
        // $ovhSMS->send($request->get('phone'), 'Your ' . config('app.name') . ' validation code is ' . $account->confirmation_key);
        // $alias->notify(new VonageSMS('Your ' . config('app.name') . ' validation code is ' . $account->confirmation_key));
        Notification::send($alias, new VonageSMS('Your ' . config('app.name') . ' validation code is ' . $account->confirmation_key));
.....
.....

app/Http/Controllers/Api/AccountController.php

.....
.....
// use App\Libraries\OvhSMS;
use App\Notifications\VonageSMS;
.....
.....
            // $ovhSMS = new OvhSMS;
            //$ovhSMS->send($request->get('phone'), 'Your ' . config('app.name') . ' recovery code is ' . $account->confirmation_key);
            // $alias->notify(new VonageSMS('Your ' . config('app.name') . ' validation code is ' . $account->confirmation_key));
            Notification::send($alias, new VonageSMS('Your ' . config('app.name') . ' validation code is ' . $account->confirmation_key));
.....
.....
        // $ovhSMS = new OvhSMS;
        // $ovhSMS->send($request->get('phone'), 'Your ' . config('app.name') . ' recovery code is ' . $account->confirmation_key);
        // $alias->notify(new VonageSMS('Your ' . config('app.name') . ' validation code is ' . $account->confirmation_key));
        Notification::send($alias, new VonageSMS('Your ' . config('app.name') . ' validation code is ' . $account->confirmation_key));
.....
.....

app/Http/Controllers/Api/AccountPhoneController.php

.....
.....
// use App\Libraries\OvhSMS;
use App\Notifications\VonageSMS;
.....
.....
        // $ovhSMS = new OvhSMS;
        // $ovhSMS->send($request->get('phone'), 'Your ' . config('app.name') . ' validation code is ' . $phoneChangeCode->code);
        //$phoneChangeCode->notify(new VonageSMS('Your ' . config('app.name') . ' validation code is ' . $phoneChangeCode->code));
        Notification::send($phoneChangeCode, new VonageSMS('Your ' . config('app.name') . ' validation code is ' . $phoneChangeCode->code));
.....
.....

Push Notification with the Session Initiation Protocol (SIP)

Flexisip Push Notification Config

Flexisip Push Notification Specification

Flexisip Account Manager フロントエンドデザイン更新

ホーム画面

ユーザ登録画面

メール認証画面

一般ユーザダッシュボード

管理者ダッシュボード

管理者アカウント

登録ユーザ設定