Voice Conference dengan Ofon SmartPBX

Salah satu layanan conference call yang sering kami gunakan adalah Ofon SmartPBX Conference Call, selain menggunakan Google Meet, Zoom, Microsft Teams, atau Aplikabiz G-Net MeetNow. SmartPBX sendiri merupakan aplikasi hosted PBX buatan 2600hz dan merupakan bagian dari platform yang lebih besar lagi yang disebut Kazoo.

Ofon SmartPBX Conference Call cukup sering kami gunakan di kantor karena sifatnya yang sederhana, straightforward, dan cocok untuk situasi yang “mission critical”, di mana kadang jangkauan jaringan data selular tidak memadai, tapi masih bisa tetap bergabung melalui jalur PSTN yang bisa diakses luas bahkan sampai pelosok daerah. Untuk ekstensi yang masih dalam jangkauan jaringan data yang bagus, dapat bergabung melalui panggilan VoIP.

Kok ekstensi? Kayak PBX saja….

Lha kan memang layanan hosted PBX. Di gawai Android, saya menggunakan LinPhone dan GSWave untuk bisa menjadi ekstensi PBX tersebut, sementara teman-teman lain yang menggunakan iOS, lebih suka WeWei, walaupun ada LinPhone dan GSWave untuk iOS juga. Tapi jika panggilan data/VoIP tidak bisa dilakukan, panggilan dapat diteruskan melalui jaringan PSTN.

Semudah apa?

Bergabung ke SmartPBX Conference Call

Secara default, Ofon SmartPBX akan memberikan 3 nomer/DID. Satu DID sebagai nomer utama yang menjadi nomer identitas ketika melakukan panggilan PSTN. DID kedua untuk voice conference call (tampak dalam contoh di bawah nomer DID untuk Conference call: +622139710091), dan DID terakhir untuk menerima fax yang kemudian akan diforward ke email pengguna.

Setiap user Ofon SmartPBX dapat memiliki ruang konferensi sendiri. Misal berikut ini saya akan setting conference room milik saya. Pilih menu Users di panel sebelah kiri, lalu di halaman list user saya, klik kolom User Features:

Aktifkan Conference Bridge dengan klik button tersebut, lalu switch dari Disabled ke Enabled lalu isikan Personal Conference Room number. Bisa diisikan berapa saja, tapi saya lebih suka menyamakan dengan nomer ekstensi saya, misal, 6681.

Lalu klik Save Changes.

Ketika fitur Conference Bridge sudah aktif, akan muncul icon baru di tabel user saya berupa buble dialog warna hitam:

Setiap kali saya mengaktifkan fitur di user saya, akan muncul icon baru di situ. Misal, jika saya aktifkan CallForward dan Hotdesking, akan muncul icon baru seperti berikut:

oh ya, device saya di screenshoot terakhir sudah berwarna hijau karena barusan saya mengaktifkan softphone. Jika tidak aktif, icon device akan berwarna merah seperti gambar sebelumnya.

Untuk mencoba panggilan conference call dari PSTN, cukup dengan mendial nomer +622139710091 dengan memasukkan nomer room 6681 dan diakhiri tanda #.

Untuk pengguna yang hendak bergabung ke conference call dari ekstensi PBX tersebut, ada dua cara untuk bergabung. Yang pertama adalah dengan melakukan panggilan ke nomer conference call di atas (+622139710091), dan memasukkan room number seperti laiknya pengguna yang bergabung dari PSTN. Panggilan tersebut tidak akan dikenakan biaya, karena sama-sama menggunakan layanan dari Ofon dan dari kode area yang sama.

Cara kedua, ada satu ekstensi 9999 yang pada saat mendaftar sudah dibuatkan oleh Customer Service Ofon sesuai permintaan sendiri. Nomer tersebut ketika dihubungi dari ekstensi akan masuk ke Conference Call service, yang kemudian akan menayakan room number juga, seperti ketika melakukan panggilan dari PSTN. Di layanan conference call ini kita tidak bisa melakukan panggilan video atau screensharing, tapi cukup handal ketika peserta tidak sedang di area yang terjangkau internet. Seperti yang saya sampaikan di atas voice conference call ini cukup straightforward ketika di tengah situasi yang kritis atau darurat, seperti akhir-akhir ini. Koordinasi dapat berjalan dengan singkat, cepat dan jelas ketika berkoordinasi.

Bukannya jadi besar biaya ya kalau harus Dial In ke nomer tersebut?

Saya kurang tau apakah akhir-akhir ini masih banyak yang menggunakan pulsa regular untuk telepon via GSM/PSTN. Dengan tingginya minat terhada layanan data/ internet melalui operator selular, membuat dua layanan dasarnya; SMS & panggilan telepon, menjadi kurang diminati, sehingga mereka berlomba-lomba mengadakan paket SMS dan telpon ke semua operator dengan harga yang relatif cukup murah. Saya menggunakan operator XL Prioritas, dan selalu mendapat paket SMS dan panggilan ke semua operator dengan talk time yang cukup banyak:

Saya yakin sudah sangat umum bahwa perusahaan membekali karyawannya dengan kemudahan melakukan panggilan dari telepon genggam, dalam bentuk tunjangan bulanan ataupun berlangganan CUG.

Bagaimana Caranya Dial-Out

Untuk saat ini fitur dial-out conference call di Ofon SmartPBX belum ada, tapi dapat dilakukan dengan cara lain yaitu menggunakan conference phone sebagai conference bridge. Sebenarnya bisa saja sih menggunakan softphone atau ip phone biasa. Tapi perangkat tersebut harus cukup kuat untuk menjadi voice bridge karena akan menjadi pusat pertemuan media dari dan ke semua peserta. Untuk 3-4 peserta saya yakin masih lancar, tapi lebih dari itu biasanya akan berpengaruh pada kualitas suara karena resource yang digunakan juga naik seiring bertambahnya peserta. Oleh karena itu diperlukan perangkat khusus seperti conference phone. Ada macam-macam brand yang ada di Indonesia. Yang paling mahal dan tentunya paling bening biasanya keluaran Polycom dengan seri conference phones nya . Brand lain yang harganya cukup terjangkau adalah YeaLink Conference Phones dan Grandstream Audio Conferencing. Di kantor saya menggunakan Yealink CP920 ketika melakukan dial-out conference call. Perangkat tersebut teregistrasi sebagai device/ekstensi si SmartPBX. Jadi selain dial-out, pengguna lain juga dapat melakukan dial-in dari VoIP dengan menghubungi nomer ekstensinya.

Serius? Ndak ada cara lain dial-out supaya MUC nya ada di SmartPBX?

Jika Anda Programmer Web…

Ada sedikit rahasia :

https://api.ofon.io:8443/v2/

URL di atas masih dalam tahap trial, yang kelak akan diintegrasikan langsung ke SmartPBX. Tapi boleh lah dibuat coba-coba.

Contoh berikut akan menggunakan curl .

Lakukan autentikasi dengan login admin SmartPBX yang telah didapat dari OFON, buatlah md5sum, misal dari shell linux, dengan format “username:password” :

echo -n "admin@localhost.localdomain:r4h4514" | md5sum
65e26add3748f33039f119f3fd8a5735  -

berbekal md5sum -> 65e26add3748f33039f119f3fd8a5735 dan dan akun name, misal: YourCompanyPBX, dapatkan auth token:

curl -v -X PUT -H "content-type:application/json" \
-d '{"data":{"credentials":"65e26add3748f33039f119f3fd8a5735",\
"account_name":"yourcompanypbx"}}' \
https://api.ofon.io:8443/v2/user_auth | jq

Perintah di atas menghasilkan output panjang. Langsung ke bawah menuju bagian auth_token.

catatan: agar output JSON rapi, saya suka menggunakan tool jq. Jika tidak ada, bisa digantikan dengan -> | python -mjson.tool

kemudian perhatikan account id yang bisa dilihat di halaman SmartPBX bagian kanan bawah:

Berbekal auth_token dan account_id dapatkan ID conference call:

curl -X GET -H "X-Auth-Token: $AUTH_TOKEN"  \
https://api.ofon.io:8443/v2/accounts/$ACCOUNT_ID/conferences | jq

Output:

{
  "page_size": 1,
  "data": [
    {
      "owner_id": "ec356f13f300109ffb17a31edf94001a",
      "name": "Gabriel Wishnu SmartPBX Conference",
      "moderator": {
        "pins": [],
        "numbers": [],
        "join_muted": false,
        "join_deaf": false
      },
      "member": {
        "pins": [],
        "numbers": [],
        "join_muted": false,
        "join_deaf": false
      },
      "id": "7810f4b14b041e1f951c31ccfb124b1d",
      "flags": [],
      "conference_numbers": [
        "6681"
      ],

dari output JSON di atas kita mendapatkan identitas conference:

7810f4b14b041e1f951c31ccfb124b1d

dari conference room number 6681 yang sudah diset sebelumnya. Misal nomer telpon yang hendak didial-out adalah 081234567890, dan callerid yang akan kita gunakan untuk dial-out adalah nomer DID conference room di atas (+622139710091) maka cara panggilnya:

curl -v -X PUT -d '{"action": "dial", \ 
"data": {"endpoints":["081234567890"],"caller_id_number":"+622139710091"}}' \
-H "X-Auth-Token: $AUTH_TOKEN" \
https://api.ofon.io:8443/v2/accounts/$ACCOUNT_ID/conferences/7810f4b14b041e1f951c31ccfb124b1d  | jq

Atau jika ada beberapa nomer sekaligus (misal 081234567890, 081818181818, 08989898989, 02129393939):

curl -v -X PUT -d '{"action": "dial", \ 
"data": {"endpoints":["081234567890","081818181818", "08989898989", "02129393939"], \
"caller_id_number":"+622139710091"}}' \
-H "X-Auth-Token: $AUTH_TOKEN" \
https://api.ofon.io:8443/v2/accounts/$ACCOUNT_ID/conferences/7810f4b14b041e1f951c31ccfb124b1d  | jq

Perintah tersebut akan memanggil sekian nomer sekaligus untuk bergabung dalam voice conference.

catan:

sehubungan dengan adanya ratelimiter call di SBC Ofon untuk mencegah fraud, panggilan serentak ke nomer seperti diatas akan dibatasi 3 nomer dalam sekali waktu. Jadi jika peserta lebih dari 3, perlu dipecah per panggilan hanya dapat melakukan 3 panggilan keluar dari callerid yang sama. 

Panggilan yang terkena rate limit akan memberikan pesan:

     {
        "message": "failed to start call: OUTGOING_CALL_BARRED",
        "hangup_cause": "OUTGOING_CALL_BARRED",
        "status": "error",
        "endpoint_id": "081234567890"
      }

Sampai di sini dulu, kapan-kapan saya akan bahas lebih lanjut mengenai API ini.

Selamat mencoba!

Links:

Replikasi usrloc Kamailio Dengan dmq_usrloc

Salah satu redundansi SIP yang digunakan di kantor adalah dengan replikasi usrloc antar dua SIP registrar di dua datacenter yang berbeda. Lalu hostname akan diresolve ke kedua server tersebut, sehingga jika pada saat ada panggilan masuk dari Offnet ke pelanggan, dan kebetulan salah satu server SIP registrar down beberapa detik sebelum panggilan diteruskan, di SIP server lain masih memiliki AoR/usrloc user yang dituju dan panggilan tetap bisa diteruskan. (Untuk redundansi outbound call tidak akan di bahas di tulisan ini).

Untuk mereplikasi AoR/usrloc saya menggunakan modul dmq

Berikut cara install dan konfigurasi dmq untuk dua SIP server yang saya beri nama sip01.domain.tld (10.0.0.1) dan sip02.domain.tld (10.0.0.2). Skenario berikut ini juga bisa dijalankan untuk dua datacenter yang berbeda, sehingga dmq melakukan sinkronisasi via internet.

sip01.domain.tld (10.0.0.1)

Dengan asumsi server yang dijalankan adalah Centos versi 7 dan ini adalah SIP server untuk Kazoo platform yang sudah disetup dan berjalan, install dmq:

yum install -y kamailio-dmq_userloc.x86_64

Karena ini adalah salah satu komponen dari Kazoo platform, edit file /etc/kazoo/kamailio/default.cfg, dan tambahkan baris berikut:

...
...
...
####### DMQ & dmq_userloc #######
loadmodule "dmq.so"
loadmodule "dmq_usrloc.so"
modparam("dmq", "server_address", "sip:10.0.0.1:5060")
modparam("dmq", "notification_address", "sip:10.0.0.2:5060")
modparam("dmq", "num_workers", 8)
modparam("dmq", "ping_interval", 90)
modparam("dmq_usrloc", "enable", 1)
modparam("dmq_usrloc", "sync", 0)
...
...
...

Perhatikan baris yang ada server_address dan notification_address. Untuk server pertama, server_address diisikan ip address dari server sip01.domain.tld, dan notification_address diisikan sip address sip02.domain.tld.

Lalu masih di dalam file yang sama, tapi di dalam block route, tambahkan baris:

...
...
...
# routing dmq 
    if(is_method("KDMQ"))
        {
                dmq_handle_message();
        }
...
...
...

Save dan restart service kamailio.

sip02.domain.tld (10.0.0.1)

Pada dasarnya kita melakukan hal yang sama dengan sip server pertama. Install module dmq di server sip server kedua.

yum install -y kamailio-dmq_userloc.x86_64

Lalu konfig file /etc/kazoo/kamailio/default.cfg dan tambahkan baris berikut:

...
...
...
####### DMQ & dmq_userloc #######
loadmodule "dmq.so"
loadmodule "dmq_usrloc.so"
modparam("dmq", "server_address", "sip:10.0.0.2:5060")
modparam("dmq", "notification_address", "sip:10.0.0.1:5060")
modparam("dmq", "num_workers", 8)
modparam("dmq", "ping_interval", 90)
modparam("dmq_usrloc", "enable", 1)
modparam("dmq_usrloc", "sync", 0)
...
...
...

Perhatikan di baris yang ada server_address dan notification_address. IP address diset berbalik dengan konfigurasi terhadap sip server pertama. Selanjutnya untuk blok route sama:

...
...
...
# routing dmq 
    if(is_method("KDMQ"))
        {
                dmq_handle_message();
        }
...
...
...

Save file konfigurasi dan reload Kamailio.

Test Hasil

Untuk melihat apakah jumlah pengguna yang teregistrasi di kedua sip server sudah sama (harusnya sama, jika ada perbedaan mungkin sedang dalam tahap sinkronisasi karena kadang-kadang pengguna terputus dan tersambung di sip server) jalankan perintah berikut:

kamctl ul show --brief | jq

Perhatikan output di bagian berikut untuk kedua server:

 "Stats": {
            "Records": 670,
            "Max-Slots": 4
          }

Untuk entri Records baik di server pertama maupun server kedua, harusnya berjumlah sama yaitu 670. Jika ada perbedaan paling hanya 5 – 10 angka saja. Dan jika ingin benar-benar memastikan, ambil contoh satu record dari hasil di atas (harusnya hasil di atas berupa list panjang, tapi dalam contoh di sini hanya diambil potongan output itu saja), misal untuk record:

{
   "AoR": "user_8udxaw@11778f.sip.domain.tld"
}

Kita bisa search AoR tersebut di kedua server dengan cara:

kamctl ul show user_8udxaw@11778f.sip.domain.tld | jq

Jika tanpa dmq user tersebut hanya ada di salah satu server. Jika dengan dmq yang terinstall dengan baik, maka di kedua server mencatat AoR yang sama sekaligus.

Transcoding G711 ke Opus di Kazoo

Tempo hari kantor kedatangan tamu dari Aarenet. Mereka memperesentasikan layanan UC yang bisa mereka sediakan untuk level provider. Platform yang mereka gunakan buatan sendiri yang didevelop dari tahun 2004 – 2009, tanpa jualan dulu. Hasilnya juga ndak main-main. Menarik lah pokoknya. Kelak kalo punya ITSP sendiri mungkin kepikiran pakai produk mereka, terutama kalo sudah males ngoprek. Hehehe.

Ada beberapa hal yang bisa dipelajari dari presentasi mereka, yang juga bisa diterapkan di network yang lagi saya bangun. Dari sekian banyak hal, saya jadi ngeh kalau ingin layanan UC bisa diakses dari jaringan 3G/4G (untuk saat ini), yang dipake adalah codec Opus. Hal lain yang saya pelajari dari mereka mungkin nanti saja diceritakan dalam postingan berikutnya (kalo sempet dan inget). Sekarang ini sudah banyak aplikasi softphone yang sudah menggunakan Opus. Salah satu yang saya pakai di PC/laptop yang cukup ringan adalah Microsip. Sedangkan di smartphone, saya memanfaatkan Linphone. Jadi di media server Kazoo yang menghadap ke user akan selalu dipaksa menggunakan Opus (kecuali jika user hendak menggunakan fax di mana harus menggunakan codec G711 ulaw/alaw), sedangkan di sisi menghadap OLO (Other Local Operator) akan tetap menggunakan G711 untuk menjamin kualitas. Karena media server melakukan transcoding, maka di FreeSWITCH ditambahkan konfigurasi seperti berikut:

  • Di sip profile (kebetulan dalam topologi Kazoo hanya punya satu profile), tambahkan baris:
    • disable-transcoding = false (tujuannya untuk mengaktifkan transcoding).
    • inbound-late-negotiation = true (tujuannya supaya media server tidak memilih codec hingga RTP lewat).
    • inherit_codec = true (tujuannya adalah agar media server mencoba codec yang pertama digunakan oleh call leg satunya. Hal ini berhubungan dengan penghematan resource server).



  • di dalam freeswitch.xml (di FS Kazoo tidak ada vars.xml) tambahkan baris:

  • Dan terakhir, paksa Device yang teregister ke Kazoo untuk selalu menggunakan Opus dengan cara hanya mengaktifkan codec Opus di setting Device dan di masing-masing software SIP client:

Ketika kita coba melakukan panggilan, maka SDP akan tampak seperti:

INVITE

v=0
o=FreeSWITCH 1522990346 1522990347 IN IP4 116.68.171.76
s=FreeSWITCH
c=IN IP4 1.2.3.4
t=0 0
m=audio 25278 RTP/AVP 102 101 13
a=rtpmap:102 opus/48000/22
a=fmtp:102 useinbandfec=1; maxaveragebitrate=30000; maxplaybackrate=48000; ptime=20; minptime=10; maxptime=40
a=rtpmap:101 telephone-event/48000
a=fmtp:101 0-16
a=rtpmap:13 CN/48000
a=ptime:20

Selamat mencoba!

Ref:

[Tips] Kazoo Media Server – Tidak Bisa Memainkan Voice Recording

Jika kita memiliki platform Kazoo dengan media server terpisah, ada kemungkinan tidak bisa mendengarkan voice recording, misal, jika kita salah mendial nomer seharusnya mendapatkan pesan suara:

“The call can not be completed as dialed. Please check your number and dial again.”

alih-alih akan mendapatkan error message di console FreeSWITCH seperti berikut:

[ERR] mod_http_cache.c:1170 Received HTTP error 0 trying to fetch http://127.0.0.1:15984/system_media/en-us%2Ffault-can_not_be_completed_as_dialed/fault-can_not_be_completed_as_dialed.wav?rev=6-585c8f2e3b6b3f4063efb1c18cce5309

Sebelum melanjutkan ke setting HAPROXY, pastikan semua rekaman suara sudah berada di dalam direktori /opt/kazoo/sounds (dalam contoh ini, karena menggunakan bahasa inggris, lokasi direktori lengkapnya /opt/kazoo/sounds/en/us). Jika belum ada, copy manual langsung dari server ecallmgr yang sudah berjalan.

Selanjutnya, ubah config HAPROXY yang mengarah ke server database CouchDB (biasanya karena server terpisah dengan media server) dengan bind server ke 0.0.0.0 misal :

....
listen bigcouch-data
bind 0.0.0.0:15984
balance roundrobin
server db_1.couch.db 127.0.0.1:5984 check
server db_2.couch.db 127.0.0.1:5984 check
server db_3.couch.db 127.0.0.1:5984 check backup
server db_4.couch.db 127.0.0.1:5984 check backup

listen bigcouch-mgr
bind 0.0.0.0:15986
balance roundrobin
server db_1.couch.db 127.0.0.1:5986 check
server db_2.couch.db 127.0.0.1:5986 check
server db_3.couch.db 127.0.0.1:5986 check backup
server db_4.couch.db 127.0.0.1:5986 check backup
...

Pastikan juga firewall hanya menerima koneksi ke service-service tersebut dari ip address cluster kita sendiri untuk keamanan.

Lalu di server FreeSWITCH juga diinstall HAPROXY dengan config sebagai berikut (misal HAPROXY database terpasang di ip address 1.2.3.4 dengan port 15984 dan 15986):

....
listen bigcouch-data
bind 127.0.0.1:15984
balance roundrobin
server db_1.couch.db 1.2.3.4:15984 check
server db_2.couch.db 1.2.3.4:15984 check
server db_3.couch.db 1.2.3.4:15984 check backup
server db_4.couch.db 1.2.3.4:15984 check backup

listen bigcouch-mgr
bind 0.0.0.0:15986
balance roundrobin
server db_1.couch.db 1.2.3.4:15986 check
server db_2.couch.db 1.2.3.4:15986 check
server db_3.couch.db 1.2.3.4:15986 check backup
server db_4.couch.db 1.2.3.4:15986 check backup
...

Reload semua HAPROXY di ke-2 server/cluster tersebut, lalu test kembali.