diff --git a/output.raw b/input.raw similarity index 100% rename from output.raw rename to input.raw diff --git a/src/danog/MadelineProto/MTProto.php b/src/danog/MadelineProto/MTProto.php index 1933b3bf..49f09671 100644 --- a/src/danog/MadelineProto/MTProto.php +++ b/src/danog/MadelineProto/MTProto.php @@ -268,7 +268,9 @@ class MTProto extends \Volatile return; } foreach ($this->calls as $id => $controller) { - if (is_array($controller) || $controller->getCallState() === \danog\MadelineProto\VoIP::CALL_STATE_ENDED) { + if (is_array($controller)) { + unset($this->calls[$id]); + } else if ($controller->getCallState() === \danog\MadelineProto\VoIP::CALL_STATE_ENDED) { $controller->discard(); } } diff --git a/src/danog/MadelineProto/MTProtoTools/UpdateHandler.php b/src/danog/MadelineProto/MTProtoTools/UpdateHandler.php index c16b3f26..5aa2e447 100644 --- a/src/danog/MadelineProto/MTProtoTools/UpdateHandler.php +++ b/src/danog/MadelineProto/MTProtoTools/UpdateHandler.php @@ -471,8 +471,9 @@ trait UpdateHandler \danog\MadelineProto\Logger::log([$update], \danog\MadelineProto\Logger::WARNING); switch ($update['phone_call']['_']) { case 'phoneCallRequested': - $this->calls[$update['phone_call']['id']] = $update['phone_call'] = new \danog\MadelineProto\VoIP(false, $update['phone_call']['admin_id'], ['_' => 'inputPhoneCall', 'id' => $update['phone_call']['id'], 'access_hash' => $update['phone_call']['access_hash']], $this, \danog\MadelineProto\VoIP::CALL_STATE_INCOMING, $update['phone_call']['protocol']); - $update['phone_call']->storage = ['g_a_hash' => $update['phone_call']['g_a_hash']]; + $controller = new \danog\MadelineProto\VoIP(false, $update['phone_call']['admin_id'], ['_' => 'inputPhoneCall', 'id' => $update['phone_call']['id'], 'access_hash' => $update['phone_call']['access_hash']], $this, \danog\MadelineProto\VoIP::CALL_STATE_INCOMING, $update['phone_call']['protocol']); + $controller->storage = ['g_a_hash' => $update['phone_call']['g_a_hash']]; + $update['phone_call'] = $this->calls[$update['phone_call']['id']] = $controller; break; case 'phoneCallAccepted': @@ -493,8 +494,7 @@ trait UpdateHandler if (!isset($this->calls[$update['phone_call']['id']])) { return; } - ($update['phone_call'] = $this->calls[$update['phone_call']['id']])->discard(['_' => 'phoneCallDiscardReasonHangup'], [], $update['phone_call']['need_debug']); - break; + return $this->calls[$update['phone_call']['id']]->discard(['_' => 'phoneCallDiscardReasonHangup'], [], $update['phone_call']['need_debug']); } } if ($update['_'] === 'updateNewEncryptedMessage' && !isset($update['message']['decrypted_message'])) { diff --git a/src/danog/MadelineProto/VoIP/AuthKeyHandler.php b/src/danog/MadelineProto/VoIP/AuthKeyHandler.php index 9f2a3bc3..c0547f3a 100644 --- a/src/danog/MadelineProto/VoIP/AuthKeyHandler.php +++ b/src/danog/MadelineProto/VoIP/AuthKeyHandler.php @@ -57,7 +57,7 @@ trait AuthKeyHandler return $controller; } - public function accept_call($params) + public function accept_call($call) { if (!class_exists('\danog\MadelineProto\VoIP')) { throw new \danog\MadelineProto\Exception('The php-libtgvoip extension is required to accept and manage calls. See daniil.it/MadelineProto for more info.'); @@ -68,19 +68,18 @@ trait AuthKeyHandler $controller->discard(); } }); - if ($this->call_status($params['id']) !== \danog\MadelineProto\VoIP::CALL_STATE_INCOMING) { - throw new \danog\MadelineProto\Exception('I cannot accept call '.$params['id']); + if ($this->call_status($call['id']) !== \danog\MadelineProto\VoIP::CALL_STATE_INCOMING) { + throw new \danog\MadelineProto\Exception('I cannot accept call '.$call['id']); return false; } - \danog\MadelineProto\Logger::log(['Accepting call from '.$this->calls[$params['id']]->getOtherID().'...'], \danog\MadelineProto\Logger::VERBOSE); + \danog\MadelineProto\Logger::log(['Accepting call from '.$this->calls[$call['id']]->getOtherID().'...'], \danog\MadelineProto\Logger::VERBOSE); $dh_config = $this->get_dh_config(); \danog\MadelineProto\Logger::log(['Generating b...'], \danog\MadelineProto\Logger::VERBOSE); $b = \phpseclib\Math\BigInteger::randomRange($this->two, $dh_config['p']->subtract($this->two)); $g_b = $dh_config['g']->powMod($b, $dh_config['p']); $this->check_G($g_b, $dh_config['p']); - $res = $this->method_call('phone.acceptCall', ['peer' => $params, 'g_b' => $g_b->toBytes(), 'protocol' => ['_' => 'phoneCallProtocol', 'udp_reflector' => true, 'udp_p2p' => true, 'min_layer' => 65, 'max_layer' => 65]], ['datacenter' => $this->datacenter->curdc]); - $this->calls[$res['phone_call']['id']]->setCallState(\danog\MadelineProto\VoIP::CALL_STATE_ACCEPTED); + $res = $this->method_call('phone.acceptCall', ['peer' => $call, 'g_b' => $g_b->toBytes(), 'protocol' => ['_' => 'phoneCallProtocol', 'udp_reflector' => true, 'udp_p2p' => true, 'min_layer' => 65, 'max_layer' => 65]], ['datacenter' => $this->datacenter->curdc]); $this->calls[$res['phone_call']['id']]->storage['b'] = $b; $this->handle_pending_updates(); @@ -250,28 +249,31 @@ trait AuthKeyHandler if (!class_exists('\danog\MadelineProto\VoIP')) { throw new \danog\MadelineProto\Exception('The php-libtgvoip extension is required to accept and manage calls. See daniil.it/MadelineProto for more info.'); } - if (!isset($this->calls[$call])) { - \danog\MadelineProto\Logger::log(['Could not find and discard call '.$call.'...'], \danog\MadelineProto\Logger::ERROR); - return false; - } - \danog\MadelineProto\Logger::log(['Discarding call '.$call.'...'], \danog\MadelineProto\Logger::VERBOSE); + \danog\MadelineProto\Logger::log(['Discarding call '.$call['id'].'...'], \danog\MadelineProto\Logger::VERBOSE); try { - $res = $this->method_call('phone.discardCall', ['peer' => $this->calls[$call]->getCallID(), 'duration' => time() - $this->calls[$call]->whenCreated(), 'connection_id' => $this->calls[$call]->getPreferredRelayID(), 'reason' => $reason], ['datacenter' => $this->datacenter->curdc]); + $res = $this->method_call('phone.discardCall', ['peer' => $call, 'duration' => time() - $this->calls[$call['id']]->whenCreated(), 'connection_id' => $this->calls[$call['id']]->getPreferredRelayID(), 'reason' => $reason], ['datacenter' => $this->datacenter->curdc]); } catch (\danog\MadelineProto\RPCErrorException $e) { if ($e->rpc !== 'CALL_ALREADY_DECLINED') { throw $e; } } if (!empty($rating)) { - \danog\MadelineProto\Logger::log(['Setting rating for call '.$call.'...'], \danog\MadelineProto\Logger::VERBOSE); - $this->method_call('phone.setCallRating', ['peer' => $this->calls[$call]->getCallID(), 'rating' => $rating['rating'], 'comment' => $rating['comment']], ['datacenter' => $this->datacenter->curdc]); + \danog\MadelineProto\Logger::log(['Setting rating for call '.$call['id'].'...'], \danog\MadelineProto\Logger::VERBOSE); + $this->method_call('phone.setCallRating', ['peer' => $call, 'rating' => $rating['rating'], 'comment' => $rating['comment']], ['datacenter' => $this->datacenter->curdc]); } if ($need_debug) { - \danog\MadelineProto\Logger::log(['Saving debug data for call '.$call.'...'], \danog\MadelineProto\Logger::VERBOSE); - $this->method_call('phone.saveCallDebug', ['peer' => $this->calls[$call]->getCallID(), 'debug' => $this->calls[$call]->getDebugLog()], ['datacenter' => $this->datacenter->curdc]); + \danog\MadelineProto\Logger::log(['Saving debug data for call '.$call['id'].'...'], \danog\MadelineProto\Logger::VERBOSE); + $this->method_call('phone.saveCallDebug', ['peer' => $call, 'debug' => $this->calls[$call['id']]->getDebugLog()], ['datacenter' => $this->datacenter->curdc]); } - unset($this->calls[$call]); + $update = ['_' => 'updatePhoneCall', 'phone_call' => $this->calls[$call['id']]]; + if (isset($this->settings['pwr']['strict']) && $this->settings['pwr']['strict']) { + $this->pwr_update_handler($update); + } else { + in_array($this->settings['updates']['callback'], [['danog\MadelineProto\API', 'get_updates_update_handler'], 'get_updates_update_handler']) ? $this->get_updates_update_handler($update) : $this->settings['updates']['callback']($update); + } + + unset($this->calls[$call['id']]); array_walk($this->calls, function ($controller, $id) { if ($controller->getCallState() === \danog\MadelineProto\VoIP::CALL_STATE_ENDED) { $controller->discard(); diff --git a/tests/testing.php b/tests/testing.php index e63ea97b..ceb919ab 100755 --- a/tests/testing.php +++ b/tests/testing.php @@ -77,62 +77,33 @@ if ($MadelineProto === false) { \danog\MadelineProto\Logger::log(['hey'], \danog\MadelineProto\Logger::FATAL_ERROR); $message = (getenv('TRAVIS_COMMIT') == '') ? 'I iz works always (io laborare sembre) (yo lavorar siempre) (mi labori ĉiam) (я всегда работать) (Ik werkuh altijd) (Ngimbonga ngaso sonke isikhathi ukusebenza)' : ('Travis ci tests in progress: commit '.getenv('TRAVIS_COMMIT').', job '.getenv('TRAVIS_JOB_NUMBER').', PHP version: '.getenv('TRAVIS_PHP_VERSION')); -class pony extends \danog\MadelineProto\VoIP -{ - public function setState(int $state) - { - var_dump("SET STATE $state"); - } - - public function startOutput() - { - var_dump('START READING DATA'); - } - - public function startInput() - { - var_dump('START WRITING DATA'); - } - - public function stopOutput() - { - var_dump('STOP READING DATA'); - } - - public function stopInput() - { - var_dump('STOP WRITING DATA'); - } - - public function getOutputLevel() - { - return 0; - } - - public function debug($state) - { - var_dump("DEBUG $state"); - flush(); - } -} echo 'Serializing MadelineProto to session.madeline...'.PHP_EOL; echo 'Wrote '.\danog\MadelineProto\Serialization::serialize('session.madeline', $MadelineProto).' bytes'.PHP_EOL; -/* -if (stripos(readline('Do you want to make a call? (y/n): '), 'y') !== false) { - $controller = $MadelineProto->request_call('@danogentili'); -}*/ -if (stripos(readline('Do you want to make the secret chat tests? (y/n): '), 'y') !== false) { - $start = false; - $MadelineProto->request_call('@danogentili'); - while (1) { - $MadelineProto->get_updates(); - } - while ($MadelineProto->call_status($id) !== \danog\MadelineProto\MTProto::READY) { - $MadelineProto->get_updates(); - } - var_dump(getenv('TEST_SECRET_CHAT')); +if (stripos(readline('Do you want to make a call? (y/n): '), 'y') !== false) { + $controller = $MadelineProto->request_call(getenv('TEST_SECRET_CHAT'))->play('input.raw')->then('input.raw')->playOnHold(['input.raw'])->setOutputFile('output.raw'); +} +if (stripos(readline('Do you want to handle incoming calls? (y/n): '), 'y') !== false) { + $howmany = readline('How many calls would you like me to handle? '); + $offset = 0; + while ($howmany > 0) { + $updates = $MadelineProto->API->get_updates(['offset' => $offset, 'limit' => 50, 'timeout' => 0]); // Just like in the bot API, you can specify an offset, a limit and a timeout + foreach ($updates as $update) { + \danog\MadelineProto\Logger::log([$update]); + $offset = $update['update_id'] + 1; // Just like in the bot API, the offset must be set to the last update_id + switch ($update['update']['_']) { + case 'updatePhoneCall': + if ($update['update']['phone_call']->getCallState() === \danog\MadelineProto\VoIP::CALL_STATE_INCOMING) { + $update['update']['phone_call']->accept()->play('input.raw')->then('input.raw')->playOnHold(['input.raw'])->setOutputFile('output.raw'); + $howmany--; + } + } + } + echo 'Wrote '.\danog\MadelineProto\Serialization::serialize('session.madeline', $MadelineProto).' bytes'.PHP_EOL; + } +} +if (stripos(readline('Do you want to make the secret chat tests? (y/n): '), 'y') !== false) { $secret = $MadelineProto->API->request_secret_chat(getenv('TEST_SECRET_CHAT')); echo 'Waiting for '.getenv('TEST_SECRET_CHAT').' (secret chat id '.$secret.') to accept the secret chat...'.PHP_EOL; while ($MadelineProto->secret_chat_status($secret) !== 2) {