Source code for rpcclient.ios.telephony

import logging

from rpcclient.structs.consts import RTLD_NOW

logger = logging.getLogger(__name__)


[docs] class Call: def __init__(self, client, controller, call): self._client = client self._controller = controller self._call = call
[docs] def disconnect(self): """ Disconnect the current call. """ self._send_action('CXEndCallAction')
[docs] def answer(self): """ Answer the current call. """ self._send_action('CXAnswerCallAction')
def _send_action(self, action_name): action_class = self._client.symbols.objc_getClass(action_name) action = action_class.objc_call('alloc').objc_call('initWithCallUUID:', self._uuid) self._controller.objc_call('requestTransactionWithAction:completion:', action, self._client.get_dummy_block()) @property def _uuid(self): return self._call.objc_call('UUID')
[docs] class Telephony: """ Telephony utils. In order to access the real telephony, the API requires the entitlement "application-identifier" to be set to "com.apple.coretelephony". """ def __init__(self, client): self._client = client self._load_callkit_library() self.cx_call_controller = self._client.symbols.objc_getClass('CXCallController').objc_call('new') self.cx_call_observer = self.cx_call_controller.objc_call('callObserver') self.ct_message_center = self._client.symbols.objc_getClass('CTMessageCenter').objc_call('sharedMessageCenter')
[docs] def dial(self, number: str): """ Start a call to a number. Use `current_call` to access the created call. :param number: Phone address to call to. """ self._client.symbols.CTCallDial(self._client.cf(number))
[docs] def send_sms(self, to_address: str, text: str, smsc: str = '1111'): """ Send a SMS. :param to_address: Phone address to send to. :param text: Message text. :param smsc: Originator's short message service center address. """ self.ct_message_center.objc_call( 'sendSMSWithText:serviceCenter:toAddress:', self._client.cf(text), self._client.cf(smsc), self._client.cf(to_address) )
@property def current_call(self) -> Call: """ Return on object representing the current active call. """ calls = self.cx_call_observer.objc_call('calls') call_count = calls.objc_call('count') call_list = [] for i in range(call_count): call_list.append(calls.objc_call('objectAtIndex:', i)) for call_id in range(call_count): call = call_list[call_id] if call.objc_call('hasEnded'): continue return Call(self._client, self.cx_call_controller, call) def _load_callkit_library(self): options = [ '/System/Library/Frameworks/CallKit.framework/CallKit' ] for option in options: if self._client.dlopen(option, RTLD_NOW): return logger.warning('CallKit library isn\'t available')