asterisk-dongle-setup
asterisk-dongle-setup copied to clipboard
Playground project aimed at setting up Asterisk server and the GSM stack on Nix.
Asterisk-dongle-setup
This project aims at wiring together many pieces of Linux software required to do the following:
- [x] Receive SMS messages and forward them to a Telegram chat.
- [x] Receive GSM voice calls and forward them to ~~Telegram voice calls~~ (Telegram voice calls are broken due to https://github.com/Infactum/tg2sip/issues/63) or to a SIP client.
- [x] Forward outgoing voice calls ~~from Telegram~~ from SIP client back to GSM
- [x] Handle incoming voice calls with a Lenny prank bot.
- [ ] Voice room with a chat bot.
Specifically, the setup includes Asterisk server with the GSM-modem dongle and tg2sip bridge and many other components glued together with Shell and Python scripts. The high degree of build automation is achieved thanks to the Nix package manager.
Contents
- Contents
-
Setup
- Walkthrough
- Doing USB Modeswitch manually
- Nix-shell
- Usage
- Hardware notes
- Known issues
- Thirdparty issues
-
Administration hints
- Ulaw audio operations:
- Cutting last x seconds from an audio file
- Clearing dongle SMS messages
- Useful Asterisk commands
-
References
- GSM modems
- Asterisk
- Telegram
- Fun
Setup
Walkthrough
-
Install Nix package manager and update Nixpkgs repositories. This whole project is designed as a collection of nix-build expressions.
- Note that Nix could co-exist with your native package manager.
- We use 21.05 Nixpkgs branch commit as a base, but older 20.03 commits should also work.
-
Go and get a GSM modem.
You need to find a supported GSM modem and plug it into the USB port of your computer. We tested
Huawei-E173
only, but in theory any model supported by chan_dongle should work.- A somewhat outdated document about supported hardware is available here. We typically do care about Voice and SMS functions and don't care about USSD.
-
./run.sh
will check for the presence of/dev/ttyUSB0
. If it is not present, the script would attempt to run theusb_modeswitch
procedure. - Currently we automate switching only for Huawei E173 modem. For other models, try to follow the section about manual mode-switching.
-
git clone --recursive <this-repo-url> ; cd ...
-
Create
./secrets.nix
file by copying and editing./secrets_template.nix
.- You need a mobile phone which is bound to some Telegram account.
- Go to https://my.telegram.org/auth and register an API Client instance.
You will be provided with
api_id
andapi_hash
values. - The bot token field is not currently used.
- The Chat id field is a (typically negative) identifier of a chat to send SMS messages
to.
./run.sh
will print available chat identifiers at some point during the startup.
-
Please be informed that the main script
./run.sh
is VERY INSECURE. It configures Asterisk to use binary codec and then runs it as root. -
If you are OK with the above notice, run
./run.sh
.- The script asks Nix to (re-)build everything that is required.
- At first run script will initialize Telegram session for python relay
script.
- As a part of initialization, Telegram server will send a digital code to your Telegram account.
- You are to type this code back into the script.
- At first run the script will also initialize another Telegram session, this
time for
tg2sip
(TODO: find out how to reuse the first session).- It will ask you a phone number with Telegram account.
- Telegram will send a code to your account. You have to read it and type it back into the script.
- At every run, the script runs a number of background services including the Asteris ARI client, SMS spool script, tg2sip application etc.
- Finally, the Asterisk is run in foreground. You should see its
*CLI>
console prompt and be able type commands.
-
???
-
Check the Usage section.
Doing USB Modeswitch manually
run.sh
attempts to run usb_modeswitch procedure automatically for devices
known to author. In case the procedure fails, one could attempt the manual way:
-
nix-build -A usb_modeswitch
. -
lsusb
to find out your modem's vendor:product numbers -
sudo ./result/usr/sbin/usb_modeswitch -v <vendor> -p <product> -X
-
/dec/ttyUSB[01]
devices should appear. You should be able tominicom -D /dev/ttyUSB0
and type some AT command, sayATI
. - Update
run.sh
script by adding new line like below to the corresponding placetry_to_deal_with "<your_device_id>" "<your_device_vendor>" && wait_for_chardev "/dev/ttyUSB0"
- Send us a PR with it.
Nix-shell
Author uses VIM as the main development IDE. The start procedure is as follows:
$ nix-shell
(nix-shell) $ vim . # Edit sources enjoying code navigaiton
(nix-shell) $ ipython # Testing telethon bot, etc
Usage
- To send SMS from the GSM modem, use the Asterisk CLI:
dongle sms dongle0 89097777777 HiHi
. - Send SMS or make a call to your GSMmodem SIM card's number. Asterisk will
redirect the call to your
telegram_master_nicname
Telegram account.- For voice calls, If you pick up the phone from your Telegram account (the green button), the GSM-to-Telegram connection will be established.
- If you cancel the Telegram call by pressing the red button instead, the caller will be handled by the brave Lenny chatbot.
- In either case, Asterisk will record the call and send the recording to the
Telegram
telegram_chat_id
(could be a group) withwav
attachments.
- From a thirdparty telegram account call to the account associated with
secrets.telegram_phone
, then go to the private chat and send a message with a phone number to call to. Asterisk will initiate an outgoing call from your Telegram account to the GSM network. - Here is how to use a SIP softphone application, e.g.
linphone
- Install the softphone application.
- Setup a local SIP account:
<sip:[email protected]:5063>
where192.168.1.2
should be copied intosoftphone_bind_ip
address. The5063
is the SIP port the softphone application should listen to. It is hardcoded intodefault.nix
currently. - Set a remote SIP account to be
<sip:[email protected]>
where192.168.1.1
is yourasterisk_bind_ip
(could be the same assoftphone_bind_ip
). Set 'softphone' as a password (also hardcoded). - Call to
sip:[email protected]
to talk to Lenny bot - Call to
sip:[email protected]
to start the outgoing GSM call.- After the connection is established, open Telegam chat with
telegram_master_nicname
and send the GSM number to call to (a simple oneline message). Asterisk will use GSM dongle to call this number.
- After the connection is established, open Telegam chat with
Hardware notes
We use the following USB dongle:
*CLI> dongle show devices
ID Group State RSSI Mode Submode Provider Name Model Firmware IMEI IMSI Number
dongle0 0 Free 9 0 0 Beeline E173 11.126.85.00.209 *************** *************** Unknown
See also somewhat outdated list of supported devices
Known issues
-
~~tg2sip calls stopped working properly. GSM callers hear themselves but can't hear the telegram side. Softphone calls work fine.~~
-
tg2sip
crashes on incoming calls :( https://github.com/Infactum/tg2sip/issues/63
Thirdparty issues
- ~~https://github.com/wdoekes/asterisk-chan-dongle/issues/109~~
- ~~https://github.com/wdoekes/asterisk-chan-dongle/issues/110~~
- ~~https://github.com/wdoekes/asterisk-chan-dongle/issues/121~~
- ~~https://github.com/Infactum/tg2sip/issues/42~~
- ~~https://community.asterisk.org/t/help-translating-a-simple-peer-config-to-pjsip/86601~~
- https://github.com/wdoekes/asterisk-chan-dongle/issues/120
- Binary codec
chan_opus.so
is required by tg2sip. Consider replacing it with https://github.com/traud/asterisk-opus - On top of above, we run Asterisk is as root, due to
chan_dongle
hardcodings. -
dongleman_daemon
has to reconnect automatically in case of network failures. Currently it issues the errorConnectionError: Cannot send requests while disconnected
. - https://github.com/Infactum/tg2sip/issues/63
Administration hints
Ulaw audio operations:
- Converting 3gpp to ulaw:
./3gpp2ulaw.sh
- Playing ulaw file:
aplay -t raw -f MU_LAW <FILE>
Cutting last x seconds from an audio file
cutlast() {
ffmpeg -i "$2" -ss 0 -to $(echo $(ffprobe -i "$2" -show_entries format=duration -v quiet -of csv="p=0") - "$1" | bc) -c copy "$3"
}
Clearing dongle SMS messages
#!/bin/bash -x
cmds()
{
cat <<EOF
dongle cmd dongle0 AT+CPMS=\"SM\",\"SM\",\"SM\"
dongle cmd dongle0 AT+CMGD=1,4
dongle cmd dongle0 AT+CPMS=\"ME\",\"ME\",\"ME\"
dongle cmd dongle0 AT+CMGD=1,4
exit
EOF
}
cmds | asterisk -r
Useful Asterisk commands
Show channels
core show channels
References
GSM modems
- Asterisk+Dongle setup guide (in Russian) http://linux.mixed-spb.ru/asterisk/dongle_app1.php
- Another Dongle guide in Russian https://jakondo.ru/podklyuchenie-gsm-modema-usb-huawei-e1550-k-asterisk-13-chan_dongle-na-debian-8-jessie/
- Random GSM software:
- GSMCTL (abandoned?) https://www.unix.com/man-page/debian/8/gsmctl/
- MMCLI https://www.freedesktop.org/software/ModemManager/man/1.0.0/mmcli.8.html
Asterisk
- Asterisk Wiki https://wiki.asterisk.org/wiki/display/AST
- About OPUS codec:
- https://community.asterisk.org/t/codec-opus-source-code/72738/6
- Binary opus module 'sends some statistics back to Digium' http://downloads.digium.com/pub/telephony/codec_opus/
- OpenSource equivalent https://github.com/traud/asterisk-opus
- Important dialplan commands:
- Dial https://wiki.asterisk.org/wiki/display/AST/Application_Dial
- ULAW file format
- https://ixnfo.com/en/how-to-convert-audio-files-to-ulaw-alaw-gsm-g722-etc-for-asterisk.html
PJSIP
- Generic information about PJSIP configuration sections
https://wiki.asterisk.org/wiki/display/AST/PJSIP+Configuration+Sections+and+Relationships
- Core config options https://wiki.asterisk.org/wiki/display/AST/Asterisk+12+Configuration_res_pjsip
- An article about PJSIP configuration https://www.redhat.com/sysadmin/asterisk-dialplan
- Setting up TG2SIP (In Russian) https://voxlink.ru/kb/asterisk-configuration/ustanovka-i-nastrojka-sip-shljuza-dlja-telegram/
ARI
-
ARI (probably the preferred way to interact with Asterisk)
- ARI Python interface https://github.com/asterisk/ari-py
- Introduction to ARI and channels https://wiki.asterisk.org/wiki/display/AST/Introduction+to+ARI+and+Channels
-
ARI (without Python) https://wiki.asterisk.org/wiki/display/AST/Getting+Started+with+ARI
-
Local ARI explorer http://ari.asterisk.org/#!/asterisk
-
About
wscat
in NixOS https://msitko.pl/blog/2020/04/22/isolated-ennvironments-with-nix-shell-and-zsh.html -
A sample websocket app in Python https://linuxhint.com/how-to-implement-a-websocket-in-python/
-
Python Websocket docs https://websockets.readthedocs.io/en/3.0/intro.html
-
Habr post about ARI https://habr.com/ru/post/308652/
-
Wiki about making calls via ARI https://wiki.asterisk.org/wiki/display/AST/ARI+and+Bridges%3A+Basic+Mixing+Bridges
Telegram
- Client API access page https://my.telegram.org/auth
- Telethon API client documentation https://docs.telethon.dev/en/latest/
- TG2SIP https://github.com/Infactum/tg2sip
- Setting up TG2SIP (In Russian) https://voxlink.ru/kb/asterisk-configuration/ustanovka-i-nastrojka-sip-shljuza-dlja-telegram/
- AsyncIO inotify interface https://github.com/giannitedesco/minotaur
- AsyncIO inotify https://asyncinotify.readthedocs.io/en/latest/
- AsyncIO wait for multiple events http://www.hydrogen18.com/blog/python-await-multiple.html
- Some tutorial https://tutorialedge.net/python/concurrency/asyncio-event-loops-tutorial/
- Waiting for messages https://stackoverflow.com/questions/66718923/python-telethon-wait-for-reply
Hardware
- https://wiki.radxa.com/ROCKPI_S_PoE_HAT
- https://www.raspberrypi.com/news/announcing-the-raspberry-pi-poe-hat/
Fun
- Lenny https://crosstalksolutions.com/howto-pwn-telemarketers-with-lenny/