Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions .github/workflows/ci.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,8 @@ jobs:
- ubuntu-20.04
php:
- 8.1
- 8.2
- 8.3
steps:
- uses: actions/checkout@v2
- uses: shivammathur/setup-php@v2
Expand Down
16 changes: 8 additions & 8 deletions composer.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"name": "rtckit/ficore",
"description": "FreeSWITCH Integration Core",
"version": "0.0.2",
"version": "0.0.3",
"keywords": [
"telecommunications",
"voip",
Expand All @@ -28,19 +28,19 @@
"ext-libxml": "*",
"ext-pcre": "*",
"ext-simplexml": "*",
"monolog/monolog": "^3.2",
"ramsey/uuid": "^4.4",
"react/event-loop": "^1.3",
"react/promise": "^2.9",
"monolog/monolog": "^3.5",
"ramsey/uuid": "^4.7",
"react/event-loop": "^1.5",
"react/promise": "^3.1",
"rtckit/esl": "^0.8",
"rtckit/react-esl": "^0.8",
"rtckit/sip": "^0.7",
"wyrihaximus/react-psr-3-stdio": "^3.0"
},
"require-dev": {
"phpstan/phpstan": "^1.9",
"phpunit/phpunit": "^9.5",
"vimeo/psalm": "^5.6"
"phpstan/phpstan": "^1.10",
"phpunit/phpunit": "^10.4",
"vimeo/psalm": "^5.16"
},
"suggest": {
"ext-pcntl": "Enables daemonization support",
Expand Down
2 changes: 1 addition & 1 deletion etc/phpstan.neon
Original file line number Diff line number Diff line change
Expand Up @@ -3,4 +3,4 @@ includes:
parameters:
checkGenericClassInNonGenericObjectType: false
ignoreErrors:
- '#Call to an undefined method React\\Promise\\PromiseInterface::otherwise\(\)#'
- '#Parameter \#1 \$onFulfilled of method React\\Promise\\PromiseInterface<mixed>::then\(\) expects \(callable\(mixed\):#'
2 changes: 1 addition & 1 deletion src/Command/Channel/DTMF/Handler.php
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ public function execute(RequestInterface $request): PromiseInterface

$response = new Response();

if ($request->action !== ActionEnum::Send) {
if (!isset($request->action)) {
$response->successful = false;

return resolve($response);
Expand Down
2 changes: 1 addition & 1 deletion src/Command/Channel/Hangup/Handler.php
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,7 @@ public function execute(RequestInterface $request): PromiseInterface
$response->successful = false;
}

return resolve();
return resolve(null);
});
}

Expand Down
7 changes: 3 additions & 4 deletions src/Command/Channel/Originate/Handler.php
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,6 @@ public function execute(RequestInterface $request): PromiseInterface
}

assert(isset($job));
assert($job instanceof OriginateJob);

$response->originateJobs[] = $job;

Expand Down Expand Up @@ -215,7 +214,7 @@ public function execute(RequestInterface $request): PromiseInterface
$job->originateStr = $originateStr;

$this->loopGateways($job)
->otherwise(function (\Throwable $t) {
->catch(function (\Throwable $t) {
$t = $t->getPrevious() ?: $t;

$this->app->eslClient->logger->error('Originate channel exception: ' . $t->getMessage(), [
Expand Down Expand Up @@ -323,7 +322,7 @@ protected function loopGateways(OriginateJob $originateJob): PromiseInterface
if ($success) {
$this->app->commandConsumer->logger->info("Call Attempt OK for RequestUUID {$originateJob->uuid}");

return resolve();
return resolve(null);
}

$this->app->commandConsumer->logger->info("Call Attempt Failed for RequestUUID {$originateJob->uuid}, retrying next gateway ...");
Expand All @@ -337,7 +336,7 @@ protected function loopGateways(OriginateJob $originateJob): PromiseInterface

return $this->loopGateways($originateJob);
})
->otherwise(function (\Throwable $t) {
->catch(function (\Throwable $t) {
$t = $t->getPrevious() ?: $t;

$this->app->eslClient->logger->error('loopGateways exception: ' . $t->getMessage(), [
Expand Down
5 changes: 3 additions & 2 deletions src/Command/Channel/Playback/Handler.php
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,7 @@ public function execute(RequestInterface $request): PromiseInterface
$this->app->commandConsumer->logger->error("Play Failed '{$command}': " . ($eslResponse->getBody() ?? '<null>'));
}

return resolve();
return resolve(null);
});
}

Expand Down Expand Up @@ -96,7 +96,7 @@ public function execute(RequestInterface $request): PromiseInterface
$this->app->commandConsumer->logger->error("PlayStop Failed '{$command}': " . ($eslResponse->getBody() ?? '<null>'));
}

return resolve();
return resolve(null);
});
}

Expand Down Expand Up @@ -160,6 +160,7 @@ private function getPlayCommands(Request $request): PromiseInterface
$ret = [];

foreach ($results as $commands) {
assert(is_array($commands));
$ret = array_merge($ret, $commands);
}

Expand Down
20 changes: 15 additions & 5 deletions src/Command/Channel/Redirect/Handler.php
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ public function execute(RequestInterface $request): PromiseInterface

$response = new Response();

if ($request->action !== ActionEnum::Redirect) {
if (!isset($request->action)) {
$response->successful = false;

return resolve($response);
Expand All @@ -48,17 +48,27 @@ public function execute(RequestInterface $request): PromiseInterface
),
])
->then(function (array $args) use ($request): PromiseInterface {
$destNumber = $args[$this->app->config->appPrefix . '_destination_number']->getBody();
$prefixedDestNumber = $args[$this->app->config->appPrefix . '_destination_number'];

assert($prefixedDestNumber instanceof ESL\Response\ApiResponse);

$destNumber = $prefixedDestNumber->getBody();

if (is_string($destNumber) && (($destNumber === '_undef_') || (strpos($destNumber, '-ERR') === 0))) {
assert($args['destination_number'] instanceof ESL\Response\ApiResponse);

if (($destNumber === '_undef_') || (strpos($destNumber, '-ERR') === 0)) {
$destNumber = $args['destination_number']->getBody();

assert(is_string($destNumber));

return $request->channel->core->client->api(
(new ESL\Request\Api())->setParameters("uuid_setvar {$request->channel->uuid} {$this->app->config->appPrefix}_destination_number " . $destNumber)
(new ESL\Request\Api())->setParameters(
"uuid_setvar {$request->channel->uuid} {$this->app->config->appPrefix}_destination_number {$destNumber}"
)
);
}

return resolve();
return resolve(null);
})
->then(function () use ($request): PromiseInterface {
$request->channel->transferInProgress = true;
Expand Down
2 changes: 1 addition & 1 deletion src/Command/Conference/Member/Handler.php
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ public function execute(RequestInterface $request): PromiseInterface
$this->app->commandConsumer->logger->debug("`conference {$request->conference->room} {$request->action->value} {$member}` success");
}

return resolve();
return resolve(null);
});
}

Expand Down
2 changes: 1 addition & 1 deletion src/Command/Conference/Speak/Handler.php
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ public function execute(RequestInterface $request): PromiseInterface

$response = new Response();

if ($request->action !== ActionEnum::Speak) {
if (!isset($request->action)) {
$response->successful = false;

return resolve($response);
Expand Down
3 changes: 3 additions & 0 deletions src/Plan/CaptureSpeech/Element.php
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,8 @@

use RTCKit\FiCore\Plan\AbstractElement;

use stdClass as Event;

class Element extends AbstractElement
{
public string $sequence;
Expand All @@ -19,6 +21,7 @@ class Element extends AbstractElement
public string $grammar;
public string $grammarPath;
public TimerInterface $timer;
public Event $event;

/** @var list<string> */
public array $setVars = [];
Expand Down
41 changes: 33 additions & 8 deletions src/Plan/CaptureSpeech/Handler.php
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
PromiseInterface
};
use RTCKit\ESL;
use RTCKit\FiCore\Exception\FiCoreException;
use RTCKit\FiCore\Plan\{
AbstractElement,
HandlerInterface,
Expand Down Expand Up @@ -63,9 +64,9 @@ public function execute(Channel $channel, AbstractElement $element): PromiseInte
if (!$response->isSuccessful()) {
$this->app->planConsumer->logger->error('GetSpeech Failed - ' . ($response->getBody() ?? '<null>'));

$deferred->resolve();
$deferred->resolve(null);

return reject();
return reject(new FiCoreException('GetSpeech Failed'));
}

return $element->channel->client->sendMsg(
Expand Down Expand Up @@ -118,6 +119,21 @@ public function execute(Channel $channel, AbstractElement $element): PromiseInte
return $this->app->planConsumer->waitForEvent($element->channel);
})
->then(function (Event $event) use ($element): PromiseInterface {
if (
($event->{'Event-Name'} === 'DETECTED_SPEECH') &&
in_array($event->{'Speech-Type'}, ['begin-speaking', 'detected-speech'])
) {
$this->app->planConsumer->logger->debug("GetSpeech Break ({$event->{'Speech-Type'}})");

if ($event->{'Speech-Type'} === 'detected-speech') {
$element->event = $event;
}

return $element->channel->client->bgApi(
(new ESL\Request\BgApi())->setParameters('uuid_break ' . $element->channel->uuid . ' all')
);
}

$response = $event->{'Application-Response'} ?? '<null>';
$this->app->planConsumer->logger->debug("GetSpeech prompt played ({$response})");

Expand Down Expand Up @@ -168,7 +184,7 @@ public function execute(Channel $channel, AbstractElement $element): PromiseInte

$signal->channel = $element->channel;

if (isset($args['response'])) {
if (isset($args['response']) && is_string($args['response'])) {
$resultXml = simplexml_load_string($args['response']);
if ($resultXml === false) {
$this->app->planConsumer->logger->error("GetSpeech result failure, cannot parse result");
Expand Down Expand Up @@ -222,7 +238,7 @@ public function execute(Channel $channel, AbstractElement $element): PromiseInte
->then(function (bool $break) use ($deferred) {
$deferred->resolve($break);
})
->otherwise(function (Throwable $t) {
->catch(function (Throwable $t) {
$t = $t->getPrevious() ?: $t;
$this->app->planConsumer->logger->error("Unhandled getspeech element error: " . $t->getMessage(), [
'file' => $t->getFile(),
Expand All @@ -237,14 +253,23 @@ protected function waitForEvent(Element $element): PromiseInterface
{
return $this->app->planConsumer->waitForEvent($element->channel)
->then(function (?Event $event) use ($element): PromiseInterface {
if (isset($element->event)) {
$event = $element->event;
}

if (!isset($event)) {
$this->app->planConsumer->logger->warning('GetSpeech Break (empty event)');

return resolve();
} elseif (($event->{'Event-Name'} === 'DETECTED_SPEECH') && ($event->{'Speech-Type'} === 'detected-speech')) {
Loop::cancelTimer($element->timer);
return resolve(null);
} else if (
($event->{'Event-Name'} === 'DETECTED_SPEECH') &&
in_array($event->{'Speech-Type'}, ['begin-speaking', 'detected-speech'])
) {
if (isset($element->timer)) {
Loop::cancelTimer($element->timer);
}

$this->app->planConsumer->logger->info("GetSpeech, result '{$event->_body}'");
$this->app->planConsumer->logger->info("GetSpeech ({$event->{'Speech-Type'}}), result '{$event->_body}'");

return resolve($event->_body);
}
Expand Down
2 changes: 1 addition & 1 deletion src/Plan/CaptureTones/Handler.php
Original file line number Diff line number Diff line change
Expand Up @@ -119,7 +119,7 @@ public function execute(Channel $channel, AbstractElement $element): PromiseInte
$this->app->planConsumer->logger->info('GetDigits, No Digits Received');
}

return resolve();
return resolve(null);
});
}
}
8 changes: 4 additions & 4 deletions src/Plan/Conference/Handler.php
Original file line number Diff line number Diff line change
Expand Up @@ -100,7 +100,7 @@ public function execute(Channel $channel, AbstractElement $element): PromiseInte
});
}

return resolve();
return resolve(null);
})
->then(function () use ($element): PromiseInterface {
$this->app->planConsumer->logger->info("Entering Conference: Room {$element->room}", $element->flags);
Expand Down Expand Up @@ -240,7 +240,7 @@ public function execute(Channel $channel, AbstractElement $element): PromiseInte
});
}

return resolve();
return resolve(null);
})
->then(function () use ($element, $digitRealm) {
$element->channel->client->sendMsg(
Expand Down Expand Up @@ -279,7 +279,7 @@ public function execute(Channel $channel, AbstractElement $element): PromiseInte
});
}
})
->otherwise(function (\Throwable $t) {
->catch(function (\Throwable $t) {
$t = $t->getPrevious() ?: $t;

$this->app->planConsumer->logger->error('Unhandled exception: ' . $t->getMessage(), [
Expand Down Expand Up @@ -307,7 +307,7 @@ protected function waitForEvent(Element $element): PromiseInterface
$this->app->signalProducer->produce($floorSignal);
}
} else {
return resolve();
return resolve(null);
}
}

Expand Down
Loading