= Calls = [[TracNav(Python_SIP/TOC)]] Calls are represented by [http://www.pjsip.org/python/pjsua.htm#Call Call] class. == Making Outgoing Calls == Making outgoing call is simple, just invoke [http://www.pjsip.org/python/pjsua.htm#Account-make_call make_call()] method of the [http://www.pjsip.org/python/pjsua.htm#Account Account] object. Assuming you have the account object as ''acc'' variable and destination URI string in ''dst_uri'', you can initiate outgoing call with the snippet below: {{{ #!python try: my_cb = MyCallCallback() call = acc.make_call(dst_uri, cb=my_cb) except pjsua.Error, err: print 'Error making outgoing call:', err }}} The snippet above initiates outgoing call to ''dst_uri'', install the callback to the call, and saves the call instance in ''call'' object. Subsequent operations to the call can use the method in the [http://www.pjsip.org/python/pjsua.htm#Call call] instance, and events to the call will be reported to the callback. More on the callback will be explained a bit later. == Receiving Incoming Calls == Incoming calls are reported as [http://www.pjsip.org/python/pjsua.htm#AccountCallback-on_incoming_call on_incoming_call()] of the [http://www.pjsip.org/python/pjsua.htm#AccountCallback AccountCallback] class. You must derive a class from the !AccountCallback (and install instance of this class to the account) to handle incoming calls. Below is a sample code: {{{ #!python class MyAccountCallback(pjsua.AccountCallback): def __init__(self, account=None): pjsua.AccountCallback.__init__(self, account) def on_incoming_call(self, call): my_cb = MyCallCallback() call.set_callback(my_cb) }}} For incoming calls, the call instance is given in the callback parameter as shown above. We just need to install our callback to receive call events to the call. == Call Operations == Please see [http://www.pjsip.org/python/pjsua.htm#Call Call class] documentation. == Handling Call Events == All call properties such as state, media state, remote peer information, etc. are stored as [http://www.pjsip.org/python/pjsua.htm#CallInfo CallInfo] class, which can be retrieved from the call object with using [http://www.pjsip.org/python/pjsua.htm#Call-info info()] method of the call. == Handling Call Events == Events to the call will be reported to [http://www.pjsip.org/python/pjsua.htm#CallCallback CallCallback] instance that is installed to the call object. To handle these events, you must derive a class from !CallCallback class and install the instance to the call object. === Call Disconnection === Call disconnection event is a special event since once the callback that reports this event returns, the call is no longer valid and any operations invoked to the call object will raise error exception. The call disconnection is reported in [http://www.pjsip.org/python/pjsua.htm#CallCallback-on_state on_state()] method of [http://www.pjsip.org/python/pjsua.htm#CallCallback CallCallback] and it can be detected as follows: {{{ #!python class MyCallCallback(pjsua.CallCallback): ... def on_state(self): if self.call.info().state == pjsua.CallState.DISCONNECTED: print 'This call has been disconnected' }}} == Working with Call's Media == You can only operate with the call's media (e.g. connecting the call to the sound device in the conference bridge) when the call's media is ready (or active). The changes to the call's media state is reported in [http://www.pjsip.org/python/pjsua.htm#CallCallback-on_media_state on_media_state()] callback, and the media state itself is stored as the ''media_state'' member of [http://www.pjsip.org/python/pjsua.htm#CallInfo CallInfo] class. The ''media state'' value can be one of the [http://www.pjsip.org/python/pjsua.htm#MediaState MediaState] constant. Below is a sample code to connect the call to the sound device when the call's media state is active: {{{ #!python class MyCallCallback(pjsua.CallCallback): ... # Notification when call's media state has changed. def on_media_state(self): if self.call.info().media_state == pj.MediaState.ACTIVE: # Connect the call to sound device call_slot = self.call.info().conf_slot pj.Lib.instance().conf_connect(call_slot, 0) pj.Lib.instance().conf_connect(0, call_slot) print "Media is now active" else: print "Media is inactive" }}} When the ''media_state'' has moved from active to non-active (for example when call is put on hold), there is no need to disconnect the call's connection in the bridge since the call's media will be removed automatically when it's no longer valid, and this will automatically remote all connections in the conference bridge to/from the call.