Changeset 4762 for pjproject


Ignore:
Timestamp:
Feb 24, 2014 11:00:15 AM (10 years ago)
Author:
bennylp
Message:

More re #1715: doxygen integration into the book

Location:
pjproject/trunk/doc/pjsip-book
Files:
1 added
19 edited

Legend:

Unmodified
Added
Removed
  • pjproject/trunk/doc/pjsip-book

    • Property svn:ignore set to
      xml
  • pjproject/trunk/doc/pjsip-book/Doxyfile

    r4704 r4762  
    649649# with spaces. 
    650650 
    651 INPUT                  = ../../pjsip/include/pjsua2/media.hpp 
     651INPUT                  = ../../pjsip/include/pjsua2 
    652652 
    653653# This tag can be used to specify the character encoding of the source files 
  • pjproject/trunk/doc/pjsip-book/Makefile

    r4704 r4762  
    4646        -rm -rf html 
    4747 
    48 xml:    Doxyfile 
     48xml:    Doxyfile ../../pjsip/include/pjsua2 
    4949        doxygen 
    5050 
  • pjproject/trunk/doc/pjsip-book/_build

    • Property svn:ignore set to
      *
  • pjproject/trunk/doc/pjsip-book/account.rst

    r4704 r4762  
    1  
    21 
    32Accounts 
    43========= 
    5 â€‹Accounts provide identity (or identities) of the user who is currently using the application. An account has one SIP Uniform Resource Identifier (URI) associated with it. In SIP terms, the identity is used as the From header in outgoing requests. 
    6  
    7 Account may or may not have client registration associated with it. An account is also associated with route set and some authentication credentials, which are used when sending SIP request messages using the account. An account also has presence online status, which will be reported to remote peer when they subscribe to the account's presence, or which is published to a presence server if presence publication is enabled for the account. 
     4Accounts provide identity (or identities) of the user who is currently using the application. An account has one SIP Uniform Resource Identifier (URI) associated with it. In SIP terms, this URI acts as Address of Record (AOR) of the person and is used as the From header in outgoing requests. 
     5 
     6Account may or may not have client registration associated with it. An account is also associated with route set and some authentication credentials, which are used when sending SIP request messages using the account. An account also has presence status, which will be reported to remote peer when they subscribe to the account's presence, or which is published to a presence server if presence publication is enabled for the account. 
    87 
    98At least one account MUST be created in the application, since any outgoing requests require an account context. If no user association is required, application can create a userless account by calling Account.create(). A userless account identifies local endpoint instead of a particular user, and it corresponds to a particular transport ID. 
    109 
    11 Also one account must be set as the default account, which will be used as the account identity when pjsua fails to match the request with any accounts using the stricter matching rules. 
     10Also one account must be set as the default account, which will be used as the account identity when pjsua fails to match incoming request with any accounts using the stricter matching rules. 
    1211 
    1312Subclassing the Account class 
    1413--------------------------------- 
    15 To use the Account class, normally application SHOULD create its own subclass, such as:: 
     14To use the Account class, normally application SHOULD create its own subclass, in order to receive notifications for the account. For example: 
     15 
     16.. code-block:: c++ 
    1617 
    1718    class MyAccount : public Account 
     
    2627            cout << (ai.regIsActive? "*** Register: code=" : "*** Unregister: code=") 
    2728                 << prm.code << endl; 
    28  
    2929        } 
    3030     
     
    3232        { 
    3333            Call *call = new MyCall(*this, iprm.callId); 
    34             // Delete the call, which will also hangup the call 
     34 
     35            // Just hangup for now 
     36            CallOpParam op; 
     37            op.statusCode = PJSIP_SC_DECLINE; 
     38            call->hangup(op); 
     39             
     40            // And delete the call 
    3541            delete call; 
    3642        } 
     
    5460Creating Userless Accounts 
    5561-------------------------- 
    56 A userless account identifies a particular SIP endpoint rather than a particular user. Some other SIP softphones may call this peer-to-peer mode, which means that we are calling another computer via its address rather than calling a particular user ID. 
    57  
    58 So for example, we might identify ourselves as "sip:192.168.0.15" (a userless account) rather than, say, "sip:bennylp@pjsip.org". 
    59  
    60 In pjsua, a userless account corresponds to a particular transport. Creating userless account is very simple, all we need is the transport ID which is returned by ​Endpoint.transportCreate() method as explained in previous chapter. 
    61  
    62 Here's a snippet:: 
     62A userless account identifies a particular SIP endpoint rather than a particular user. Some other SIP softphones may call this peer-to-peer mode, which means that we are calling another computer via its address rather than calling a particular user ID. For example, we might identify ourselves as "sip:192.168.0.15" (a userless account) rather than, say, "sip:alice@pjsip.org". 
     63 
     64In the lower layer PJSUA-LIB API, a userless account is associated with a SIP transport, and is created with ``pjsua_acc_add_local()`` API. This concept has been deprecated in PJSUA2, and rather, a userless account is a "normal" account with a userless ID URI (e.g. "sip:192.168.0.15") and without registration. Thus creating a userless account is exactly the same as creating "normal" account. 
     65 
     66 
     67Creating Account 
     68---------------- 
     69We need to configure AccountConfig and call Account.create() to create the account. At the very minimum, pjsua only requires the account's ID, which is an URI to identify the account (or in SIP terms, it's called Address of Record/AOR). Here's a snippet: 
     70 
     71.. code-block:: c++ 
    6372 
    6473    AccountConfig acc_cfg; 
    65     acc_cfg.sipConfig.transportId = tid; 
     74    acc_cfg.idUri = "sip:test1@pjsip.org"; 
     75 
    6676    MyAccount *acc = new MyAccount; 
    6777    try { 
    6878        acc->create(acc_cfg); 
    6979    } catch(Error& err) { 
    70         cout << "Account creation error: " << err.reason << endl; 
     80        cout << "Account creation error: " << err.info() << endl; 
    7181    } 
    7282 
    73 Once the account is created, you can use the instance as a normal account. More will be explained later. 
    74  
    75 Accounts created this way will have its URI derived from the transport address. For example, if the transport address is "192.168.0.15:5080", then the account's URI for UDP transport will be "sip:192.168.0.15:5080", or "sip:192.168.0.15:5080;transport=tcp" for TCP transport. 
    76  
    77 Creating Account 
    78 ---------------- 
    79 For the "normal" account, we need to configure ​AccountConfig and call ​Account.create() to create the account. 
    80  
    81 At the very minimum, pjsua only requires the account's ID, which is an URI to identify the account (or in SIP terms, it's called Address of Record/AOR). Here's a snippet:: 
     83The account created above doesn't do anything except to provide identity in the "From:" header for outgoing requests. The account will not register to SIP server or anything. 
     84 
     85Typically you will want the account to authenticate and register to your SIP server so that you can receive incoming calls. To do that you will need to configure some more settings in your AccountConfig, something like this: 
     86 
     87.. code-block:: c++ 
    8288 
    8389    AccountConfig acc_cfg; 
    8490    acc_cfg.idUri = "sip:test1@pjsip.org"; 
     91    acc_cfg.regConfig.registrarUri = "sip:pjsip.org"; 
     92    acc_cfg.sipConfig.authCreds.push_back( AuthCredInfo("digest", "*", "test1", 0, "secret1") ); 
     93 
    8594    MyAccount *acc = new MyAccount; 
    8695    try { 
    8796        acc->create(acc_cfg); 
    8897    } catch(Error& err) { 
    89         cout << "Account creation error: " << err.reason << endl; 
    90     } 
    91  
    92 The account created above doesn't do anything except to provide identity in the "From:" header for outgoing requests. The account will not register to SIP server or anything. 
    93  
    94 Typically you will want the account to authenticate and register to your SIP server so that you can receive incoming calls. To do that you will need to configure some more settings in your ​AccountConfig, something like this:: 
    95  
    96     AccountConfig acc_cfg; 
    97     acc_cfg.idUri = "sip:test1@pjsip.org"; 
    98     acc_cfg.regConfig.registrarUri = "sip:pjsip.org"; 
    99     acc_cfg.sipConfig.authCreds.push_back( AuthCredInfo("digest", "*", "test1", 0, "test1") ); 
    100     MyAccount *acc = new MyAccount; 
    101     try { 
    102         acc->create(acc_cfg); 
    103     } catch(Error& err) { 
    104         cout << "Account creation error: " << err.reason << endl; 
     98        cout << "Account creation error: " << err.info() << endl; 
    10599    } 
    106100 
    107101Account Configurations 
    108102----------------------- 
    109 There are many more settings that can be specified in ​AccountConfig, like: 
     103There are many more settings that can be specified in AccountConfig, like: 
    110104 
    111105- AccountRegConfig, to specify registration settings, such as registrar server and retry interval. 
     
    118112- AccountVideoConfig, to specify video settings, such as default capture and render device. 
    119113 
    120 Please see ​AccountConfig reference documentation for more info. 
     114Please see AccountConfig reference documentation for more info. 
    121115 
    122116Account Operations 
    123117-------------------------------------- 
    124 Some of the operations to the ​Account object: 
    125  
    126 - add buddy objects 
    127 - set account's presence online status 
    128 - stop/start SIP registration 
    129  
    130 Please see the reference documentation for Account for more info. Calls, presence, and buddy list will be explained in later sections. 
    131  
    132  
     118Some of the operations to the Account object: 
     119 
     120- manage registration 
     121- manage buddies/contacts 
     122- manage presence online status 
     123 
     124Please see the reference documentation for Account for more info. Calls, presence, and buddy will be explained in later chapters. 
     125 
     126 
     127Class Reference 
     128--------------- 
     129Account 
     130+++++++ 
     131.. doxygenclass:: pj::Account 
     132        :path: xml 
     133        :members: 
     134 
     135AccountInfo 
     136+++++++++++ 
     137.. doxygenstruct:: pj::AccountInfo 
     138        :path: xml 
     139 
     140Account Settings 
     141++++++++++++++++ 
     142AccountConfig 
     143~~~~~~~~~~~~~ 
     144.. doxygenstruct:: pj::AccountConfig 
     145        :path: xml 
     146 
     147AccoutRegConfig 
     148~~~~~~~~~~~~~~~ 
     149.. doxygenstruct:: pj::AccountRegConfig 
     150        :path: xml 
     151 
     152AccountSipConfig 
     153~~~~~~~~~~~~~~~~ 
     154.. doxygenstruct:: pj::AccountSipConfig 
     155        :path: xml 
     156 
     157AccountCallConfig 
     158~~~~~~~~~~~~~~~~~ 
     159.. doxygenstruct:: pj::AccountCallConfig 
     160        :path: xml 
     161 
     162AccountPresConfig 
     163~~~~~~~~~~~~~~~~~ 
     164.. doxygenstruct:: pj::AccountPresConfig 
     165        :path: xml 
     166 
     167AccountMwiConfig 
     168~~~~~~~~~~~~~~~~ 
     169.. doxygenstruct:: pj::AccountMwiConfig 
     170        :path: xml 
     171 
     172AccountNatConfig 
     173~~~~~~~~~~~~~~~~ 
     174.. doxygenstruct:: pj::AccountNatConfig 
     175        :path: xml 
     176 
     177AccountMediaConfig 
     178~~~~~~~~~~~~~~~~~~ 
     179.. doxygenstruct:: pj::AccountMediaConfig 
     180        :path: xml 
     181 
     182AccountVideoConfig 
     183~~~~~~~~~~~~~~~~~~ 
     184.. doxygenstruct:: pj::AccountVideoConfig 
     185        :path: xml 
     186 
     187 
     188Callback Parameters 
     189+++++++++++++++++++ 
     190.. doxygenstruct:: pj::OnIncomingCallParam 
     191        :path: xml 
     192 
     193.. doxygenstruct:: pj::OnRegStartedParam 
     194        :path: xml 
     195 
     196.. doxygenstruct:: pj::OnRegStateParam 
     197        :path: xml 
     198 
     199.. doxygenstruct:: pj::OnIncomingSubscribeParam 
     200        :path: xml 
     201 
     202.. doxygenstruct:: pj::OnInstantMessageParam 
     203        :path: xml 
     204 
     205.. doxygenstruct:: pj::OnInstantMessageStatusParam 
     206        :path: xml 
     207 
     208.. doxygenstruct:: pj::OnTypingIndicationParam 
     209        :path: xml 
     210 
     211.. doxygenstruct:: pj::OnMwiInfoParam 
     212        :path: xml 
     213 
     214.. doxygenstruct:: pj::PresNotifyParam 
     215        :path: xml 
     216 
     217Other 
     218+++++ 
     219.. doxygenclass:: pj::FindBuddyMatch 
     220        :path: xml 
     221        :members: 
     222 
  • pjproject/trunk/doc/pjsip-book/call.rst

    r4704 r4762  
    1  
    21 
    32Calls 
    43===== 
    5 Calls are represented by ​Call class. 
     4Calls are represented by Call class. 
    65 
    76Subclassing the Call Class 
    87------------------------------------ 
    9 To use the Call class, normally application SHOULD create its own subclass, such as:: 
     8To use the Call class, normally application SHOULD create its own subclass, such as: 
     9 
     10.. code-block:: c++ 
    1011 
    1112    class MyCall : public Call 
     
    3031Making Outgoing Calls 
    3132-------------------------------------- 
    32 Making outgoing call is simple, just invoke ​makeCall() method of the Call 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:: 
     33Making outgoing call is simple, just invoke makeCall() method of the Call object. Assuming you have the Account object as acc variable and destination URI string in dest_uri, you can initiate outgoing call with the snippet below: 
     34 
     35.. code-block:: c++ 
    3336 
    3437    Call *call = new MyCall(*acc); 
     
    3740        call->makeCall(dest_uri, prm); 
    3841    } catch(Error& err) { 
    39     } 
    40  
    41 The snippet above creates a Call object and initiates outgoing call to dst_uri using the default call settings. Subsequent operations to the call can use the method in the ​call instance, and events to the call will be reported to the callback. More on the callback will be explained a bit later. 
     42        cout << err.info() << endl; 
     43    } 
     44 
     45The snippet above creates a Call object and initiates outgoing call to dest_uri using the default call settings. Subsequent operations to the call can use the method in the call instance, and events to the call will be reported to the callback. More on the callback will be explained a bit later. 
    4246 
    4347Receiving Incoming Calls 
    4448-------------------------------------- 
    45 Incoming calls are reported as ​onIncomingCall() of the ​Account class. You must derive a class from the Account class to handle incoming calls. 
    46  
    47 Below is a sample code of the callback implementation:: 
     49Incoming calls are reported as onIncomingCall() of the Account class. You must derive a class from the Account class to handle incoming calls. 
     50 
     51Below is a sample code of the callback implementation: 
     52 
     53.. code-block:: c++ 
    4854 
    4955    void MyAccount::onIncomingCall(OnIncomingCallParam &iprm) 
     
    5157        Call *call = new MyCall(*this, iprm.callId); 
    5258        CallOpParam prm; 
    53         prm.statusCode = (pjsip_status_code)200; 
     59        prm.statusCode = PJSIP_SC_OK; 
    5460        call->answer(prm); 
    5561    } 
    5662 
    57 For incoming calls, the call instance is created in the callback parameter as shown above. Application should make sure to store the call instance during the lifetime of the call (that is until the call is disconnected). 
     63For incoming calls, the call instance is created in the callback function as shown above. Application should make sure to store the call instance during the lifetime of the call (that is until the call is disconnected). 
    5864 
    5965Call Properties 
     66---------------- 
     67All call properties such as state, media state, remote peer information, etc. are stored as CallInfo class, which can be retrieved from the call object with using getInfo() method of the Call. 
     68 
     69Call Disconnection 
    6070------------------- 
    61 All call properties such as state, media state, remote peer information, etc. are stored as ​CallInfo class, which can be retrieved from the call object with using getInfo() method of the Call. 
    62  
    63 Call Disconnection 
    64 -------------------------------------- 
    6571Call 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. Thus, it is recommended to delete the call object inside the callback. 
    6672 
    67 The call disconnection is reported in ​onCallState() method of ​Call and it can be detected as follows:: 
     73The call disconnection is reported in onCallState() method of Call and it can be detected as follows: 
     74 
     75.. code-block:: c++ 
    6876 
    6977    void MyCall::onCallState(OnCallStateParam &prm) 
     
    7886Working with Call's Audio Media 
    7987------------------------------------------------- 
    80 You can only operate with the call's audio media (e.g. connecting the call to the sound device in the conference bridge) when the call's audio media is ready (or active). The changes to the call's media state is reported in ​onCallMediaState() callback, and if the call’s audio media is ready (or active) the function getMedia() will return a valid audio media. 
    81  
    82 Below is a sample code to connect the call to the sound device when the media is active:: 
     88You can only operate with the call's audio media (e.g. connecting the call to the sound device in the conference bridge) when the call's audio media is ready (or active). The changes to the call's media state is reported in onCallMediaState() callback, and if the calls audio media is ready (or active) the function Call.getMedia() will return a valid audio media. 
     89 
     90Below is a sample code to connect the call to the sound device when the media is active: 
     91 
     92.. code-block:: c++ 
    8393 
    8494    void MyCall::onCallMediaState(OnCallMediaStateParam &prm) 
    8595    { 
    8696        CallInfo ci = getInfo(); 
    87         // Iterate all medias 
     97        // Iterate all the call medias 
    8898        for (unsigned i = 0; i < ci.media.size(); i++) { 
    89             if (getMedia(i)) { // Check if the media is valid 
    90                 AudioMedia *aud_med = getMedia(i); 
     99            if (ci.media[i].type==PJMEDIA_TYPE_AUDIO && getMedia(i)) { 
     100                AudioMedia *aud_med = (AudioMedia *)getMedia(i); 
     101 
    91102                // Connect the call audio media to sound device 
    92                 aud_med->startTransmit(); 
    93                 ->startTransmit(*aud_med); 
     103                AudDevManager& mgr = Endpoint::instance().audDevManager(); 
     104                aud_med->startTransmit(mgr.getPlaybackDevMedia()); 
     105                mgr.getCaptureDevMedia().startTransmit(*aud_med); 
    94106            } 
    95107        } 
     
    99111 
    100112Call Operations 
    101 -------------------------------------- 
    102 Some of the operations to the Call object, such as making outgoing call, answering, holding, sending re-INVITE, etc. Please see the reference documentation of Call for more info. 
    103  
     113------------------- 
     114You can invoke operations to the Call object, such as hanging up, putting the call on hold, sending re-INVITE, etc. Please see the reference documentation of Call for more info. 
     115 
     116Instant Messaging(IM) 
     117--------------------- 
     118You can send IM within a call using Call.sendInstantMessage(). The transmission status of outgoing instant messages is reported in Call.onInstantMessageStatus() callback method. 
     119 
     120In addition to sending instant messages, you can also send typing indication using Call.sendTypingIndication(). 
     121 
     122Incoming IM and typing indication received within a call will be reported in the callback functions Call.onInstantMessage() and Call.onTypingIndication(). 
     123 
     124Alternatively, you can send IM and typing indication outside a call by using Buddy.sendInstantMessage() and Buddy.sendTypingIndication(). For more information, please see Presence documentation. 
     125 
     126 
     127Class Reference 
     128--------------- 
     129Call 
     130++++ 
     131.. doxygenclass:: pj::Call 
     132        :path: xml 
     133        :members: 
     134 
     135Settings 
     136++++++++ 
     137.. doxygenstruct:: pj::CallSetting 
     138        :path: xml 
     139         
     140 
     141Info and Statistics 
     142+++++++++++++++++++ 
     143.. doxygenstruct:: pj::CallInfo 
     144        :path: xml 
     145         
     146.. doxygenstruct:: pj::CallMediaInfo 
     147        :path: xml 
     148         
     149.. doxygenstruct:: pj::StreamInfo 
     150        :path: xml 
     151         
     152.. doxygenstruct:: pj::StreamStat 
     153        :path: xml 
     154 
     155.. doxygenstruct:: pj::JbufState 
     156        :path: xml 
     157 
     158.. doxygenstruct:: pj::RtcpStat 
     159        :path: xml 
     160 
     161.. doxygenstruct:: pj::RtcpStreamStat 
     162        :path: xml 
     163 
     164.. doxygenstruct:: pj::MathStat 
     165        :path: xml 
     166 
     167.. doxygenstruct:: pj::MediaTransportInfo 
     168        :path: xml 
     169 
     170 
     171Callback Parameters 
     172+++++++++++++++++++ 
     173.. doxygenstruct:: pj::OnCallStateParam 
     174        :path: xml 
     175 
     176.. doxygenstruct:: pj::OnCallTsxStateParam 
     177        :path: xml 
     178 
     179.. doxygenstruct:: pj::OnCallMediaStateParam 
     180        :path: xml 
     181 
     182.. doxygenstruct:: pj::OnCallSdpCreatedParam 
     183        :path: xml 
     184 
     185.. doxygenstruct:: pj::OnStreamCreatedParam 
     186        :path: xml 
     187 
     188.. doxygenstruct:: pj::OnStreamDestroyedParam 
     189        :path: xml 
     190 
     191.. doxygenstruct:: pj::OnDtmfDigitParam 
     192        :path: xml 
     193 
     194.. doxygenstruct:: pj::OnCallTransferRequestParam 
     195        :path: xml 
     196 
     197.. doxygenstruct:: pj::OnCallTransferStatusParam 
     198        :path: xml 
     199 
     200.. doxygenstruct:: pj::OnCallReplaceRequestParam 
     201        :path: xml 
     202 
     203.. doxygenstruct:: pj::OnCallReplacedParam 
     204        :path: xml 
     205 
     206.. doxygenstruct:: pj::OnCallRxOfferParam 
     207        :path: xml 
     208 
     209.. doxygenstruct:: pj::OnCallRedirectedParam 
     210        :path: xml 
     211 
     212.. doxygenstruct:: pj::OnCallMediaEventParam 
     213        :path: xml 
     214 
     215.. doxygenstruct:: pj::OnCallMediaTransportStateParam 
     216        :path: xml 
     217 
     218.. doxygenstruct:: pj::OnCreateMediaTransportParam 
     219        :path: xml 
     220 
     221.. doxygenstruct:: pj::CallOpParam 
     222        :path: xml 
     223 
     224.. doxygenstruct:: pj::CallSendRequestParam 
     225        :path: xml 
     226 
     227.. doxygenstruct:: pj::CallVidSetStreamParam 
     228        :path: xml 
     229 
     230Other 
     231+++++ 
     232.. doxygenstruct:: pj::MediaEvent 
     233        :path: xml 
     234 
     235.. doxygenstruct:: pj::MediaFmtChangedEvent 
     236        :path: xml 
     237 
     238.. doxygenstruct:: pj::SdpSession 
     239        :path: xml 
     240 
     241.. doxygenstruct:: pj::RtcpSdes 
     242        :path: xml 
     243 
     244 
  • pjproject/trunk/doc/pjsip-book/consider.rst

    r4704 r4762  
    11 
    22 
    3  
    4 Development Considerations 
    5 ************************** 
    6  
    7 Let's review various aspects that you need to consider when developing your application. 
    8  
    9  
    10 Target Platforms 
    11 ================ 
    12 Platform selection will affect all aspects of development, and here we will cover  considerations for each platforms that we support. 
     3Development Guidelines and Considerations 
     4***************************************** 
     5 
     6Development Guidelines 
     7====================== 
     8 
     9Preparation 
     10------------ 
     11* **Essential:** Familiarise yourself with SIP. You don't need to be an expert, but SIP knowledge is essential.  
     12* Check out our features in `Datasheet <http://trac.pjsip.org/repos/wiki/PJSIP-Datasheet>`_. Other features may be provided by our `community <http://trac.pjsip.org/repos/wiki/Projects_Using_PJSIP>`_. 
     13* All PJSIP documentation is indexed in our `Trac site <http://trac.pjsip.org/repos>`_. 
     14 
     15 
     16Development 
     17------------- 
     18* **Essential:** Interactive debugging capability is essential during development 
     19* Start with default settings in `<pj/config_site_sample.h>`. 
     20 
     21Coding Style 
     22------------- 
     23**Essential:** set your editor to use 8 characters tab size in order to see PJSIP source correctly. 
     24 
     25These below are PJSIP coding style. You don't need to follow it unless you are submitting patches to PJSIP: 
     26 
     27* indentation uses tabs and spaces. Tab size is 8 characters, indentation 4. 
     28* all public API in header file must be documented in Doxygen format. 
     29* other than that, we mostly just use `K & R style <http://en.wikipedia.org/wiki/1_true_brace_style#K.26R_style>`_, which is the only correct style anyway. 
     30 
     31 
     32Deployment 
     33----------- 
     34* **Essential:** Logging is essential when troubleshooting any problems. The application MUST be equipped with logging capability. Enable PJSIP log at level 5. 
     35 
     36 
     37Platform Consideration 
     38======================== 
     39Platform selection is usually driven by business motives. The selection will affect all aspects of development, and here we will cover  considerations for each platforms that we support. 
    1340 
    1441Windows Desktop 
  • pjproject/trunk/doc/pjsip-book/endpoint.rst

    r4704 r4762  
    1  
    21 
    32Endpoint 
    43************ 
    5 The ​Endpoint class is a singleton class, and application MUST create one and at most one of this class instance before it can do anything else. This class is the core class of PJSUA2, and it provides the following functions: 
     4The Endpoint class is a singleton class, and application MUST create one and at most one of this class instance before it can do anything else, and similarly, once this class is destroyed, application must NOT call any library API. This class is the core class of PJSUA2, and it provides the following functions: 
    65 
    76- Starting up and shutting down 
    87- Customization of configurations, such as core UA (User Agent) SIP configuration, media configuration, and logging configuration 
    98 
    10 This section will describe the functions above. 
     9This chapter will describe the functions above. 
    1110 
    1211To use the Endpoint class, normally application does not need to subclass it unless: 
    1312 
    14 - application wants to implement/override Endpoint’s callback methods to get the events such as transport state change or NAT detection completion, or 
     13- application wants to implement/override Endpoints callback methods to get the events such as transport state change or NAT detection completion, or 
    1514- application schedules a timer using Endpoint.utilTimerSchedule() API. In this case, application needs to implement the onTimer() callback to get the notification when the timer expires. 
    1615 
     
    2524Creating the Library 
    2625---------------------- 
    27 Create the library by calling its libCreate() method:: 
     26Create the library by calling its libCreate() method: 
     27 
     28.. code-block:: c++ 
    2829 
    2930    try { 
    3031        ep->libCreate(); 
    3132    } catch(Error& err) { 
    32         cout << "Startup error: " << err.reason << endl; 
     33        cout << "Startup error: " << err.info() << endl; 
    3334    } 
    3435 
     
    4142 
    4243- UAConfig, to specify core SIP user agent settings. 
    43 - MediaConfig, to specify various media settings, including ICE and TURN. 
     44- MediaConfig, to specify various media *global* settings 
    4445- LogConfig, to customize logging settings. 
    4546 
    46 To customize the settings, create instance of EpConfig class and specify them during the endpoint initialization (will be explained more later), for example:: 
     47Note that some settings can be further specified on per account basis, in the AccountConfig. 
     48 
     49To customize the settings, create instance of EpConfig class and specify them during the endpoint initialization (will be explained more later), for example: 
     50 
     51.. code-block:: c++ 
    4752 
    4853    EpConfig ep_cfg; 
     
    5156    ep_cfg.mediaConfig.sndClockRate = 16000; 
    5257 
    53 Next, you can initialize the library by calling libInit():: 
     58Next, you can initialize the library by calling libInit(): 
     59 
     60.. code-block:: c++ 
    5461 
    5562    try { 
     
    5865        ep->libInit(ep_cfg); 
    5966    } catch(Error& err) { 
    60         cout << "Initialization error: " << err.reason << endl; 
     67        cout << "Initialization error: " << err.info() << endl; 
    6168    } 
    6269 
     
    6572Creating One or More Transports 
    6673-------------------------------------------------- 
    67 Application needs to create one or more ​transports before it can send or receive SIP messages:: 
     74Application needs to create one or more transports before it can send or receive SIP messages: 
     75 
     76.. code-block:: c++ 
    6877 
    6978    try { 
     
    7281        TransportId tid = ep->transportCreate(PJSIP_TRANSPORT_UDP, tcfg); 
    7382    } catch(Error& err) { 
    74         cout << "Transport creation error: " << err.reason << endl; 
     83        cout << "Transport creation error: " << err.info() << endl; 
    7584    } 
    7685 
    77 The transportCreate() method returns the newly created ​Transport ID and it takes the transport type and ​TransportConfig object to customize the transport settings like bound address and listening port number. Without this, by default the transport will be bound to INADDR_ANY and any available port. 
     86The transportCreate() method returns the newly created Transport ID and it takes the transport type and TransportConfig object to customize the transport settings like bound address and listening port number. Without this, by default the transport will be bound to INADDR_ANY and any available port. 
    7887 
    79 There is no real use of the ​Transport ID, except to create userless account (with ​Account.create(), as will be explained later), and perhaps to display the list of transports to user if the application wants it. 
     88There is no real use of the Transport ID, except to create userless account (with Account.create(), as will be explained later), and perhaps to display the list of transports to user if the application wants it. 
    8089 
    8190Starting the Library 
    8291-------------------- 
    83 Now we're ready to start the library. We need to start the library to finalize the initialization phase, e.g. to complete the initial STUN address resolution, initialize/start the sound device, etc. To start the library, call ​libStart() method:: 
     92Now we're ready to start the library. We need to start the library to finalize the initialization phase, e.g. to complete the initial STUN address resolution, initialize/start the sound device, etc. To start the library, call libStart() method: 
     93 
     94.. code-block:: c++ 
    8495 
    8596    try { 
    8697        ep->libStart(); 
    8798    } catch(Error& err) { 
    88         cout << "Startup error: " << err.reason << endl; 
     99        cout << "Startup error: " << err.info() << endl; 
    89100    } 
    90101 
    91102Shutting Down the Library 
    92103-------------------------------------- 
    93 Once the application exits, the library needs to be shutdown so that resources can be released back to the operating system. This is done by deleting the Endpoint instance, which will internally call ​libDestroy():: 
     104Once the application exits, the library needs to be shutdown so that resources can be released back to the operating system. Although this can be done by deleting the Endpoint instance, which will internally call libDestroy(), it is better to call it manually because on Java or Python there are problems with garbage collection as explained earlier: 
    94105 
     106.. code-block:: c++ 
     107 
     108    ep->libDestroy(); 
    95109    delete ep; 
    96110 
     111 
     112Class Reference 
     113--------------- 
     114The Endpoint 
     115++++++++++++ 
     116.. doxygenclass:: pj::Endpoint 
     117        :path: xml 
     118        :members: 
     119 
     120Endpoint Configurations 
     121+++++++++++++++++++++++ 
     122Endpoint 
     123~~~~~~~~ 
     124.. doxygenstruct:: pj::EpConfig 
     125        :path: xml 
     126 
     127Media 
     128~~~~~ 
     129.. doxygenstruct:: pj::MediaConfig 
     130        :path: xml 
     131 
     132Logging 
     133~~~~~~~ 
     134.. doxygenstruct:: pj::LogConfig 
     135        :path: xml 
     136 
     137.. doxygenclass:: pj::LogWriter 
     138        :path: xml 
     139        :members: 
     140 
     141.. doxygenstruct:: pj::LogEntry 
     142        :path: xml 
     143 
     144User Agent 
     145~~~~~~~~~~ 
     146.. doxygenstruct:: pj::UaConfig 
     147        :path: xml 
     148 
     149 
     150Callback Parameters 
     151+++++++++++++++++++ 
     152.. doxygenstruct:: pj::OnNatDetectionCompleteParam 
     153        :path: xml 
     154 
     155.. doxygenstruct:: pj::OnNatCheckStunServersCompleteParam 
     156        :path: xml 
     157 
     158.. doxygenstruct:: pj::OnTimerParam 
     159        :path: xml 
     160 
     161.. doxygenstruct:: pj::OnTransportStateParam 
     162        :path: xml 
     163 
     164.. doxygenstruct:: pj::OnSelectAccountParam 
     165        :path: xml 
     166 
     167 
     168Other 
     169+++++ 
     170.. doxygenstruct:: pj::PendingJob 
     171        :path: xml 
     172 
  • pjproject/trunk/doc/pjsip-book/fetch_trac.py

    r4704 r4762  
    11import urllib2 
    22import sys 
     3import unicodedata 
    34 
    45def fetch_rst(url): 
     
    78                 
    89        fd = urllib2.urlopen(req, timeout=30) 
    9         body = fd.read()                 
     10        body = fd.read() 
     11        body = body.replace("\r\n", "\n") 
     12 
     13        body = body.decode('utf8', 'ignore').encode('ascii', 'ignore') 
    1014 
    1115        pos = body.find("{{{") 
     
    7983        pages = process_index('index') 
    8084        for page in pages: 
     85                #if not 'endpoint' in page: 
     86                #       continue 
    8187                url = url_format % (page) 
    8288                fetch_rst(url) 
  • pjproject/trunk/doc/pjsip-book/index.rst

    r4704 r4762  
    1  
    21.. The PJSIP Book documentation master file, created by 
    32   sphinx-quickstart on Sat Nov 30 06:36:26 2013. 
     
    54   contain the root `toctree` directive. 
    65 
    7 Welcome to The PJSIP Book's documentation! 
     6The PJSIP Book 
    87========================================== 
    98 
     
    1211.. toctree:: 
    1312   :maxdepth: 2 
     13   :numbered: 1 
    1414 
    1515   intro 
    1616   consider 
    1717   intro_pjsua2 
     18   getting_started 
    1819   endpoint 
    1920   account 
  • pjproject/trunk/doc/pjsip-book/intro.rst

    r4704 r4762  
    1  
    21 
    32Introduction to PJSUA2 
     
    54This documentation is intended for developers looking to develop Session Initiation Protocol (SIP) based client application. Some knowledge on SIP is definitely required, and of course some programming experience. Prior knowledge of PJSUA C API is not needed, although it will probably help. 
    65 
    7 This PJSUA2 module provides very high level API to do SIP calls, presence, and instant messaging, as well as handling media and NAT traversal. Knowledge of SIP protocol details (such as the grammar, transaction, dialog, and whatnot) are not required, however you should know how SIP works in general and particularly how to configure SIP clients to, e.g. register to a SIP provider, specify SIP URI to make call to, and so on, to use the module. 
     6This PJSUA2 module provides very high level C++ API to do SIP calls, presence, and instant messaging, as well as handling media and NAT traversal. Knowledge of SIP protocol details (such as the grammar, transaction, dialog, and whatnot) are not required, however you should know how SIP works in general and particularly how to configure SIP clients to, e.g. register to a SIP provider, specify SIP URI to make call to, and so on, to use the module. 
    87 
    98Getting Started with PJSIP 
    109============================== 
    11 To begin using PJSIP 
    12 http://trac.pjsip.org/repos/wiki/Getting-Started 
     10Check `PJSIP's Features List`_ to make sure that it has the features that you require. 
     11 
     12.. _`PJSIP's Features List`: http://trac.pjsip.org/repos/wiki/PJSIP-Datasheet 
     13 
     14Then to begin using PJSIP, the `Getting Started Guide`_ contains instructions to acquire and build PJSIP on various platforms that we support. 
     15 
     16.. _`Getting Started Guide`: http://trac.pjsip.org/repos/wiki/Getting-Started  
    1317 
    1418PJSIP Info and Documentation 
    1519================================ 
    16 PJSIP General Wiki: 
    17 http://trac.pjsip.org/repos/wiki 
     20To get other relevant info and documentations about PJSIP, you can visit: 
    1821 
    19 PJSIP FAQ: 
    20 http://trac.pjsip.org/repos/wiki/FAQ 
     22- `PJSIP General Wiki`_ 
     23- `PJSIP FAQ`_ 
     24- `PJSIP Reference Manual`_ - please see Reference Manual section 
    2125 
    22 PJSIP Reference Manual: 
    23 http://trac.pjsip.org/repos/wiki - Reference Manual 
     26.. _`PJSIP General Wiki`: http://trac.pjsip.org/repos/wiki 
     27.. _`PJSIP FAQ`: http://trac.pjsip.org/repos/wiki/FAQ 
     28.. _`PJSIP Reference Manual`: http://trac.pjsip.org/repos/wiki 
    2429 
    2530Building PJSUA2 
    2631================= 
    27 PJSUA2 API declaration can be found in pjproject/pjsip/include/pjsua2 while the source codes are located in pjproject/pjsip/src/pjsua2. It will be automatically built when you compile PJSIP. 
     32PJSUA2 API declaration can be found in ``pjsip/include/pjsua2`` while the source codes are located in ``pjsip/src/pjsua2``. It will be automatically built when you compile PJSIP. 
    2833 
    2934PJSUA2 Language Binding Support 
    3035=================================== 
    31 Optional if you want to: 
    32 â€‹SWIG (minimum version 2.0.5) 
     36The PJSUA2 API is also available for other programming languages via SWIG binding, such as Java and Python. 
    3337 
  • pjproject/trunk/doc/pjsip-book/intro_pjsua2.rst

    r4704 r4762  
    1  
    21PJSUA2-High Level API 
    32****************************** 
    4 PJSUA2 is an object-oriented abstraction above ​PJSUA API. It provides high level API for constructing ​Session Initiation Protocol (SIP) multimedia user agent applications (a.k.a Voice over IP/VoIP softphones). It wraps together the signaling, media, and NAT traversal functionality into easy to use call control API, account management, buddy list management, presence, and instant messaging, along with multimedia features such as local conferencing, file streaming, local playback, and voice recording, and powerful NAT traversal techniques utilizing ​STUN, ​TURN, and ​ICE. 
     3PJSUA2 is an object-oriented abstraction above PJSUA API. It provides high level API for constructing Session Initiation Protocol (SIP) multimedia user agent applications (a.k.a Voice over IP/VoIP softphones). It wraps together the signaling, media, and NAT traversal functionality into easy to use call control API, account management, buddy list management, presence, and instant messaging, along with multimedia features such as local conferencing, file streaming, local playback, and voice recording, and powerful NAT traversal techniques utilizing STUN, TURN, and ICE. 
    54 
    65PJSUA2 is implemented on top of PJSUA-LIB API. The SIP and media features and object modelling follows what PJSUA-LIB provides (for example, we still have accounts, call, buddy, and so on), but the API to access them is different. These features will be described later in this chapter. PJSUA2 is a C++ library, which you can find under ``pjsip`` directory in the PJSIP distribution. The C++ library can be used by native C++ applications directly. But PJSUA2 is not just a C++ library. From the beginning, it has been designed to be accessible from high level non-native languages such as Java and Python. This is achieved by SWIG binding. And thanks to SWIG, binding to other languages can be added relatively easily in the future. 
     6 
     7 
     8Building PJSUA2 
     9====================== 
     10The PJSUA2 C++ library will be built by default by PJSIP build system. 
     11 
     12The SWIG modules for Python and Java are built by invoking ``make`` manually from ``pjsip-apps/src/swig`` directory. 
    713 
    814 
     
    2127Media 
    2228---------- 
    23 This class represents a media element which is capable to either produce media or takes media. 
     29This is an abstract base class that represents a media element which is capable to either produce media or takes media. It is then subclassed into ``AudioMedia``, which is then subclassed into concrete classes such as ``AudioMediaPlayer`` and ``AudioMediaRecorder``. 
    2430 
    2531Call 
    2632------ 
    27 This class is used to manipulate calls, such as to answer the call, hangup the call, put the call on hold, transfer the call, etc. 
     33This class represents an ongoing call (or speaking technically, an INVITE session) and can be used to manipulate it, such as to answer the call, hangup the call, put the call on hold, transfer the call, etc. 
    2834 
    2935Buddy 
     
    3541Class Usage Patterns 
    3642--------------------- 
    37 With the methods of the main classes above, you will be able to invoke various operations to the object quite easily. But how can we get events/notifications from these classes? Each of the main classes above (except Media) will get their events in the callback methods. So to handle these events, just derive a class from the corresponding class (​Endpoint, Call, Account, or Buddy) and implement/override the relevant method (depending on which event you want to handle). More will be explained in later sections. 
     43With the methods of the main classes above, you will be able to invoke various operations to the object quite easily. But how can we get events/notifications from these classes? Each of the main classes above (except Media) will get their events in the callback methods. So to handle these events, just derive a class from the corresponding class (Endpoint, Call, Account, or Buddy) and implement/override the relevant method (depending on which event you want to handle). More will be explained in later sections. 
     44 
     45Error Handling 
     46--------------- 
     47We use exceptions as means to report error, as this would make the program flows more naturally. Operations which yield error will raise Error exception. If you prefer to display the error in more structured manner, the Error class has several members to explain the error, such as the operation name that raised the error, the error code, and the error message itself. 
     48 
     49Asynchronous Operations 
     50------------------------- 
     51If you have developed applications with PJSIP, you'll know about this already. In PJSIP, all operations that involve sending and receiving SIP messages are asynchronous, meaning that the function that invokes the operation will complete immediately, and you will be given the completion status as callbacks. 
     52 
     53Take a look for example the makeCall() method of the Call class. This function is used to initiate outgoing call to a destination. When this function returns successfully, it does not mean that the call has been established, but rather it means that the call has been initiated successfully. You will be given the report of the call progress and/or completion in the onCallState() callback method of Call class. 
     54 
     55Threading 
     56---------- 
     57For platforms that require polling, the PJSUA2 module provides its own worker thread to poll PJSIP, so it is not necessary to instantiate own your polling thread. Having said that the application should be prepared to have the callbacks called by different thread than the main thread. The PJSUA2 module itself is thread safe. 
     58 
     59Problems with Garbage Collection 
     60-------------------------------- 
     61Garbage collection (GC) exists in Java and Python (and other languages, but we don't support those for now), and there are some problems with it when it comes to PJSUA2 usage: 
     62 
     63- it delays the destruction of objects (including PJSUA2 objects), causing the code in object's destructor to be executed out of order 
     64- the GC operation may run on different thread not previously registered to PJLIB, causing assertion 
     65 
     66Due to problems above, application '''MUST immediately destroy PJSUA2 objects using object's delete() method (in Java)''', instead of relying on the GC to clean up the object. 
     67 
     68For example, to delete an Account, it's **NOT** enough to just let it go out of scope. Application MUST delete it manually like this (in Java): 
     69 
     70.. code-block:: c++ 
     71 
     72    acc.delete(); 
     73 
     74 
     75 
    3876 
    3977Objects Persistence 
    4078--------------------- 
    41 PJSUA2 includes PersistentObject class to provide functionality to read/write data from/to a document (string or file). The data can be simple data types such as boolean, number, string, and string arrays, or a user defined object. Currently the implementation supports reading and writing from/to JSON document, but the framework allows application to extend the API to support other document formats. 
     79PJSUA2 includes PersistentObject class to provide functionality to read/write data from/to a document (string or file). The data can be simple data types such as boolean, number, string, and string arrays, or a user defined object. Currently the implementation supports reading and writing from/to JSON document ([http://tools.ietf.org/html/rfc4627 RFC 4627]), but the framework allows application to extend the API to support other document formats. 
    4280 
    43 As such, classes which inherit from PersistentObject, such as EpConfig (endpoint configuration), AccountConfig (account configuration), and BuddyConfig (buddy configuration) can be loaded/saved from/to a file. Here’s an example to save a config to a file: 
     81As such, classes which inherit from PersistentObject, such as EpConfig (endpoint configuration), AccountConfig (account configuration), and BuddyConfig (buddy configuration) can be loaded/saved from/to a file. Heres an example to save a config to a file: 
    4482 
    4583.. code-block:: c++ 
     
    5088    epCfg.uaConfig.userAgent = "Just JSON Test"; 
    5189    jDoc.writeObject(epCfg); 
    52     jDoc.saveFile(“jsontest.js”); 
     90    jDoc.saveFile("jsontest.js"); 
    5391 
    5492To load from the file: 
     
    6199    jDoc.readObject(epCfg); 
    62100 
    63 Error Handling 
    64 --------------- 
    65 We use exceptions as means to report error, as this would make the program flows more naturally. Operations which yield error will raise ​Error exception. If you prefer to display the error in more structured manner, the ​Error class has several members to explain the error, such as the operation name that raised the error, the error code, and the error message itself. 
    66101 
    67 Asynchronous Operations 
    68 ------------------------- 
    69 If you have developed applications with PJSIP, you'll know about this already. In PJSIP, all operations that involve sending and receiving SIP messages are asynchronous, meaning that the function that invokes the operation will complete immediately, and you will be given the completion status as callbacks. 
    70  
    71 Take a look for example the ​makeCall() method of the Call class. This function is used to initiate outgoing call to a destination. When this function returns successfully, it does not mean that the call has been established, but rather it means that the call has been initiated successfully. You will be given the report of the call progress and/or completion in the ​onCallState() callback method of ​Call class. 
    72  
    73 Threading 
    74 ---------- 
    75 For platforms that require polling, the PJSUA2 module provides its own worker thread to poll PJSIP, so it is not necessary to instantiate own your polling thread. Having said that the application should be prepared to have the callbacks called by different thread than the main thread. The PJSUA2 module should be thread safe. 
    76  
    77  
    78 Using in C++ Application 
    79 ======================== 
    80 As mentioned in previous chapter, A C++ application can use *pjsua2* natively, while at the same time still has access to the lower level objects and the ability to extend the libraries if it needs to. Using the API will be exactly the same as the API reference that is written in this book. 
    81  
    82 Here is a sample complete C++ application to give you some idea about the API. The snippet below initializes the library and creates an account that registers to our pjsip.org SIP server. 
    83  
    84 .. code-block:: c++ 
    85      
    86   #include <pjsua2.hpp> 
    87   #include <iostream> 
    88    
    89   using namespace pj; 
    90    
    91   // Subclass to extend the Account and get notifications etc. 
    92   class MyAccount : public Account { 
    93   public: 
    94       virtual void onRegState(OnRegStateParam &prm) { 
    95           AccountInfo ai = getInfo(); 
    96           std::cout << (ai.regIsActive? "*** Register:" : "*** Unregister:") 
    97                     << " code=" << prm.code << std::endl; 
    98       } 
    99   }; 
    100  
    101   int main() 
    102   { 
    103       Endpoint ep; 
    104        
    105       ep.libCreate(); 
    106        
    107       // Initialize endpoint 
    108       EpConfig ep_cfg; 
    109       ep_cfg.uaConfig.userAgent = "pjsua2-hello"; 
    110       ep.libInit( ep_cfg ); 
    111        
    112       // Create SIP transport. Error handling sample is shown 
    113       TransportConfig tcfg; 
    114       tcfg.port = 5060; 
    115       try { 
    116           ep.transportCreate(PJSIP_TRANSPORT_UDP, tcfg); 
    117       } catch (Error &err) { 
    118           std::cout << err.info() << std::endl; 
    119           return 1; 
    120       } 
    121        
    122       // Start the library (worker threads etc) 
    123       ep.libStart(); 
    124       std::cout << "*** PJSUA2 STARTED ***" << std::endl; 
    125        
    126       // Configure an AccountConfig 
    127       AccountConfig acfg; 
    128       acfg.idUri = "sip:test@pjsip.org"; 
    129       acfg.regConfig.registrarUri = "sip:pjsip.org"; 
    130       AuthCredInfo cred("digest", "*", "test", 0, "secret"); 
    131       acfg.sipConfig.authCreds.push_back( cred ); 
    132        
    133       // Create the account 
    134       MyAccount *acc = new MyAccount; 
    135       acc->create(acfg); 
    136        
    137       // Here we don't have anything else to do.. 
    138       pj_thread_sleep(10000); 
    139        
    140       // Delete the account. This will unregister from server 
    141       delete acc; 
    142        
    143       // This will implicitly shutdown the library 
    144       return 0; 
    145   } 
    146  
    147  
    148 Using in Python Application 
    149 =========================== 
    150  
    151  
    152  
    153 Using in Java Application 
    154 ========================= 
    155  
    156  
    157  
    158  
  • pjproject/trunk/doc/pjsip-book/media.rst

    r4704 r4762  
    1  
    21 
    32Media 
    43===== 
    5 Media objects are objects that are capable to either produce media or takes media. In ​PJMEDIA terms, these objects are implemented as media ports (​pjmedia_port). 
     4Media objects are objects that are capable to either produce media or takes media. 
    65 
    76An important subclass of Media is AudioMedia which represents audio media. There are several type of audio media objects supported in PJSUA2: 
    87 
    9 - CallAudioMedia, to transmit and receive audio to/from remote person. 
     8- Capture device's AudioMedia, to capture audio from the sound device. 
     9- Playback device's AudioMedia, to play audio to the sound device. 
     10- Call's AudioMedia, to transmit and receive audio to/from remote person. 
    1011- AudioMediaPlayer, to play WAV file(s). 
    1112- AudioMediaRecorder, to record audio to a WAV file. 
     
    1516The Audio Conference Bridge 
    1617---------------------------- 
    17 The conference bridge provides a simple but yet powerful concept to manage audio flow between the audio medias. The principle is very simple, that is you connect audio source to audio destination, and the bridge will make the audio flows from the source to destination, and that's it. If more than one sources are transmitting to the same destination, then the audio from the sources will be mixed. If one source is transmitting to more than one destinations, the bridge will take care of duplicating the audio from the source to the multiple destinations. 
    18  
    19 In ​PJSUA2, all audio media objects are plugged-in to the central conference bridge for easier manipulation. A plugged-in audio media will not be connected to anything, so media will not flow from/to any objects. An audio media source can start/stop the transmission to a destination by using the API AudioMedia.startTransmit() / AudioMedia.stopTransmit(). 
    20  
    21 An audio media object plugged-in to the conference bridge will be given a port ID number that identifies the object in the bridge. Application can use the API AudioMedia.getPortId() to retrieve the port ID. Normally, application should not need to worry about the port ID (as all will be taken care of by the bridge) unless application want to create its own custom audio media. 
     18The conference bridge provides a simple but yet powerful concept to manage audio flow between the audio medias. The principle is very simple, that is you connect audio source to audio destination, and the bridge will make the audio flows from the source to destination, and that's it. If more than one sources are transmitting to the same destination, then the audio from the sources will be mixed. If one source is transmitting to more than one destinations, the bridge will take care of duplicating the audio from the source to the multiple destinations. The bridge will even take care medias with different clock rates and ptime. 
     19 
     20In PJSUA2, all audio media objects are plugged-in to the central conference bridge for easier manipulation. At first, a plugged-in audio media will not be connected to anything, so media will not flow from/to any objects. An audio media source can start/stop the transmission to a destination by using the API AudioMedia.startTransmit() / AudioMedia.stopTransmit(). 
     21 
     22An audio media object plugged-in to the conference bridge will be given a port ID number that identifies the object in the bridge. Application can use the API AudioMedia.getPortId() to retrieve the port ID. Normally, application should not need to worry about the conference bridge and its port ID (as all will be taken care of by the Media class) unless application want to create its own custom audio media. 
    2223 
    2324Playing a WAV File 
    2425++++++++++++++++++ 
    25 To playback the WAV file to the speaker, just start the transmission of the WAV playback object to the sound device:: 
     26To playback the WAV file to the sound device, just start the transmission of the WAV playback object to the sound device's playback media: 
     27 
     28.. code-block:: c++ 
    2629 
    2730    AudioMediaPlayer player; 
    28     try { 
    29         player.createPlayer(“file.wav”); 
    30         player.startTransmit(); 
    31     } catch(Error& err) { 
    32     } 
    33  
    34 Once you're done with the playback, just stop the transmission n to stop the playback:: 
    35  
    36     try { 
    37         player.stopTransmit(); 
    38     } catch(Error& err) { 
    39     } 
     31    AudioMedia& play_med = Endpoint::instance().audDevManager().getPlaybackDevMedia(); 
     32    try { 
     33        player.createPlayer("file.wav"); 
     34        player.startTransmit(play_med); 
     35    } catch(Error& err) { 
     36    } 
     37 
     38By default, the WAV file will be played in a loop. To disable the loop, specify ``PJMEDIA_FILE_NO_LOOP`` when creating the player: 
     39 
     40.. code-block:: c++ 
     41 
     42        player.createPlayer("file.wav", PJMEDIA_FILE_NO_LOOP); 
     43 
     44Without looping, silence will be played once the playback has reached the end of the WAV file. 
     45 
     46Once you're done with the playback, just stop the transmission to stop the playback: 
     47 
     48.. code-block:: c++ 
     49 
     50    try { 
     51        player.stopTransmit(play_med); 
     52    } catch(Error& err) { 
     53    } 
     54 
     55Resuming the transmission after the playback is stopped will resume playback from the last play position. Use ``player.setPos()`` to set playback position to a desired location. 
     56 
    4057 
    4158Recording to WAV File 
    4259+++++++++++++++++++++ 
    43 Or if you want to record the microphone to the WAV file, simply do this:: 
     60Or if you want to record the audio from the sound device to the WAV file, simply do this: 
     61 
     62.. code-block:: c++ 
    4463 
    4564    AudioMediaRecorder recorder; 
    46     try { 
    47         recorder.createRecorder(“file.wav”); 
    48         .startTransmit(recorder); 
    49     } catch(Error& err) { 
    50     } 
    51  
    52 And the media will flow from the sound device to the WAV record file. As usual, to stop or pause recording, just stop the transmission:: 
    53  
    54     try { 
    55        .stopTransmit(recorder); 
    56     } catch(Error& err) { 
    57     } 
    58  
    59 (Note that stopping the transmission to the WAV recorder as above does not close the WAV file, and you can resume recording by connecting a source to the WAV recorder again. You cannot playback the recorded WAV file before you close it.) 
     65    AudioMedia& cap_med = Endpoint::instance().audDevManager().getCaptureDevMedia(); 
     66    try { 
     67        recorder.createRecorder("file.wav"); 
     68        cap_med.startTransmit(recorder); 
     69    } catch(Error& err) { 
     70    } 
     71 
     72And the media will flow from the sound device to the WAV record file. As usual, to stop or pause recording, just stop the transmission: 
     73 
     74.. code-block:: c++ 
     75 
     76    try { 
     77       cap_med.stopTransmit(recorder); 
     78    } catch(Error& err) { 
     79    } 
     80 
     81Note that stopping the transmission to the WAV recorder as above does not close the WAV file, and you can resume recording by connecting a source to the WAV recorder again. You cannot playback the recorded WAV file before you close it. To close the WAV recorder, simply delete it: 
     82 
     83.. code-block:: c++ 
     84 
     85    delete recorder; 
     86 
     87 
     88Local Audio Loopback 
     89++++++++++++++++++++ 
     90A useful test to check whether the local sound device (capture and playback device) is working properly is by transmitting the audio from the capture device directly to the playback device (i.e. local loopback). You can do this by: 
     91 
     92.. code-block:: c++ 
     93 
     94    cap_med.startTransmit(play_med); 
     95 
    6096 
    6197Looping Audio 
    6298+++++++++++++ 
    63 If you want, you can loop the audio of a media object to itself (i.e. the audio received from the object will be transmitted to itself). For example, you can loop the audio of the sound device with:: 
    64  
    65     .startTransmit(); 
    66  
    67 With the above connection, audio received from the microphone will be played back to the speaker. This is useful to test whether the microphone and speaker are working properly. 
    68  
    69 You can loop-back audio from any objects, as long as the object has bidirectional media. That means you can loop the call's audio media, so that audio received from the remote person will be transmitted back to her/him. But you can't loop the WAV player or recorder since these objects can only play or record and not both. 
     99If you want, you can loop the audio of an audio media object to itself (i.e. the audio received from the object will be transmitted to itself). You can loop-back audio from any objects, as long as the object has bidirectional media. That means you can loop the call's audio media, so that audio received from the remote person will be transmitted back to her/him. But you can't loop the WAV player or recorder since these objects can only play or record and not both. 
    70100 
    71101Normal Call 
    72102+++++++++++ 
    73103 
    74 A single call can has several audio medias. Application can retrieve the audio media by using the API Call.getMedia():: 
    75  
    76     AudioMedia *aud_med = (AudioMedia *)call.getMedia(0); 
    77  
    78 In the above, we assume that the audio media is located in index 0. Of course on a real application, we should iterate the medias to find the correct media index by checking whether the media returned by getMedia() is valid. More on this will be explained later in the Call section. Then for a normal call, we would want to establish bidirectional audio with the remote person, which can be done easily by connecting the sound device and the call audio media and vice versa:: 
    79  
    80     // This will connect the sound device/mic to the call audio media 
    81     ->startTransmit(*aud_med); 
    82  
    83     // And this will connect the call audio media to the sound device/speaker 
    84     aud_med->startTransmit(); 
     104A single call can have more than one media (for example, audio and video). Application can retrieve the audio media by using the API Call.getMedia(). Then for a normal call, we would want to establish bidirectional audio with the remote person, which can be done easily by connecting the sound device and the call audio media and vice versa: 
     105 
     106.. code-block:: c++ 
     107 
     108    CallInfo ci = call.getInfo(); 
     109    AudioMedia *aud_med = NULL; 
     110 
     111    // Find out which media index is the audio 
     112    for (unsigned i=0; i<ci.media.size(); ++i) { 
     113        if (ci.media[i].type == PJMEDIA_TYPE_AUDIO) { 
     114            aud_med = (AudioMedia *)call.getMedia(i); 
     115            break; 
     116        } 
     117    } 
     118 
     119    if (aud_med) { 
     120        // This will connect the sound device/mic to the call audio media 
     121        cap_med.startTransmit(*aud_med); 
     122 
     123        // And this will connect the call audio media to the sound device/speaker 
     124        aud_med->startTransmit(play_med); 
     125    } 
     126 
     127 
    85128 
    86129Second Call 
    87130+++++++++++ 
    88 Suppose we want to talk with two remote parties at the same time. Since we already have bidirectional media connection with one party, we just need to add bidirectional connection with the other party using the code below:: 
    89  
    90     AudioMedia *aud_med2 = (AudioMedia *)call2.getMedia(0); 
    91     ->startTransmit(*aud_med2); 
    92     aud_med2->startTransmit(); 
     131Suppose we want to talk with two remote parties at the same time. Since we already have bidirectional media connection with one party, we just need to add bidirectional connection with the other party using the code below: 
     132 
     133.. code-block:: c++ 
     134 
     135    AudioMedia *aud_med2 = (AudioMedia *)call2.getMedia(aud_idx); 
     136    if (aud_med2) { 
     137        cap_med->startTransmit(*aud_med2); 
     138        aud_med2->startTransmit(play_med); 
     139    } 
    93140 
    94141Now we can talk to both parties at the same time, and we will hear audio from either party. But at this stage, the remote parties can't talk or hear each other (i.e. we're not in full conference mode yet). 
     
    96143Conference Call 
    97144+++++++++++++++ 
    98 To enable both parties talk to each other, just establish bidirectional media between them:: 
     145To enable both parties talk to each other, just establish bidirectional media between them: 
     146 
     147.. code-block:: c++ 
    99148 
    100149    aud_med->startTransmit(*aud_med2); 
     
    106155++++++++++++++++++++++++ 
    107156 
    108 While doing the conference, it perfectly makes sense to want to record the conference to a WAV file, and all we need to do is to connect the microphone and both calls to the WAV recorder:: 
    109  
    110     ->startTransmit(recorder); 
     157While doing the conference, it perfectly makes sense to want to record the conference to a WAV file, and all we need to do is to connect the microphone and both calls to the WAV recorder: 
     158 
     159.. code-block:: c++ 
     160 
     161    cap_med.startTransmit(recorder); 
    111162    aud_med->startTransmit(recorder); 
    112163    aud_med2->startTransmit(recorder); 
    113164 
     165 
     166Audio Device Management 
     167----------------------- 
     168Please see `Audio Device Framework <#auddev>`_ below. 
     169 
     170 
     171Class Reference 
     172--------------- 
     173Media Framework 
     174+++++++++++++++ 
     175Classes 
     176~~~~~~~ 
     177.. doxygenclass:: pj::Media 
     178        :path: xml 
     179        :members: 
     180 
     181.. doxygenclass:: pj::AudioMedia 
     182        :path: xml 
     183        :members: 
     184 
     185.. doxygenclass:: pj::AudioMediaPlayer 
     186        :path: xml 
     187        :members: 
     188 
     189.. doxygenclass:: pj::AudioMediaRecorder 
     190        :path: xml 
     191        :members: 
     192 
     193Formats and Info 
     194~~~~~~~~~~~~~~~~ 
     195.. doxygenstruct:: pj::MediaFormat 
     196        :path: xml 
     197 
     198.. doxygenstruct:: pj::MediaFormatAudio 
     199        :path: xml 
     200 
     201.. doxygenstruct:: pj::MediaFormatVideo 
     202        :path: xml 
     203 
     204.. doxygenstruct:: pj::ConfPortInfo 
     205        :path: xml 
     206 
     207Audio Device Framework 
     208++++++++++++++++++++++ 
     209Device Manager 
     210~~~~~~~~~~~~~~ 
     211.. _auddev: 
     212.. doxygenclass:: pj::AudDevManager 
     213        :path: xml 
     214        :members: 
     215 
     216Device Info 
     217~~~~~~~~~~~ 
     218.. doxygenstruct:: pj::AudioDevInfo 
     219        :path: xml 
     220 
  • pjproject/trunk/doc/pjsip-book/media_quality.rst

    r4704 r4762  
    1  
    21 
    32Media Quality 
     
    65Audio Quality 
    76============= 
     7If you experience any problem with the audio quality, you may want to try the steps below: 
     8 
     91. Follow the guide: `Test the sound device using pjsystest`_. 
     102. Identify the sound problem and troubleshoot it using the steps described in: `Checking for sound problems`_. 
     11 
     12.. _`Checking for sound problems`: http://trac.pjsip.org/repos/wiki/sound-problems 
     13.. _`Test the sound device using pjsystest`: http://trac.pjsip.org/repos/wiki/Testing_Audio_Device_with_pjsystest 
     14 
     15It is probably easier to do the testing using lower level API such as PJSUA since we already have a built-in pjsua sample app located in pjsip-apps/bin to do the testing. However, you can also do the testing in your application using PJSUA2 API such as local audio loopback, recording to WAV file as explained in the Media chapter previously. 
    816 
    917Video Quality 
    1018============= 
     19For video quality problems, the steps are as follows: 
    1120 
     211. For lack of video, check account's AccountVideoConfig, especially the fields autoShowIncoming and autoTransmitOutgoing. More about the video API is explained in `Video Users Guide`_. 
     222. Check local video preview using PJSUA API as described in `Video Users Guide-Video Preview API`_. 
     233. Since video requires a larger bandwidth, we need to check for network impairments as described in `Checking Network Impairments`_. The document is for troubleshooting audio problem but it applies for video as well. 
     244. Check the CPU utilization. If the CPU utilization is too high, you can try a different (less CPU-intensive) video codec or reduce the resolution/fps. A general guide on how to reduce CPU utilization can be found here: `FAQ-CPU utilization`_. 
     25 
     26.. _`Video Users Guide`: http://trac.pjsip.org/repos/wiki/Video_Users_Guide 
     27.. _`Video Users Guide-Video Preview API`: http://trac.pjsip.org/repos/wiki/Video_Users_Guide#VideopreviewAPI 
     28.. _`Checking Network Impairments`: http://trac.pjsip.org/repos/wiki/audio-check-packet-loss 
     29.. _`FAQ-CPU utilization`: http://trac.pjsip.org/repos/wiki/FAQ#cpu 
     30 
  • pjproject/trunk/doc/pjsip-book/network_problems.rst

    r4704 r4762  
    1  
    21 
    32Network Problems 
     
    65IP Address Change 
    76================= 
     7Please see the wiki `Handling IP Address Change`_. Note that the guide is written using PJSUA API as a reference. 
     8 
     9.. _`Handling IP Address Change`: https://trac.pjsip.org/repos/wiki/IPAddressChange 
    810 
    911Blocked/Filtered Network 
    1012======================== 
     13Please refer to the wiki `Getting Around Blocked or Filtered VoIP Network`_. 
    1114 
     15.. _`Getting Around Blocked or Filtered VoIP Network`: https://trac.pjsip.org/repos/wiki/get-around-nat-blocked-traffic-filtering 
     16 
  • pjproject/trunk/doc/pjsip-book/optimization.rst

    r4704 r4762  
    1  
    21 
    32General Configuration Optimization 
     
    98CPU Optimization 
    109================ 
     10A general guide on how to reduce CPU utilization can be found here: `FAQ-CPU utilization`_. 
    1111 
     12.. _`FAQ-CPU utilization`: http://trac.pjsip.org/repos/wiki/FAQ#cpu 
     13 
  • pjproject/trunk/doc/pjsip-book/presence.rst

    r4704 r4762  
    1  
    21 
    32Buddy (Presence) 
    43================ 
    5 This class represents a remote buddy (a person, or a SIP endpoint). 
    6 To use the Buddy class, application DOES NOT need to subclass it unless application wants to get the notifications on buddy state change. 
     4Presence feature in PJSUA2 centers around Buddy class. This class represents a remote buddy (a person, or a SIP endpoint). 
    75 
    8 Subscribe to Buddy's Presence Status 
    9 --------------------------------------------------------- 
    10 To subscribe to buddy's presence status, you need to add a buddy object, install callback to handle buddy's event, and start subscribing to buddy's presence status. The snippet below shows a sample code to achieve these:: 
     6Subclassing the Buddy class 
     7---------------------------- 
     8To use the Buddy class, normally application SHOULD create its own subclass, such as: 
    119 
    12   class MyBuddyCallback(pjsua.BuddyCallback): 
    13     def __init__(self, buddy=None): 
    14         pjsua.BuddyCallback.__init__(self, buddy) 
     10.. code-block:: c++ 
    1511 
    16     def on_state(self): 
    17         print "Buddy", self.buddy.info().uri, "is", 
    18         print self.buddy.info().online_text 
     12    class MyBuddy : public Buddy 
     13    { 
     14    public: 
     15        MyBuddy() {} 
     16        ~MyBuddy() {} 
    1917 
    20   try: 
    21     uri = '"Alice" <sip:alice@example.com>' 
    22     buddy = acc.add_buddy(uri, cb=MyBuddyCallback()) 
    23     buddy.subscribe() 
     18        virtual void onBuddyState(); 
     19    }; 
    2420 
    25   except pjsua.Error, err: 
    26     print 'Error adding buddy:', err 
     21In its subclass, application can implement the buddy callback to get the notifications on buddy state change. 
    2722 
    28 For more information please see ​Buddy class and ​BuddyCallback class reference documentation. 
     23Subscribing to Buddy's Presence Status 
     24--------------------------------------- 
     25To subscribe to buddy's presence status, you need to add a buddy object and subscribe to buddy's presence status. The snippet below shows a sample code to achieve these: 
     26 
     27.. code-block:: c++ 
     28 
     29    BuddyConfig cfg; 
     30    cfg.uri = "sip:alice@example.com"; 
     31    MyBuddy buddy; 
     32    try { 
     33        buddy.create(*acc, cfg); 
     34        buddy.subscribePresence(true); 
     35    } catch(Error& err) { 
     36    } 
     37 
     38Then you can get the buddy's presence state change inside the onBuddyState() callback: 
     39 
     40.. code-block:: c++ 
     41 
     42    void MyBuddy::onBuddyState() 
     43    { 
     44        BuddyInfo bi = getInfo(); 
     45        cout << "Buddy " << bi.uri << " is " << bi.presStatus.statusText << endl; 
     46    } 
     47 
     48For more information, please see Buddy class reference documentation. 
    2949 
    3050Responding to Presence Subscription Request 
    31  
     51------------------------------------------- 
    3252By default, incoming presence subscription to an account will be accepted automatically. You will probably want to change this behavior, for example only to automatically accept subscription if it comes from one of the buddy in the buddy list, and for anything else prompt the user if he/she wants to accept the request. 
    3353 
    34 This can be done by implementing the ​on_incoming_subscribe() method of the ​AccountCallback class. 
     54This can be done by overriding the onIncomingSubscribe() method of the Account class. Please see the documentation of this method for more info. 
    3555 
    3656Changing Account's Presence Status 
     57---------------------------------- 
     58To change account's presence status, you can use the function Account.setOnlineStatus() to set basic account's presence status (i.e. available or not available) and optionally, some extended information (e.g. busy, away, on the phone, etc), such as: 
    3759 
    38 The ​Account class provides two methods to change account's presence status: 
     60.. code-block:: c++ 
    3961 
    40 â€‹set_basic_status() can be used to set basic account's presence status (i.e. available or not available). 
    41 â€‹set_presence_status() can be used to set both the basic presence status and some extended information (e.g. busy, away, on the phone, etc.). 
    42 When the presence status is changed, the account will publish the new status to all of its presence subscriber, either with PUBLISH request or SUBSCRIBE request, or both, depending on account configuration. 
     62    try { 
     63        PresenceStatus ps; 
     64        ps.status = PJSUA_BUDDY_STATUS_ONLINE; 
     65        // Optional, set the activity and some note 
     66        ps.activity = PJRPID_ACTIVITY_BUSY; 
     67        ps.note = "On the phone"; 
     68        acc->setOnlineStatus(ps); 
     69    } catch(Error& err) { 
     70    } 
    4371 
     72When the presence status is changed, the account will publish the new status to all of its presence subscriber, either with PUBLISH request or NOTIFY request, or both, depending on account configuration. 
     73 
     74Instant Messaging(IM) 
     75--------------------- 
     76You can send IM using Buddy.sendInstantMessage(). The transmission status of outgoing instant messages is reported in Account.onInstantMessageStatus() callback method of Account class. 
     77 
     78In addition to sending instant messages, you can also send typing indication to remote buddy using Buddy.sendTypingIndication(). 
     79 
     80Incoming IM and typing indication received not within the scope of a call will be reported in the callback functions Account.onInstantMessage() and Account.onTypingIndication(). 
     81 
     82Alternatively, you can send IM and typing indication within a call by using Call.sendInstantMessage() and Call.sendTypingIndication(). For more information, please see Call documentation. 
     83 
     84 
     85Class Reference 
     86--------------- 
     87Buddy 
     88+++++ 
     89.. doxygenclass:: pj::Buddy 
     90        :path: xml 
     91        :members: 
     92 
     93Status 
     94++++++ 
     95.. doxygenstruct:: pj::PresenceStatus 
     96        :path: xml 
     97         
     98Info 
     99++++ 
     100.. doxygenstruct:: pj::BuddyInfo 
     101        :path: xml 
     102 
     103Config 
     104++++++ 
     105.. doxygenstruct:: pj::BuddyConfig 
     106        :path: xml 
     107 
     108 
  • pjproject/trunk/doc/pjsip-book/reference.rst

    r4704 r4762  
    1  
    21 
    32PJSUA2 API Reference Manuals 
  • pjproject/trunk/doc/pjsip-book/samples.rst

    r4704 r4762  
    1  
    21 
    32PJSUA2 Sample Applications 
     
    76=========== 
    87 
     8C++ 
     9----- 
     10There is a very simple C++ sample application available in ``pjsip-apps/src/samples/pjsua2_demo.cpp``. The binary will be located in ``pjsip-apps/bin/samples``. 
     11 
     12 
    913Python GUI 
    1014------------------ 
    11 It requires Python 2.7 and above. 
     15This is a rather complete Python GUI sample apps, located in ``pjsip-apps/src/pygui``. It requires Python 2.7 and above, and the Python SWIG module of course. To use the application, simply run:: 
    1216 
    13 Android & Java 
    14 ----------------------------- 
     17    python application.py 
    1518 
    16 C++ 
    17 ----------------------------- 
     19Android 
     20---------------- 
     21Please see https://trac.pjsip.org/repos/wiki/Getting-Started/Android#pjsua2 for Android sample application. 
     22 
     23Java 
     24---------------- 
     25There is a Hello World type of application located in ``pjsip-apps/src/swig/java``. This requires the Java SWIG module. After building the SWIG module, run ``make test`` from this directory to run the app. 
     26 
    1827 
    1928Miscellaneous 
    2029=================== 
    2130 
    22 How to dump call stats 
     31How to  
    2332----------------------------- 
    2433 
    25 How to 
 
    26 ----------------------------- 
    27  
Note: See TracChangeset for help on using the changeset viewer.