Skip to content

Commit

Permalink
Merge pull request #18 from rtckit/v0.6.0
Browse files Browse the repository at this point in the history
v0.6.0
  • Loading branch information
cdosoftei authored Feb 2, 2023
2 parents 9bf0d04 + 45f1279 commit c5e2b97
Show file tree
Hide file tree
Showing 309 changed files with 8,025 additions and 12,486 deletions.
5 changes: 4 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,8 @@

A reimplementation of the open source [Plivo framework](https://github.com/plivo/plivoframework) on top of [ReactPHP](https://reactphp.org) and [FreeSWITCH](https://github.com/signalwire/freeswitch). If you are not familiar with the legacy platform, please inspect its [repository](https://github.com/plivo/plivoframework) as well as the archived web resources [here](https://web.archive.org/web/20171127130133/http://docs.plivo.org/), [here](https://web.archive.org/web/20171207074507/http://docs.plivo.org/get-started/) and [here](https://web.archive.org/web/20190108064818/https://www.plivo.com/open-source/).

As of [v0.6](https://github.com/rtckit/eqivo/releases/tag/v0.6.0), **Eqivo** builds on top of the _FiCore_ [FreeSWITCH integration library](https://github.com/rtckit/ficore).

For integrating **Eqivo** in your projects, please refer to **[https://eqivo.org](https://eqivo.org)** as well as to **[rtckit/eqivo-sandbox](https://github.com/rtckit/eqivo-sandbox)**. If you want to contribute or to extend this project, keep reading.

## Requirements
Expand All @@ -38,7 +40,7 @@ composer psalm

### Tests

Unit tests are presently lacking, yet they're [stubbed out](tests) for future development. The project itself has been scaffolded against an acceptance test suite hosted in [its own repository](https://github.com/rtckit/eqivo-acceptance-test-suite).
Unit tests are presently lacking. The project itself has been scaffolded against an acceptance test suite hosted in [its own repository](https://github.com/rtckit/eqivo-acceptance-test-suite).

## License

Expand All @@ -51,6 +53,7 @@ MIT, see [LICENSE file](LICENSE).
* [Plivo framework](https://github.com/plivo/plivoframework) - Original framework; Eqivo and its authors are not affiliated with the legacy open source project nor with with the company behind it
* [ReactPHP](https://reactphp.org) - Provides the asynchronous I/O fabric on top of which Eqivo interacts with FreeSWITCH and the consuming applications
* [FreeSWITCH](https://github.com/signalwire/freeswitch) - Handles the real time communications aspects, particularly signalling and media processing
* [FiCore](https://github.com/rtckit/ficore) - FreeSWITCH Integration Core responsible for the bulk of dialplan/call flow logic exposed by Eqivo
* [Slate](https://github.com/slatedocs/slate) is responsible for rendering the [project's website](https://eqivo.org)
* [widdershins](https://github.com/Mermade/widdershins) translates the OpenApi spec to Markdown

Expand Down
207 changes: 133 additions & 74 deletions bin/eqivo
Original file line number Diff line number Diff line change
Expand Up @@ -3,26 +3,29 @@

declare(strict_types=1);

use RTCKit\Eqivo\{
App,
Config,
HttpClient,
Inbound,
Outbound,
Rest
use RTCKit\Eqivo as Eqivo;

use RTCKit\FiCore\{
Plan,
Command,
Signal,
};
use RTCKit\FiCore\Switch\ESL;

error_reporting(-1);
set_time_limit(0);

if (is_file(__DIR__ . '/../vendor/autoload.php')) {
require __DIR__ . '/../vendor/autoload.php';
$autoloadPath = __DIR__ . '/../vendor/autoload.php';
} else if (is_file('./vendor/autoload.php')) {
require './vendor/autoload.php';
$autoloadPath = './vendor/autoload.php';
} else {
die('Cannot locate vendor/autoload.php file!' . PHP_EOL);
}

/** @psalm-suppress UnresolvableInclude */
require_once($autoloadPath);

if (!defined('PHP_VERSION_ID') || (PHP_VERSION_ID < 80100)) {
die('Eqivo requires PHP 8.1+' . PHP_EOL);
}
Expand All @@ -33,84 +36,140 @@ foreach (['ctype', 'date', 'filter', 'json', 'libxml', 'pcre', 'simplexml'] as $
}
}

$eqivo = new App;
libxml_use_internal_errors(true);

$eqivo->setConfig(new Config\Set);
$eqivo = new Eqivo\App;

$eqivo->addConfigResolver(new Config\CliArguments);
$eqivo->addConfigResolver(new Config\LegacyConfigFile);
$eqivo->addConfigResolver(new Config\ConfigFile);
$eqivo->addConfigResolver(new Config\EnvironmentVars);
$eqivo->resolveConfig();
$eqivo
->setConfig(new Eqivo\Config\Set)
->addConfigResolver(new Eqivo\Config\CliArguments)
->addConfigResolver(new Eqivo\Config\LegacyConfigFile)
->addConfigResolver(new Eqivo\Config\ConfigFile)
->addConfigResolver(new Eqivo\Config\EnvironmentVars)
->resolveConfig();

$eqivo->setHttpClient(new HttpClient);
$eqivo->setHttpClient(new Eqivo\HttpClient);

$eqivo->setInboundServer(
(new Inbound\Server)
$eqivo
->setEventConsumer(new ESL\Event\Consumer)
->setPlanConsumer(
(new Eqivo\Plan\Consumer)
->setApp($eqivo)
->setElementHandler(Plan\CaptureSpeech\Element::class, new Plan\CaptureSpeech\Handler)
->setElementHandler(Plan\CaptureTones\Element::class, new Plan\CaptureTones\Handler)
->setElementHandler(Plan\Conference\Element::class, new Plan\Conference\Handler)
->setElementHandler(Plan\Hangup\Element::class, new Plan\Hangup\Handler)
->setElementHandler(Plan\Playback\Element::class, new Plan\Playback\Handler)
->setElementHandler(Plan\Record\Element::class, new Plan\Record\Handler)
->setElementHandler(Plan\Redirect\Element::class, new Plan\Redirect\Handler)
->setElementHandler(Plan\Silence\Element::class, new Plan\Silence\Handler)
->setElementHandler(Plan\Speak\Element::class, new Plan\Speak\Handler)
->setElementHandler(Eqivo\Plan\Dial\Element::class, new Eqivo\Plan\Dial\Handler)
->setElementHandler(Eqivo\Plan\PreAnswer\Element::class, new Eqivo\Plan\PreAnswer\Handler)
->setElementHandler(Eqivo\Plan\SipTransfer\Element::class, new Eqivo\Plan\SipTransfer\Handler)
)
->setPlanProducer(
(new Eqivo\Plan\Producer)
->setApp($eqivo)
->setRestXmlElementParser(new Eqivo\Plan\Parser\Conference)
->setRestXmlElementParser(new Eqivo\Plan\Parser\Dial)
->setRestXmlElementParser(new Eqivo\Plan\Parser\GetDigits)
->setRestXmlElementParser(new Eqivo\Plan\Parser\GetSpeech)
->setRestXmlElementParser(new Eqivo\Plan\Parser\Hangup)
->setRestXmlElementParser(new Eqivo\Plan\Parser\Play)
->setRestXmlElementParser(new Eqivo\Plan\Parser\PreAnswer)
->setRestXmlElementParser(new Eqivo\Plan\Parser\Record)
->setRestXmlElementParser(new Eqivo\Plan\Parser\Redirect)
->setRestXmlElementParser(new Eqivo\Plan\Parser\SipTransfer)
->setRestXmlElementParser(new Eqivo\Plan\Parser\Speak)
->setRestXmlElementParser(new Eqivo\Plan\Parser\Wait)
);

$eqivo->setSignalProducer(
(new Eqivo\Signal\Producer)
->setApp($eqivo)
->setController(new Inbound\Controller)
->setElementHandler(new Inbound\Handler\BackgroundJob)
->setElementHandler(new Inbound\Handler\CallUpdate)
->setElementHandler(new Inbound\Handler\ChannelHangupComplete)
->setElementHandler(new Inbound\Handler\ChannelProgress)
->setElementHandler(new Inbound\Handler\ChannelProgressMedia)
->setElementHandler(new Inbound\Handler\ChannelState)
->setElementHandler(new Inbound\Handler\Custom)
->setElementHandler(new Inbound\Handler\RecordStop)
->setElementHandler(new Inbound\Handler\SessionHeartbeat)
->setSignalHandler(Signal\Channel\DTMF::class, new Eqivo\Signal\Handler\Channel\DTMF)
->setSignalHandler(Signal\Channel\Hangup::class, new Eqivo\Signal\Handler\Channel\Hangup)
->setSignalHandler(Signal\Channel\Heartbeat::class, new Eqivo\Signal\Handler\Channel\Heartbeat)
->setSignalHandler(Signal\Channel\MachineDetection::class, new Eqivo\Signal\Handler\Channel\MachineDetection)
->setSignalHandler(Signal\Channel\Progress::class, new Eqivo\Signal\Handler\Channel\Progress)
->setSignalHandler(Signal\Channel\Recording::class, new Eqivo\Signal\Handler\Channel\Recording)
->setSignalHandler(Signal\Channel\Speech::class, new Eqivo\Signal\Handler\Channel\Speech)
->setSignalHandler(Signal\Conference\DTMF::class, new Eqivo\Signal\Handler\Conference\DTMF)
->setSignalHandler(Signal\Conference\Enter::class, new Eqivo\Signal\Handler\Conference\Enter)
->setSignalHandler(Signal\Conference\Floor::class, new Eqivo\Signal\Handler\Conference\Floor)
->setSignalHandler(Signal\Conference\Leave::class, new Eqivo\Signal\Handler\Conference\Leave)
->setSignalHandler(Signal\Conference\Recording::class, new Eqivo\Signal\Handler\Conference\Recording)
->setSignalHandler(Eqivo\Signal\Channel\Bridge::class, new Eqivo\Signal\Handler\Channel\Bridge)
->setSignalHandler(Eqivo\Signal\Channel\DTMF::class, new Eqivo\Signal\Handler\Channel\DTMF)
);

$eqivo->setOutboundServer(
(new Outbound\Server)
$eqivo->setEslClient(
(new ESL\Client)
->setApp($eqivo)
->setController(new Outbound\Controller)
->setElementHandler(new Outbound\Conference\Handler)
->setElementHandler(new Outbound\Dial\Handler)
->setElementHandler(new Outbound\GetDigits\Handler)
->setElementHandler(new Outbound\GetSpeech\Handler)
->setElementHandler(new Outbound\Hangup\Handler)
->setElementHandler(new Outbound\Play\Handler)
->setElementHandler(new Outbound\PreAnswer\Handler)
->setElementHandler(new Outbound\Record\Handler)
->setElementHandler(new Outbound\Redirect\Handler)
->setElementHandler(new Outbound\SipTransfer\Handler)
->setElementHandler(new Outbound\Speak\Handler)
->setElementHandler(new Outbound\Wait\Handler)
->setEventHandler(new ESL\Event\BackgroundJob)
->setEventHandler(new ESL\Event\ChannelHangupComplete)
->setEventHandler(new ESL\Event\ChannelProgress)
->setEventHandler(new ESL\Event\ChannelProgressMedia)
->setEventHandler(new ESL\Event\ChannelState)
->setEventHandler(new ESL\Event\Custom)
->setEventHandler(new ESL\Event\RecordStop)
->setEventHandler(new ESL\Event\SessionHeartbeat)
->setEventHandler(new Eqivo\Switch\ESL\Event\CallUpdate)
);

$eqivo->setCommandConsumer(
(new Command\Consumer)
->setApp($eqivo)
->setMethodHandler(Command\Channel\DTMF\Request::class, new Command\Channel\DTMF\Handler)
->setMethodHandler(Command\Channel\Hangup\Request::class, new Command\Channel\Hangup\Handler)
->setMethodHandler(Command\Channel\Originate\Request::class, new Command\Channel\Originate\Handler)
->setMethodHandler(Command\Channel\Playback\Request::class, new Command\Channel\Playback\Handler)
->setMethodHandler(Command\Channel\Record\Request::class, new Command\Channel\Record\Handler)
->setMethodHandler(Command\Channel\Redirect\Request::class, new Command\Channel\Redirect\Handler)
->setMethodHandler(Command\Conference\Member\Request::class, new Command\Conference\Member\Handler)
->setMethodHandler(Command\Conference\Playback\Request::class, new Command\Conference\Playback\Handler)
->setMethodHandler(Command\Conference\Record\Request::class, new Command\Conference\Record\Handler)
->setMethodHandler(Command\Conference\Speak\Request::class, new Command\Conference\Speak\Handler)
->setMethodHandler(Eqivo\Command\Channel\SoundTouch\Request::class, new Eqivo\Command\Channel\SoundTouch\Handler)
->setMethodHandler(Eqivo\Command\Conference\Query\Request::class, new Eqivo\Command\Conference\Query\Handler)
);

$eqivo->setRestServer(
(new Rest\Server)
(new Eqivo\Rest\Server)
->setApp($eqivo)
->setRouteController('POST', '/v0.1/BulkCall/', new Rest\Controller\V0_1\BulkCall)
->setRouteController('POST', '/v0.1/Call/', new Rest\Controller\V0_1\Call)
->setRouteController('POST', '/v0.1/CancelScheduledHangup/', new Rest\Controller\V0_1\CancelScheduledHangup)
->setRouteController('POST', '/v0.1/CancelScheduledPlay/', new Rest\Controller\V0_1\CancelScheduledPlay)
->setRouteController('POST', '/v0.1/ConferenceDeaf/', new Rest\Controller\V0_1\ConferenceDeaf)
->setRouteController('POST', '/v0.1/ConferenceHangup/', new Rest\Controller\V0_1\ConferenceHangup)
->setRouteController('POST', '/v0.1/ConferenceKick/', new Rest\Controller\V0_1\ConferenceKick)
->setRouteController('POST', '/v0.1/ConferenceList/', new Rest\Controller\V0_1\ConferenceList)
->setRouteController('POST', '/v0.1/ConferenceListMembers/', new Rest\Controller\V0_1\ConferenceListMembers)
->setRouteController('POST', '/v0.1/ConferenceMute/', new Rest\Controller\V0_1\ConferenceMute)
->setRouteController('POST', '/v0.1/ConferencePlay/', new Rest\Controller\V0_1\ConferencePlay)
->setRouteController('POST', '/v0.1/ConferenceRecordStart/', new Rest\Controller\V0_1\ConferenceRecordStart)
->setRouteController('POST', '/v0.1/ConferenceRecordStop/', new Rest\Controller\V0_1\ConferenceRecordStop)
->setRouteController('POST', '/v0.1/ConferenceSpeak/', new Rest\Controller\V0_1\ConferenceSpeak)
->setRouteController('POST', '/v0.1/ConferenceUndeaf/', new Rest\Controller\V0_1\ConferenceUndeaf)
->setRouteController('POST', '/v0.1/ConferenceUnmute/', new Rest\Controller\V0_1\ConferenceUnmute)
->setRouteController('POST', '/v0.1/GroupCall/', new Rest\Controller\V0_1\GroupCall)
->setRouteController('POST', '/v0.1/HangupAllCalls/', new Rest\Controller\V0_1\HangupAllCalls)
->setRouteController('POST', '/v0.1/HangupCall/', new Rest\Controller\V0_1\HangupCall)
->setRouteController('POST', '/v0.1/Play/', new Rest\Controller\V0_1\Play)
->setRouteController('POST', '/v0.1/PlayStop/', new Rest\Controller\V0_1\PlayStop)
->setRouteController('POST', '/v0.1/RecordStart/', new Rest\Controller\V0_1\RecordStart)
->setRouteController('POST', '/v0.1/RecordStop/', new Rest\Controller\V0_1\RecordStop)
->setRouteController('POST', '/v0.1/ScheduleHangup/', new Rest\Controller\V0_1\ScheduleHangup)
->setRouteController('POST', '/v0.1/SchedulePlay/', new Rest\Controller\V0_1\SchedulePlay)
->setRouteController('POST', '/v0.1/SendDigits/', new Rest\Controller\V0_1\SendDigits)
->setRouteController('POST', '/v0.1/SoundTouch/', new Rest\Controller\V0_1\SoundTouch)
->setRouteController('POST', '/v0.1/SoundTouchStop/', new Rest\Controller\V0_1\SoundTouchStop)
->setRouteController('POST', '/v0.1/TransferCall/', new Rest\Controller\V0_1\TransferCall)
->setRouteController('POST', '/v0.1/BulkCall/', new Eqivo\Rest\Controller\V0_1\BulkCall)
->setRouteController('POST', '/v0.1/Call/', new Eqivo\Rest\Controller\V0_1\Call)
->setRouteController('POST', '/v0.1/CancelScheduledHangup/', new Eqivo\Rest\Controller\V0_1\CancelScheduledHangup)
->setRouteController('POST', '/v0.1/CancelScheduledPlay/', new Eqivo\Rest\Controller\V0_1\CancelScheduledPlay)
->setRouteController('POST', '/v0.1/ConferenceDeaf/', new Eqivo\Rest\Controller\V0_1\ConferenceDeaf)
->setRouteController('POST', '/v0.1/ConferenceHangup/', new Eqivo\Rest\Controller\V0_1\ConferenceHangup)
->setRouteController('POST', '/v0.1/ConferenceKick/', new Eqivo\Rest\Controller\V0_1\ConferenceKick)
->setRouteController('POST', '/v0.1/ConferenceList/', new Eqivo\Rest\Controller\V0_1\ConferenceList)
->setRouteController('POST', '/v0.1/ConferenceListMembers/', new Eqivo\Rest\Controller\V0_1\ConferenceListMembers)
->setRouteController('POST', '/v0.1/ConferenceMute/', new Eqivo\Rest\Controller\V0_1\ConferenceMute)
->setRouteController('POST', '/v0.1/ConferencePlay/', new Eqivo\Rest\Controller\V0_1\ConferencePlay)
->setRouteController('POST', '/v0.1/ConferenceRecordStart/', new Eqivo\Rest\Controller\V0_1\ConferenceRecordStart)
->setRouteController('POST', '/v0.1/ConferenceRecordStop/', new Eqivo\Rest\Controller\V0_1\ConferenceRecordStop)
->setRouteController('POST', '/v0.1/ConferenceSpeak/', new Eqivo\Rest\Controller\V0_1\ConferenceSpeak)
->setRouteController('POST', '/v0.1/ConferenceUndeaf/', new Eqivo\Rest\Controller\V0_1\ConferenceUndeaf)
->setRouteController('POST', '/v0.1/ConferenceUnmute/', new Eqivo\Rest\Controller\V0_1\ConferenceUnmute)
->setRouteController('POST', '/v0.1/GroupCall/', new Eqivo\Rest\Controller\V0_1\GroupCall)
->setRouteController('POST', '/v0.1/HangupAllCalls/', new Eqivo\Rest\Controller\V0_1\HangupAllCalls)
->setRouteController('POST', '/v0.1/HangupCall/', new Eqivo\Rest\Controller\V0_1\HangupCall)
->setRouteController('POST', '/v0.1/Play/', new Eqivo\Rest\Controller\V0_1\Play)
->setRouteController('POST', '/v0.1/PlayStop/', new Eqivo\Rest\Controller\V0_1\PlayStop)
->setRouteController('POST', '/v0.1/RecordStart/', new Eqivo\Rest\Controller\V0_1\RecordStart)
->setRouteController('POST', '/v0.1/RecordStop/', new Eqivo\Rest\Controller\V0_1\RecordStop)
->setRouteController('POST', '/v0.1/ScheduleHangup/', new Eqivo\Rest\Controller\V0_1\ScheduleHangup)
->setRouteController('POST', '/v0.1/SchedulePlay/', new Eqivo\Rest\Controller\V0_1\SchedulePlay)
->setRouteController('POST', '/v0.1/SendDigits/', new Eqivo\Rest\Controller\V0_1\SendDigits)
->setRouteController('POST', '/v0.1/SoundTouch/', new Eqivo\Rest\Controller\V0_1\SoundTouch)
->setRouteController('POST', '/v0.1/SoundTouchStop/', new Eqivo\Rest\Controller\V0_1\SoundTouchStop)
->setRouteController('POST', '/v0.1/TransferCall/', new Eqivo\Rest\Controller\V0_1\TransferCall)
);

$eqivo->setEslServer(new ESL\Server);

$eqivo->prepare();
$eqivo->run();
21 changes: 6 additions & 15 deletions composer.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"name": "rtckit/eqivo",
"description": "Telephony API Platform",
"version": "0.5.5",
"version": "0.6.0",
"keywords": [
"telecommunications",
"voip",
Expand All @@ -27,6 +27,7 @@
"ext-ctype": "*",
"ext-date": "*",
"ext-filter": "*",
"ext-hash": "*",
"ext-json": "*",
"ext-libxml": "*",
"ext-pcre": "*",
Expand All @@ -38,22 +39,14 @@
"react/http": "^1.7",
"react/promise": "^2.9",
"rtckit/esl": "^0.8",
"rtckit/react-esl": "^0.8",
"rtckit/ficore": "0.0.2",
"rtckit/sip": "^0.7",
"symfony/yaml": "^6.1",
"wikimedia/ip-set": "^3.1",
"wyrihaximus/react-psr-3-stdio": "^3.0"
"wikimedia/ip-set": "^3.1"
},
"require-dev": {
"clue/block-react": "^1.5",
"phpstan/phpstan": "^1.8",
"phpunit/phpunit": "^9.5",
"vimeo/psalm": "^4.26",
"zircote/swagger-php": "^4.4"
},
"suggest": {
"ext-pcntl": "Enables daemonization support",
"ext-posix": "Enables UID/GID manipulation"
"phpstan/phpstan": "^1.9",
"vimeo/psalm": "^5.6"
},
"autoload": {
"psr-4": {
Expand All @@ -77,8 +70,6 @@
"scripts": {
"phpstan": "php -d memory_limit=-1 ./vendor/bin/phpstan analyse -c ./etc/phpstan.neon -n -vvv --ansi --level=max src",
"psalm": "php -d memory_limit=-1 ./vendor/bin/psalm --config=./etc/psalm.xml --show-info=true",
"phpunit": "php -d memory_limit=-1 ./vendor/bin/phpunit --debug -c ./etc/phpunit.xml.dist",
"coverage": "php -d memory_limit=-1 ./vendor/bin/phpunit --debug -c ./etc/phpunit.xml.dist --coverage-text --coverage-html=reports/coverage",
"dev-docker": "docker build -f ./etc/Dockerfile.dev -t rtckit/eqivo ."
}
}
2 changes: 1 addition & 1 deletion etc/Dockerfile
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
FROM php:8.1.7-cli-bullseye
FROM php:8.1.14-cli-bullseye

RUN docker-php-ext-install pcntl

Expand Down
2 changes: 1 addition & 1 deletion etc/Dockerfile.dev
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
FROM php:8.1.7-cli-bullseye
FROM php:8.1.14-cli-bullseye

RUN docker-php-ext-install pcntl

Expand Down
4 changes: 2 additions & 2 deletions etc/Dockerfile.freeswitch
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
FROM rtckit/slimswitch-builder:v1.10.7
FROM rtckit/slimswitch-builder:v1.10.8

# Build with:
#
# docker build -f ./etc/Dockerfile.freeswitch -t rtckit/eqivo-freeswitch-builder:v1.10.7 .
# docker build -f ./etc/Dockerfile.freeswitch -t rtckit/eqivo-freeswitch-builder:v1.10.8 .
#
# Minify with rtckit/slimswitch:
#
Expand Down
Loading

0 comments on commit c5e2b97

Please sign in to comment.