/* BEGIN BLOG-CLOSE-CHAT */ /* END BLOG-CLOSE-CHAT */

Architecture Overview

ICTPBX is composed of four layers that work together:

┌─────────────────────────────────────┐
│  Angular 13 Frontend (ngx-admin)    │  Browser → https://<host>/
├─────────────────────────────────────┤
│  ICTCore REST API (PHP 8.3)         │  https://<host>/api
├─────────────────────────────────────┤
│  ICTCore PBX Engine (DB + Config)   │  PostgreSQL (ictcore pbx)
├─────────────────────────────────────┤
│  FreeSWITCH 1.10.12 (PBX Engine)    │  SIP :5080, WebRTC via /ws/, ESL :8021
└─────────────────────────────────────┘

Component Roles

Component Role Path
Angular Frontend Web UI served by Apache /usr/ictpbxx
ICTCore REST API, auth, billing, users, PBX config /usr/ictcore
FreeSWITCH SIP server, media handling /etc/freeswitch
MariaDB ICTCore data (users, tenants, CDR) Port 3306
PostgreSQL ICTCore PBX config data Port 5432

Call Flow

Inbound Call (PSTN)
  └── Carrier trunk → FreeSWITCH (SIP :5080)
        └── Static XML dialplan generated by ICTCore
              └── Bridges to Extension / IVR / Queue / Voicemail
                    └── Media: RTP audio streams (UDP 16384-32768)

FreeSWITCH doesn’t read the dialplan from the database. When you save something in the portal, ICTCore writes the record, regenerates the static XML and reloads FreeSWITCH, so the change is live straight away.

Data Flow (Admin Actions)

Browser (Angular)
  └── POST /api/extensions  →  ICTCore
        └── Writes the record to PostgreSQL (v_extensions)
              └── ICTCore regenerates the FreeSWITCH XML and reloads it

Tenant SIP Domains

Each tenant gets its own SIP domain. Phones register as extension@tenant-domain, so two tenants can both use extension 1001.

Ports Summary

There’s no SIP on 5060. Desk phones, softphones and trunks all use 5080.

Port Protocol Service
80/443 HTTP/HTTPS Apache (portal, /api, and the /ws/ WebSocket proxy for the browser softphone)
5080 UDP/TCP FreeSWITCH SIP (desk phones, softphones, trunks)
16384-32768 UDP RTP media
5066 / 5067 WS / WSS FreeSWITCH WebRTC (internal only, reached through Apache at /ws/)
8021 TCP FreeSWITCH ESL (localhost only)
3306 TCP MariaDB (localhost only)
5432 TCP PostgreSQL (localhost only)
11211 TCP memcached (localhost only)