def accept(self) -> bool: self.update_state(CallState.EXCHANGING_KEYS) if not self.call: self.call_failed() raise RuntimeError('call is not set') self.get_dhc() self.b = randint(2, self.dhc.p-1) self.g_b = pow(self.dhc.g, self.b, self.dhc.p) self.g_a_hash = self.call.g_a_hash try: self.call = self.client.send(functions.phone.AcceptCall( peer=types.InputPhoneCall(id=self.call_id, access_hash=self.call_access_hash), g_b=i2b(self.g_b), protocol=self.get_protocol() )).phone_call except errors.Error as e: if e.ID == 'CALL_ALREADY_ACCEPTED': self.stop() return True elif e.ID == 'CALL_ALREADY_DECLINED': self.call_discarded() return False raise e if isinstance(self.call, types.PhoneCallDiscarded): print('Call is already discarded') self.call_discarded() return False return True
def request(self): self.update_state(CallState.REQUESTING) self.peer = self.client.resolve_peer(self.user_id) self.get_dhc() self.a = randint(2, self.dhc.p - 1) self.g_a = pow(self.dhc.g, self.a, self.dhc.p) self.g_a_hash = hashlib.sha256(i2b(self.g_a)).digest() self.call = self.client.send( functions.phone.RequestCall( user_id=self.peer, random_id=randint(0, 0x7fffffff - 1), g_a_hash=self.g_a_hash, protocol=self.get_protocol(), )).phone_call self.update_state(CallState.WAITING)
def __init__(self, user_id: Union[int, str], *args, **kwargs): super(VoIPOutgoingCall, self).__init__(*args, **kwargs) self.update_state(CallState.REQUESTING) self.peer = self.client.resolve_peer(user_id) self.a = randint(2, self.dhc.p - 1) self.g_a = pow(self.dhc.g, self.a, self.dhc.p) self.g_a_hash = hashlib.sha256(i2b(self.g_a)).digest() self.call = self.client.send( functions.phone.RequestCall( user_id=self.peer, random_id=randint(0, 0x7fffffff - 1), g_a_hash=self.g_a_hash, protocol=self.get_protocol(), )).phone_call self.update_state(CallState.WAITING) self.call_accepted_handlers = []
def call_accepted(self) -> None: for handler in self.call_accepted_handlers: callable(handler) and handler(self) self.update_state(CallState.EXCHANGING_KEYS) self.g_b = b2i(self.call.g_b) self.check_g(self.g_b, self.dhc.p) self.auth_key = pow(self.g_b, self.a, self.dhc.p) self.key_fingerprint = calc_fingerprint(self.auth_key_bytes) self.call = self.client.send( functions.phone.ConfirmCall( key_fingerprint=self.key_fingerprint, peer=types.InputPhoneCall(id=self.call.id, access_hash=self.call_access_hash), g_a=i2b(self.g_a), protocol=self.get_protocol(), )).phone_call self._initiate_encrypted_call()
def auth_key_bytes(self) -> bytes: return i2b(self.auth_key) if self.auth_key is not None else b''