Changes between Version 4 and Version 5 of Python_SIP_Tutorial


Ignore:
Timestamp:
Jul 15, 2008 11:29:07 AM (11 years ago)
Author:
bennylp
Comment:

--

Legend:

Unmodified
Added
Removed
Modified
  • Python_SIP_Tutorial

    v4 v5  
    11 
    22= Getting Started = 
    3  
    4 The Python language binding for PJSUA-API is available in PJSIP release 0.5.10 or later. 
     3---- 
     4 
     5This tutorial replaces the older [wiki:Py_PJSUA py_pjsua] tutorial. 
    56 
    67== What is it? == 
    78 
    8 '''[/repos/browser/pjproject/trunk/pjsip-apps/src/py_pjsua py_pjsua]''' is a Python module implemented in C language to provide '''[http://www.pjsip.org/pjsip/docs/html/group__PJSUA__LIB.htm PJSUA-API]''' for [http://www.python.org Python] applications. Using '''[/repos/browser/pjproject/trunk/pjsip-apps/src/py_pjsua py_pjsua]''' enables Python application to exploit the features of PJSIP, for example: 
    9  * multiple SIP accounts 
    10  * SIP for presence (SIMPLE) and instant messaging 
    11  * multiple/unlimited calls 
    12  * call hold and transfer (attended or unattended) 
    13  * DTMF support 
    14  * conferencing with multiple/unlimited sources 
    15  * wideband and ultra-wideband audio support 
    16  * WAV files playback, playlist, and recording 
    17  * adaptive jitter buffer, silence detection, packet lost concealment, etc. 
    18  * tone generation 
    19  * multiple sound devices (planned) 
    20  * ICE support (planned) 
    21  * and so on. 
    22  
    23 == Status == 
    24  
    25 The '''py_pjsua''' module has just been released on 0.5.10 version and therefore it's expected to contain few bugs, so it's still in alpha/beta stage. 
    26  
    27 Also since the Python abstraction is created manually (rather than using automated Python abstraction generation tools), it is expected that there will be time lag between introduction of new API in PJSUA-API (the C API) and the implementation in the Python module. 
    28  
    29  
    30 == Building py_pjsua Module == 
     9This is the new Python wrapper for [http://www.pjsip.org/pjsip/docs/html/group__PJSUA__LIB.htm PJSUA API] which is available in PJSIP version 0.9.5 and later. It is much easier to use, much more Python-ish, and it deprecates the old [wiki:Py_PJSUA py_pjsua] Python module. 
     10 
     11The Python wrapper is implemented in two modules: 
     12 
     13 '''_pjsua''' module :: 
     14  This is the low-level C Python module which provides Python binding to [http://www.pjsip.org/pjsip/docs/html/group__PJSUA__LIB.htm PJSUA API]. This module is the successor of  [wiki:Py_PJSUA py_pjsua] module which now has been deprecated. 
     15 
     16 '''pjsua''' module :: 
     17  This is the higher level abstraction for [http://www.pjsip.org/pjsip/docs/html/group__PJSUA__LIB.htm PJSUA API]. It is object oriented and implemented purely on Python, on top of {{{_pjsua}}} module. 
     18 
     19Applications should use the '''pjsua''' module rather than '''_pjsua''' module, since it is easier to use and it is the module which API compatibility will be maintained between releases. 
     20 
     21You can find all the source codes in [source:pjproject/trunk/pjsip-apps/src/python pjproject/pjsip-apps/src/python] directory. 
     22 
     23 
     24== Building The Modules == 
    3125 
    3226Using Microsoft Visual Studio projects: 
    3327 * Open '''pjsip-apps.dsw''' from {{{pjsip-apps\build}}} directory. 
    34  * Select '''py_pjsua''' project. 
     28 * Select '''python_pjsua''' project as the active project. 
    3529 * Build the project 
    36  * The Python module will be placed in {{{pjsip-apps\lib}}} directory. 
     30 * The {{{_pjsua.pyd}}} Python module will be placed in {{{pjsip-apps\lib}}} directory. 
     31 * Copy {{{_pjsua.pyd}}} and {{{pjsua.py}}} from {{{pjsip-apps\src\python}}} directory to Python's site_packages directory (see Python manual for this), or alternatively add the directories where these files reside to your {{{PYTHONPATH}}} environment variable. 
    3732 
    3833Using Python build script: 
    39  * Go to {{{pjsip-apps/src/py_pjsua}}} directory. 
     34 * Go to {{{pjsip-apps/src/python}}} directory. 
    4035 * Run '''{{{'python ./setup.py build'}}}''' 
    4136 * The Python module will be placed in {{{build}}} directory inside current directory. 
    42  * Alternatively run '''{{{'python ./setup.py install'}}}''' to install the '''py_pjsua''' module to Python's site_packages directory. 
    43  
     37 * Alternatively run '''{{{'python ./setup.py install'}}}''' to install both '''_pjsua''' and '''pjsua''' modules to Python's site_packages directory. 
     38 
     39[[BR]] 
    4440 
    4541= Developing Python SIP Application = 
     42---- 
    4643 
    4744== Introduction == 
    4845 
    49 The Python API is pretty much the same like PJSUA-API - each Python function corresponds to one function in PJSUA-API, therefore one can use [http://www.pjsip.org/pjsip/docs/html/group__PJSUA__LIB.htm PJSUA-API Documentation] or [wiki:PJSIP_Tutorial PJSUA Tutorial] to learn about the Python API. 
    50  
    51 To highlight the similarities between PJSUA-API and the py_pjsua API, below are some sample names: 
    52  
    53 {{{ 
    54          PJSUA-API:                       py_pjsua API: 
    55  
    56   #include <pjsua-lib/pjsua.h>  ==>   import py_pjsua 
    57  
    58   pjsua_create()                ==>   py_pjsua.create() 
    59   pjsua_init()                  ==>   py_pjsua.init() 
    60    
    61   pjsua_call_make_call()        ==>   py_pjsua.call_make_call() 
    62 }}} 
    63  
    64  
    65  
    66  
    67 == Sample Application == 
    68  
    69 Please see [/repos/browser/pjproject/trunk/pjsip-apps/src/py_pjsua/pjsua_app.py pjsua_app.py] for a sample/simple Python application. 
    70  
    71  
    72 == Documentation == 
    73  
    74 The documentation for the Python module is integrated with '''[http://www.pjsip.org/pjsip/docs/html/group__PJSUA__LIB.htm PJSUA-API Documentation]'''. Please follow the step by step on how to use the API there, as well as specific instructions to use each PJSUA feature. 
    75  
     46The pjsua module only contains few classes so it should be straightforward to use. 
     47 
     48=== Error Handling === 
     49 
     50By convention, we use exceptions as means to report error. Operations which yields error will raise [http://www.pjsip.org/python/pjsua.htm#Error pjsua.Error] exception. 
     51 
     52 
     53=== Lib Class === 
     54 
     55The [http://www.pjsip.org/python/pjsua.htm#Lib Lib] class provides the base API's to communicate with PJSUA-API and to create objects (such as [http://www.pjsip.org/python/pjsua.htm#Account Account] and [http://www.pjsip.org/python/pjsua.htm#Transport Transport]). 
     56 
     57==== Initializing the Library ==== 
     58 
     59Instantiate the library: 
     60 
     61 {{{ 
     62#!python 
     63 
     64import pjsua as pj 
     65 
     66lib = pj.Lib() 
     67 
     68 }}} 
     69 
     70then initialize and start the library.  
     71 
     72 {{{ 
     73#!python 
     74 
     75try: 
     76    lib.init() 
     77    lib.start() 
     78 
     79except pj.Error, e: 
     80    print "Error initializing library:", e 
     81 }}} 
     82 
     83Both the {{{init()}}} and {{{start()}}} methods above may be given additional parameters. Please see [http://www.pjsip.org/python/pjsua.htm#Lib Lib] class reference manual for more information. 
     84 
     85 
     86=== Transport === 
     87 
     88Application needs to create one or more [http://www.pjsip.org/python/pjsua.htm#Transport Transport] objects before it can send or receive SIP messages: 
     89 
     90 {{{ 
     91#!python 
     92 
     93try: 
     94    udp = lib.create_transport(pj.TransportType.UDP) 
     95 
     96except pj.Error, e: 
     97    print "Error creating transport:", e 
     98 }}} 
     99 
     100 
     101=== Accounts === 
     102 
     103Application must create at least one [http://www.pjsip.org/python/pjsua.htm#Account Account] before it can send and receive SIP messages. An account specifies the '''From:''' URI, so it's needed before you can send SIP messages. 
     104 
     105There are two types of accounts in pjsua: 
     106 * real account: this is an account that can register to a SIP server 
     107 * transport account: this corresponds to one [http://www.pjsip.org/python/pjsua.htm#Transport Transport]. So for example if we have created UDP transport which listens to {{{192.168.0.1:5080}}}, the transport account will have URI: "{{{sip:192.168.0.1:5080}}}" (rather than, say, "{{{sip:user@domain}}}"). 
     108 
     109There can be more than one accounts in an application. 
     110 
     111==== Creating Accounts ==== 
     112 
     113To create transport account: 
     114 
     115 {{{ 
     116#!python 
     117 
     118try: 
     119    acc = lib.create_account_for_transport(udp) 
     120 
     121except pj.Error, e: 
     122    print "Error creating UDP local account:", e 
     123 }}} 
     124 
     125To create a real account account, first you must configure an [http://www.pjsip.org/python/pjsua.htm#AccountConfig AccountConfig], then create the account: 
     126 
     127 {{{ 
     128#!python 
     129 
     130try: 
     131    acc_cfg = pj.AccountConfig() 
     132    acc_cfg.id = "sip:user@pjsip.org" 
     133    acc_cfg.reg_uri = "sip:pjsip.org" 
     134    acc_cfg.proxy = ["<sip:pjsip.org;lr>"] 
     135    acc_cfg.auth_cred = [pj.AuthCred("*", "user", "password")] 
     136 
     137    acc = lib.create_account(acc_cfg, True) 
     138 
     139except pj.Error, e: 
     140    print "Error creating account:", e 
     141 }}} 
     142 
     143Alternatively, for typical account config like above, we can do like this: 
     144 
     145 {{{ 
     146#!python 
     147 
     148try: 
     149    acc = lib.create_account(pj.AccountConfig("pjsip.org", "username", "password"), True) 
     150 
     151except pj.Error, e: 
     152    print "Error creating account:", e 
     153 }}} 
     154 
     155 
     156==== Getting Events from Account ==== 
     157 
     158[http://www.pjsip.org/python/pjsua.htm#Account Account] object emits events such as incoming call and registration state.  
     159 
     160To capture events from [http://www.pjsip.org/python/pjsua.htm#Account Account], first you need to derive your account callback class from [http://www.pjsip.org/python/pjsua.htm#AccountCallback AccountCallback] class and implement the relevant callback methods: 
     161 
     162 {{{ 
     163#!python 
     164 
     165class MyAccountCallback(pj.AccountCallback): 
     166    def __init__(self, account): 
     167        pj.AccountCallback.__init__(self, account) 
     168 
     169    def on_reg_state(self): 
     170        print "Account", self.account.info().uri, 
     171        print "registration status is", self.account.info().reg_reason 
     172 
     173    def on_incoming_call(self, call): 
     174        print "Incoming call from", call.info().remote_uri 
     175        call.answer(200) 
     176 }}} 
     177 
     178(Note: we've touched the [http://www.pjsip.org/python/pjsua.htm#Call Call] object a little bit above, that will be explained later). 
     179 
     180Then install the callback to [http://www.pjsip.org/python/pjsua.htm#Account Account] object: 
     181 
     182 {{{ 
     183#!python 
     184 
     185   acc_cb = MyAccountCallback(acc) 
     186   acc.set_callback(acc_cb) 
     187 }}} 
     188 
     189 
     190==== Account Sample Application ==== 
     191 
     192For a complete account sample application (including registration), please see source:pjproject/trunk/pjsip-apps/src/python/samples/registration.py 
     193 
     194 
     195=== Calls === 
     196 
     197==== Creating Calls ==== 
     198 
     199Incoming call events are reported via [http://www.pjsip.org/python/pjsua.htm#AccountCallback AccountCallback]'s {{{on_incoming_call()}}} callback as shown above. 
     200 
     201To make outgoing call: 
     202 
     203 {{{ 
     204#!python 
     205 
     206   call = acc.make_call("sip:buddy@pjsip.org") 
     207 }}} 
     208 
     209Note that as with all PJSIP operations, the {{{make_call()}}} function is asynchronous; it will not block until the call is connected, but rather it will return immediately as soon as the initial INVITE request is sent. Application is then informed about the call completion via [http://www.pjsip.org/python/pjsua.htm#CallCallback CallCallback] object (see below). 
     210 
     211==== Getting Events from Call ==== 
     212 
     213To retrieve events from a call, derive a class from [http://www.pjsip.org/python/pjsua.htm#CallCallback CallCallback] class and implement the methods that you want to be notified about. Normally at the very least you'd want to implement {{{on_state()}}} and {{{on_media_state()}}} methods: 
     214 
     215 {{{ 
     216#!python 
     217 
     218class MyCallCallback(pj.CallCallback): 
     219    def __init__(self, call): 
     220        pj.CallCallback.__init__(self, call) 
     221 
     222    def on_state(self): 
     223        print "Call with", self.call.info().remote_uri, 
     224        print "is", self.call.info().state_text 
     225 
     226    def on_media_state(self): 
     227        if self.call.info().media_state == pj.MediaState.ACTIVE: 
     228            # Connect the call to sound device 
     229            call_slot = self.call.info().conf_slot 
     230            pj.Lib.instance().conf_connect(call_slot, 0) 
     231            pj.Lib.instance().conf_connect(0, call_slot) 
     232            print "Media is now active" 
     233        else: 
     234            print "Media is inactive" 
     235 
     236 }}} 
     237 
     238Then install your callback to the call object: 
     239 
     240 {{{ 
     241#!python 
     242 
     243  call_cb = MyCallCallback(call) 
     244  call.set_callback(call_cb) 
     245 }}} 
     246 
     247 
     248==== Call Sample Application ==== 
     249 
     250For a complete call sample application, please see source:pjproject/trunk/pjsip-apps/src/python/samples/call.py 
     251