diff --git a/src/MTProtoTools/UpdateHandler.php b/src/MTProtoTools/UpdateHandler.php index 41355007e..fdd37b5c6 100644 --- a/src/MTProtoTools/UpdateHandler.php +++ b/src/MTProtoTools/UpdateHandler.php @@ -939,6 +939,9 @@ trait UpdateHandler $this->parseConfig(); return; } + if ($update['_'] === 'updatePhoneCallSignalingData') { + ($this->calls[$update['phone_call_id']] ?? null)?->onSignaling((string) $update['data']); + } if ($update['_'] === 'updatePhoneCall') { switch ($update['phone_call']['_']) { case 'phoneCallRequested': diff --git a/src/VoIP/AuthKeyHandler.php b/src/VoIP/AuthKeyHandler.php index 920b57bcb..cefbc8465 100644 --- a/src/VoIP/AuthKeyHandler.php +++ b/src/VoIP/AuthKeyHandler.php @@ -79,7 +79,11 @@ trait AuthKeyHandler $this->logger->logger('Generating g_a...', Logger::VERBOSE); $g_a = $dh_config['g']->powMod($a, $dh_config['p']); Crypt::checkG($g_a, $dh_config['p']); - $res = $this->methodCallAsyncRead('phone.requestCall', ['user_id' => $user, 'g_a_hash' => \hash('sha256', $g_a->toBytes(), true), 'protocol' => ['_' => 'phoneCallProtocol', 'udp_p2p' => true, 'udp_reflector' => true, 'min_layer' => 65, 'max_layer' => 92]])['phone_call']; + $res = $this->methodCallAsyncRead('phone.requestCall', [ + 'user_id' => $user, + 'g_a_hash' => \hash('sha256', $g_a->toBytes(), true), + 'protocol' => VoIPController::CALL_PROTOCOL + ])['phone_call']; $res['a'] = $a; $res['g_a'] = \str_pad($g_a->toBytes(), 256, \chr(0), STR_PAD_LEFT); $this->calls[$res['id']] = $controller = new VoIPController($this, $res); diff --git a/src/VoIPController.php b/src/VoIPController.php index bc65a81a5..349645b2d 100644 --- a/src/VoIPController.php +++ b/src/VoIPController.php @@ -39,6 +39,24 @@ use function Amp\Future\await; /** @internal */ final class VoIPController { + public const CALL_PROTOCOL = [ + '_' => 'phoneCallProtocol', + 'udp_p2p' => true, + 'udp_reflector' => true, + 'min_layer' => 65, + 'max_layer' => 92, + /*'library_versions' => [ + "2.4.4", + "2.7.7", + "5.0.0", + "6.0.0", + "7.0.0", + "8.0.0", + "9.0.0", + "10.0.0", + "11.0.0" + ]*/ + ]; const NET_TYPE_UNKNOWN = 0; const NET_TYPE_GPRS = 1; const NET_TYPE_EDGE = 2; @@ -196,7 +214,12 @@ final class VoIPController Crypt::checkG($params['g_b'], $dh_config['p']); $key = \str_pad($params['g_b']->powMod($this->call['a'], $dh_config['p'])->toBytes(), 256, \chr(0), STR_PAD_LEFT); try { - $res = ($this->API->methodCallAsyncRead('phone.confirmCall', ['key_fingerprint' => \substr(\sha1($key, true), -8), 'peer' => ['id' => $params['id'], 'access_hash' => $params['access_hash'], '_' => 'inputPhoneCall'], 'g_a' => $this->call['g_a'], 'protocol' => ['_' => 'phoneCallProtocol', 'udp_reflector' => true, 'min_layer' => 65, 'max_layer' => 92]]))['phone_call']; + $res = ($this->API->methodCallAsyncRead('phone.confirmCall', [ + 'key_fingerprint' => \substr(\sha1($key, true), -8), + 'peer' => ['id' => $params['id'], 'access_hash' => $params['access_hash'], '_' => 'inputPhoneCall'], + 'g_a' => $this->call['g_a'], + 'protocol' => self::CALL_PROTOCOL + ]))['phone_call']; } catch (RPCErrorException $e) { if ($e->rpc === 'CALL_ALREADY_ACCEPTED') { $this->log(\sprintf(Lang::$current_lang['call_already_accepted'], $params['id'])); @@ -244,7 +267,15 @@ final class VoIPController $this->callState = CallState::ACCEPTED; try { - $this->API->methodCallAsyncRead('phone.acceptCall', ['peer' => ['id' => $this->call['id'], 'access_hash' => $this->call['access_hash'], '_' => 'inputPhoneCall'], 'g_b' => $g_b->toBytes(), 'protocol' => ['_' => 'phoneCallProtocol', 'udp_reflector' => true, 'udp_p2p' => true, 'min_layer' => 65, 'max_layer' => 92]]); + $this->API->methodCallAsyncRead('phone.acceptCall', [ + 'peer' => [ + 'id' => $this->call['id'], + 'access_hash' => $this->call['access_hash'], + '_' => 'inputPhoneCall' + ], + 'g_b' => $g_b->toBytes(), + 'protocol' => self::CALL_PROTOCOL + ]); } catch (RPCErrorException $e) { if ($e->rpc === 'CALL_ALREADY_ACCEPTED') { $this->log(\sprintf(Lang::$current_lang['call_already_accepted'], $this->public->callID)); @@ -360,6 +391,10 @@ final class VoIPController } return $this; } + public function onSignaling(string $data): void + { + //\var_dump($data); + } private function setVoipState(VoIPState $state): bool { @@ -378,6 +413,9 @@ final class VoIPController { foreach ([true, false] as $udp) { foreach ($endpoints as $endpoint) { + if ($endpoint['_'] !== 'phoneConnection') { + continue; + } if (!isset($this->sockets[($udp ? 'udp' : 'tcp').' v6 '.$endpoint['id']])) { $this->sockets[($udp ? 'udp' : 'tcp').' v6 '.$endpoint['id']] = new Endpoint( $udp,