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) |