- Timestamp:
- Feb 24, 2014 11:00:15 AM (11 years ago)
- 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
-
Property
svn:ignore
set to
-
pjproject/trunk/doc/pjsip-book/Doxyfile
r4704 r4762 649 649 # with spaces. 650 650 651 INPUT = ../../pjsip/include/pjsua2 /media.hpp651 INPUT = ../../pjsip/include/pjsua2 652 652 653 653 # This tag can be used to specify the character encoding of the source files -
pjproject/trunk/doc/pjsip-book/Makefile
r4704 r4762 46 46 -rm -rf html 47 47 48 xml: Doxyfile 48 xml: Doxyfile ../../pjsip/include/pjsua2 49 49 doxygen 50 50 -
pjproject/trunk/doc/pjsip-book/_build
-
Property
svn:ignore
set to
*
-
Property
svn:ignore
set to
-
pjproject/trunk/doc/pjsip-book/account.rst
r4704 r4762 1 2 1 3 2 Accounts 4 3 ========= 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 identityis 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 onlinestatus, 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.4 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, this URI acts as Address of Record (AOR) of the person and is used as the From header in outgoing requests. 5 6 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 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. 8 7 9 8 At 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. 10 9 11 Also one account must be set as the default account, which will be used as the account identity when pjsua fails to match therequest with any accounts using the stricter matching rules.10 Also 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. 12 11 13 12 Subclassing the Account class 14 13 --------------------------------- 15 To use the Account class, normally application SHOULD create its own subclass, such as:: 14 To 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++ 16 17 17 18 class MyAccount : public Account … … 26 27 cout << (ai.regIsActive? "*** Register: code=" : "*** Unregister: code=") 27 28 << prm.code << endl; 28 29 29 } 30 30 … … 32 32 { 33 33 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 35 41 delete call; 36 42 } … … 54 60 Creating Userless Accounts 55 61 -------------------------- 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:: 62 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. For example, we might identify ourselves as "sip:192.168.0.15" (a userless account) rather than, say, "sip:alice@pjsip.org". 63 64 In 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 67 Creating Account 68 ---------------- 69 We 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++ 63 72 64 73 AccountConfig acc_cfg; 65 acc_cfg.sipConfig.transportId = tid; 74 acc_cfg.idUri = "sip:test1@pjsip.org"; 75 66 76 MyAccount *acc = new MyAccount; 67 77 try { 68 78 acc->create(acc_cfg); 69 79 } catch(Error& err) { 70 cout << "Account creation error: " << err. reason<< endl;80 cout << "Account creation error: " << err.info() << endl; 71 81 } 72 82 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:: 83 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. 84 85 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: 86 87 .. code-block:: c++ 82 88 83 89 AccountConfig acc_cfg; 84 90 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 85 94 MyAccount *acc = new MyAccount; 86 95 try { 87 96 acc->create(acc_cfg); 88 97 } 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; 105 99 } 106 100 107 101 Account Configurations 108 102 ----------------------- 109 There are many more settings that can be specified in âAccountConfig, like:103 There are many more settings that can be specified in AccountConfig, like: 110 104 111 105 - AccountRegConfig, to specify registration settings, such as registrar server and retry interval. … … 118 112 - AccountVideoConfig, to specify video settings, such as default capture and render device. 119 113 120 Please see âAccountConfig reference documentation for more info.114 Please see AccountConfig reference documentation for more info. 121 115 122 116 Account Operations 123 117 -------------------------------------- 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 118 Some of the operations to the Account object: 119 120 - manage registration 121 - manage buddies/contacts 122 - manage presence online status 123 124 Please see the reference documentation for Account for more info. Calls, presence, and buddy will be explained in later chapters. 125 126 127 Class Reference 128 --------------- 129 Account 130 +++++++ 131 .. doxygenclass:: pj::Account 132 :path: xml 133 :members: 134 135 AccountInfo 136 +++++++++++ 137 .. doxygenstruct:: pj::AccountInfo 138 :path: xml 139 140 Account Settings 141 ++++++++++++++++ 142 AccountConfig 143 ~~~~~~~~~~~~~ 144 .. doxygenstruct:: pj::AccountConfig 145 :path: xml 146 147 AccoutRegConfig 148 ~~~~~~~~~~~~~~~ 149 .. doxygenstruct:: pj::AccountRegConfig 150 :path: xml 151 152 AccountSipConfig 153 ~~~~~~~~~~~~~~~~ 154 .. doxygenstruct:: pj::AccountSipConfig 155 :path: xml 156 157 AccountCallConfig 158 ~~~~~~~~~~~~~~~~~ 159 .. doxygenstruct:: pj::AccountCallConfig 160 :path: xml 161 162 AccountPresConfig 163 ~~~~~~~~~~~~~~~~~ 164 .. doxygenstruct:: pj::AccountPresConfig 165 :path: xml 166 167 AccountMwiConfig 168 ~~~~~~~~~~~~~~~~ 169 .. doxygenstruct:: pj::AccountMwiConfig 170 :path: xml 171 172 AccountNatConfig 173 ~~~~~~~~~~~~~~~~ 174 .. doxygenstruct:: pj::AccountNatConfig 175 :path: xml 176 177 AccountMediaConfig 178 ~~~~~~~~~~~~~~~~~~ 179 .. doxygenstruct:: pj::AccountMediaConfig 180 :path: xml 181 182 AccountVideoConfig 183 ~~~~~~~~~~~~~~~~~~ 184 .. doxygenstruct:: pj::AccountVideoConfig 185 :path: xml 186 187 188 Callback 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 217 Other 218 +++++ 219 .. doxygenclass:: pj::FindBuddyMatch 220 :path: xml 221 :members: 222 -
pjproject/trunk/doc/pjsip-book/call.rst
r4704 r4762 1 2 1 3 2 Calls 4 3 ===== 5 Calls are represented by âCall class.4 Calls are represented by Call class. 6 5 7 6 Subclassing the Call Class 8 7 ------------------------------------ 9 To use the Call class, normally application SHOULD create its own subclass, such as:: 8 To use the Call class, normally application SHOULD create its own subclass, such as: 9 10 .. code-block:: c++ 10 11 11 12 class MyCall : public Call … … 30 31 Making Outgoing Calls 31 32 -------------------------------------- 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:: 33 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 dest_uri, you can initiate outgoing call with the snippet below: 34 35 .. code-block:: c++ 33 36 34 37 Call *call = new MyCall(*acc); … … 37 40 call->makeCall(dest_uri, prm); 38 41 } 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 45 The 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. 42 46 43 47 Receiving Incoming Calls 44 48 -------------------------------------- 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:: 49 Incoming calls are reported as onIncomingCall() of the Account class. You must derive a class from the Account class to handle incoming calls. 50 51 Below is a sample code of the callback implementation: 52 53 .. code-block:: c++ 48 54 49 55 void MyAccount::onIncomingCall(OnIncomingCallParam &iprm) … … 51 57 Call *call = new MyCall(*this, iprm.callId); 52 58 CallOpParam prm; 53 prm.statusCode = (pjsip_status_code)200;59 prm.statusCode = PJSIP_SC_OK; 54 60 call->answer(prm); 55 61 } 56 62 57 For incoming calls, the call instance is created in the callback parameteras shown above. Application should make sure to store the call instance during the lifetime of the call (that is until the call is disconnected).63 For 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). 58 64 59 65 Call Properties 66 ---------------- 67 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. 68 69 Call Disconnection 60 70 ------------------- 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 Disconnection64 --------------------------------------65 71 Call disconnection event is a special event since once the callback that reports this event returns, the call is no longer valid and any operations invoked to the call object will raise error exception. Thus, it is recommended to delete the call object inside the callback. 66 72 67 The call disconnection is reported in âonCallState() method of âCall and it can be detected as follows:: 73 The call disconnection is reported in onCallState() method of Call and it can be detected as follows: 74 75 .. code-block:: c++ 68 76 69 77 void MyCall::onCallState(OnCallStateParam &prm) … … 78 86 Working with Call's Audio Media 79 87 ------------------------------------------------- 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:: 88 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 calls audio media is ready (or active) the function Call.getMedia() will return a valid audio media. 89 90 Below is a sample code to connect the call to the sound device when the media is active: 91 92 .. code-block:: c++ 83 93 84 94 void MyCall::onCallMediaState(OnCallMediaStateParam &prm) 85 95 { 86 96 CallInfo ci = getInfo(); 87 // Iterate all medias97 // Iterate all the call medias 88 98 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 91 102 // 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); 94 106 } 95 107 } … … 99 111 100 112 Call 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 ------------------- 114 You 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 116 Instant Messaging(IM) 117 --------------------- 118 You can send IM within a call using Call.sendInstantMessage(). The transmission status of outgoing instant messages is reported in Call.onInstantMessageStatus() callback method. 119 120 In addition to sending instant messages, you can also send typing indication using Call.sendTypingIndication(). 121 122 Incoming IM and typing indication received within a call will be reported in the callback functions Call.onInstantMessage() and Call.onTypingIndication(). 123 124 Alternatively, 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 127 Class Reference 128 --------------- 129 Call 130 ++++ 131 .. doxygenclass:: pj::Call 132 :path: xml 133 :members: 134 135 Settings 136 ++++++++ 137 .. doxygenstruct:: pj::CallSetting 138 :path: xml 139 140 141 Info 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 171 Callback 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 230 Other 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 1 1 2 2 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. 3 Development Guidelines and Considerations 4 ***************************************** 5 6 Development Guidelines 7 ====================== 8 9 Preparation 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 16 Development 17 ------------- 18 * **Essential:** Interactive debugging capability is essential during development 19 * Start with default settings in `<pj/config_site_sample.h>`. 20 21 Coding Style 22 ------------- 23 **Essential:** set your editor to use 8 characters tab size in order to see PJSIP source correctly. 24 25 These 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 32 Deployment 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 37 Platform Consideration 38 ======================== 39 Platform 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. 13 40 14 41 Windows Desktop -
pjproject/trunk/doc/pjsip-book/endpoint.rst
r4704 r4762 1 2 1 3 2 Endpoint 4 3 ************ 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:4 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, 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: 6 5 7 6 - Starting up and shutting down 8 7 - Customization of configurations, such as core UA (User Agent) SIP configuration, media configuration, and logging configuration 9 8 10 This sectionwill describe the functions above.9 This chapter will describe the functions above. 11 10 12 11 To use the Endpoint class, normally application does not need to subclass it unless: 13 12 14 - application wants to implement/override Endpoint âs callback methods to get the events such as transport state change or NAT detection completion, or13 - application wants to implement/override Endpoints callback methods to get the events such as transport state change or NAT detection completion, or 15 14 - 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. 16 15 … … 25 24 Creating the Library 26 25 ---------------------- 27 Create the library by calling its libCreate() method:: 26 Create the library by calling its libCreate() method: 27 28 .. code-block:: c++ 28 29 29 30 try { 30 31 ep->libCreate(); 31 32 } catch(Error& err) { 32 cout << "Startup error: " << err. reason<< endl;33 cout << "Startup error: " << err.info() << endl; 33 34 } 34 35 … … 41 42 42 43 - 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 44 45 - LogConfig, to customize logging settings. 45 46 46 To customize the settings, create instance of EpConfig class and specify them during the endpoint initialization (will be explained more later), for example:: 47 Note that some settings can be further specified on per account basis, in the AccountConfig. 48 49 To 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++ 47 52 48 53 EpConfig ep_cfg; … … 51 56 ep_cfg.mediaConfig.sndClockRate = 16000; 52 57 53 Next, you can initialize the library by calling libInit():: 58 Next, you can initialize the library by calling libInit(): 59 60 .. code-block:: c++ 54 61 55 62 try { … … 58 65 ep->libInit(ep_cfg); 59 66 } catch(Error& err) { 60 cout << "Initialization error: " << err. reason<< endl;67 cout << "Initialization error: " << err.info() << endl; 61 68 } 62 69 … … 65 72 Creating One or More Transports 66 73 -------------------------------------------------- 67 Application needs to create one or more âtransports before it can send or receive SIP messages:: 74 Application needs to create one or more transports before it can send or receive SIP messages: 75 76 .. code-block:: c++ 68 77 69 78 try { … … 72 81 TransportId tid = ep->transportCreate(PJSIP_TRANSPORT_UDP, tcfg); 73 82 } catch(Error& err) { 74 cout << "Transport creation error: " << err. reason<< endl;83 cout << "Transport creation error: " << err.info() << endl; 75 84 } 76 85 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.86 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. 78 87 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.88 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. 80 89 81 90 Starting the Library 82 91 -------------------- 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:: 92 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: 93 94 .. code-block:: c++ 84 95 85 96 try { 86 97 ep->libStart(); 87 98 } catch(Error& err) { 88 cout << "Startup error: " << err. reason<< endl;99 cout << "Startup error: " << err.info() << endl; 89 100 } 90 101 91 102 Shutting Down the Library 92 103 -------------------------------------- 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()::104 Once 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: 94 105 106 .. code-block:: c++ 107 108 ep->libDestroy(); 95 109 delete ep; 96 110 111 112 Class Reference 113 --------------- 114 The Endpoint 115 ++++++++++++ 116 .. doxygenclass:: pj::Endpoint 117 :path: xml 118 :members: 119 120 Endpoint Configurations 121 +++++++++++++++++++++++ 122 Endpoint 123 ~~~~~~~~ 124 .. doxygenstruct:: pj::EpConfig 125 :path: xml 126 127 Media 128 ~~~~~ 129 .. doxygenstruct:: pj::MediaConfig 130 :path: xml 131 132 Logging 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 144 User Agent 145 ~~~~~~~~~~ 146 .. doxygenstruct:: pj::UaConfig 147 :path: xml 148 149 150 Callback 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 168 Other 169 +++++ 170 .. doxygenstruct:: pj::PendingJob 171 :path: xml 172 -
pjproject/trunk/doc/pjsip-book/fetch_trac.py
r4704 r4762 1 1 import urllib2 2 2 import sys 3 import unicodedata 3 4 4 5 def fetch_rst(url): … … 7 8 8 9 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') 10 14 11 15 pos = body.find("{{{") … … 79 83 pages = process_index('index') 80 84 for page in pages: 85 #if not 'endpoint' in page: 86 # continue 81 87 url = url_format % (page) 82 88 fetch_rst(url) -
pjproject/trunk/doc/pjsip-book/index.rst
r4704 r4762 1 2 1 .. The PJSIP Book documentation master file, created by 3 2 sphinx-quickstart on Sat Nov 30 06:36:26 2013. … … 5 4 contain the root `toctree` directive. 6 5 7 Welcome to The PJSIP Book's documentation! 6 The PJSIP Book 8 7 ========================================== 9 8 … … 12 11 .. toctree:: 13 12 :maxdepth: 2 13 :numbered: 1 14 14 15 15 intro 16 16 consider 17 17 intro_pjsua2 18 getting_started 18 19 endpoint 19 20 account -
pjproject/trunk/doc/pjsip-book/intro.rst
r4704 r4762 1 2 1 3 2 Introduction to PJSUA2 … … 5 4 This 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. 6 5 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.6 This 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. 8 7 9 8 Getting Started with PJSIP 10 9 ============================== 11 To begin using PJSIP 12 http://trac.pjsip.org/repos/wiki/Getting-Started 10 Check `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 14 Then 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 13 17 14 18 PJSIP Info and Documentation 15 19 ================================ 16 PJSIP General Wiki: 17 http://trac.pjsip.org/repos/wiki 20 To get other relevant info and documentations about PJSIP, you can visit: 18 21 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 21 25 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 24 29 25 30 Building PJSUA2 26 31 ================= 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.32 PJSUA2 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. 28 33 29 34 PJSUA2 Language Binding Support 30 35 =================================== 31 Optional if you want to: 32 âSWIG (minimum version 2.0.5) 36 The PJSUA2 API is also available for other programming languages via SWIG binding, such as Java and Python. 33 37 -
pjproject/trunk/doc/pjsip-book/intro_pjsua2.rst
r4704 r4762 1 2 1 PJSUA2-High Level API 3 2 ****************************** 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.3 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. 5 4 6 5 PJSUA2 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 8 Building PJSUA2 9 ====================== 10 The PJSUA2 C++ library will be built by default by PJSIP build system. 11 12 The SWIG modules for Python and Java are built by invoking ``make`` manually from ``pjsip-apps/src/swig`` directory. 7 13 8 14 … … 21 27 Media 22 28 ---------- 23 This class represents a media element which is capable to either produce media or takes media.29 This 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``. 24 30 25 31 Call 26 32 ------ 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.33 This 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. 28 34 29 35 Buddy … … 35 41 Class Usage Patterns 36 42 --------------------- 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. 43 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. 44 45 Error Handling 46 --------------- 47 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. 48 49 Asynchronous Operations 50 ------------------------- 51 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. 52 53 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. 54 55 Threading 56 ---------- 57 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 itself is thread safe. 58 59 Problems with Garbage Collection 60 -------------------------------- 61 Garbage 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 66 Due 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 68 For 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 38 76 39 77 Objects Persistence 40 78 --------------------- 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.79 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 ([http://tools.ietf.org/html/rfc4627 RFC 4627]), but the framework allows application to extend the API to support other document formats. 42 80 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:81 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. Heres an example to save a config to a file: 44 82 45 83 .. code-block:: c++ … … 50 88 epCfg.uaConfig.userAgent = "Just JSON Test"; 51 89 jDoc.writeObject(epCfg); 52 jDoc.saveFile( âjsontest.jsâ);90 jDoc.saveFile("jsontest.js"); 53 91 54 92 To load from the file: … … 61 99 jDoc.readObject(epCfg); 62 100 63 Error Handling64 ---------------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.66 101 67 Asynchronous Operations68 -------------------------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 Threading74 ----------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++ Application79 ========================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 endpoint108 EpConfig ep_cfg;109 ep_cfg.uaConfig.userAgent = "pjsua2-hello";110 ep.libInit( ep_cfg );111 112 // Create SIP transport. Error handling sample is shown113 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 AccountConfig127 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 account134 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 server141 delete acc;142 143 // This will implicitly shutdown the library144 return 0;145 }146 147 148 Using in Python Application149 ===========================150 151 152 153 Using in Java Application154 =========================155 156 157 158 -
pjproject/trunk/doc/pjsip-book/media.rst
r4704 r4762 1 2 1 3 2 Media 4 3 ===== 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).4 Media objects are objects that are capable to either produce media or takes media. 6 5 7 6 An important subclass of Media is AudioMedia which represents audio media. There are several type of audio media objects supported in PJSUA2: 8 7 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. 10 11 - AudioMediaPlayer, to play WAV file(s). 11 12 - AudioMediaRecorder, to record audio to a WAV file. … … 15 16 The Audio Conference Bridge 16 17 ---------------------------- 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. Aplugged-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.18 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. The bridge will even take care medias with different clock rates and ptime. 19 20 In 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 22 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 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. 22 23 23 24 Playing a WAV File 24 25 ++++++++++++++++++ 25 To playback the WAV file to the speaker, just start the transmission of the WAV playback object to the sound device:: 26 To 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++ 26 29 27 30 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 38 By 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 44 Without looping, silence will be played once the playback has reached the end of the WAV file. 45 46 Once 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 55 Resuming 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 40 57 41 58 Recording to WAV File 42 59 +++++++++++++++++++++ 43 Or if you want to record the microphone to the WAV file, simply do this:: 60 Or if you want to record the audio from the sound device to the WAV file, simply do this: 61 62 .. code-block:: c++ 44 63 45 64 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 72 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: 73 74 .. code-block:: c++ 75 76 try { 77 cap_med.stopTransmit(recorder); 78 } catch(Error& err) { 79 } 80 81 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. To close the WAV recorder, simply delete it: 82 83 .. code-block:: c++ 84 85 delete recorder; 86 87 88 Local Audio Loopback 89 ++++++++++++++++++++ 90 A 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 60 96 61 97 Looping Audio 62 98 +++++++++++++ 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. 99 If 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. 70 100 71 101 Normal Call 72 102 +++++++++++ 73 103 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(); 104 A 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 85 128 86 129 Second Call 87 130 +++++++++++ 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(); 131 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: 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 } 93 140 94 141 Now 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). … … 96 143 Conference Call 97 144 +++++++++++++++ 98 To enable both parties talk to each other, just establish bidirectional media between them:: 145 To enable both parties talk to each other, just establish bidirectional media between them: 146 147 .. code-block:: c++ 99 148 100 149 aud_med->startTransmit(*aud_med2); … … 106 155 ++++++++++++++++++++++++ 107 156 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); 157 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: 158 159 .. code-block:: c++ 160 161 cap_med.startTransmit(recorder); 111 162 aud_med->startTransmit(recorder); 112 163 aud_med2->startTransmit(recorder); 113 164 165 166 Audio Device Management 167 ----------------------- 168 Please see `Audio Device Framework <#auddev>`_ below. 169 170 171 Class Reference 172 --------------- 173 Media Framework 174 +++++++++++++++ 175 Classes 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 193 Formats 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 207 Audio Device Framework 208 ++++++++++++++++++++++ 209 Device Manager 210 ~~~~~~~~~~~~~~ 211 .. _auddev: 212 .. doxygenclass:: pj::AudDevManager 213 :path: xml 214 :members: 215 216 Device Info 217 ~~~~~~~~~~~ 218 .. doxygenstruct:: pj::AudioDevInfo 219 :path: xml 220 -
pjproject/trunk/doc/pjsip-book/media_quality.rst
r4704 r4762 1 2 1 3 2 Media Quality … … 6 5 Audio Quality 7 6 ============= 7 If you experience any problem with the audio quality, you may want to try the steps below: 8 9 1. Follow the guide: `Test the sound device using pjsystest`_. 10 2. 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 15 It 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. 8 16 9 17 Video Quality 10 18 ============= 19 For video quality problems, the steps are as follows: 11 20 21 1. 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`_. 22 2. Check local video preview using PJSUA API as described in `Video Users Guide-Video Preview API`_. 23 3. 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. 24 4. 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 2 1 3 2 Network Problems … … 6 5 IP Address Change 7 6 ================= 7 Please 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 8 10 9 11 Blocked/Filtered Network 10 12 ======================== 13 Please refer to the wiki `Getting Around Blocked or Filtered VoIP Network`_. 11 14 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 2 1 3 2 General Configuration Optimization … … 9 8 CPU Optimization 10 9 ================ 10 A general guide on how to reduce CPU utilization can be found here: `FAQ-CPU utilization`_. 11 11 12 .. _`FAQ-CPU utilization`: http://trac.pjsip.org/repos/wiki/FAQ#cpu 13 -
pjproject/trunk/doc/pjsip-book/presence.rst
r4704 r4762 1 2 1 3 2 Buddy (Presence) 4 3 ================ 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. 4 Presence feature in PJSUA2 centers around Buddy class. This class represents a remote buddy (a person, or a SIP endpoint). 7 5 8 Sub scribe to Buddy's Presence Status9 ---------------------------- -----------------------------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::6 Subclassing the Buddy class 7 ---------------------------- 8 To use the Buddy class, normally application SHOULD create its own subclass, such as: 11 9 12 class MyBuddyCallback(pjsua.BuddyCallback): 13 def __init__(self, buddy=None): 14 pjsua.BuddyCallback.__init__(self, buddy) 10 .. code-block:: c++ 15 11 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() {} 19 17 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 }; 24 20 25 except pjsua.Error, err: 26 print 'Error adding buddy:', err 21 In its subclass, application can implement the buddy callback to get the notifications on buddy state change. 27 22 28 For more information please see âBuddy class and âBuddyCallback class reference documentation. 23 Subscribing to Buddy's Presence Status 24 --------------------------------------- 25 To 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 38 Then 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 48 For more information, please see Buddy class reference documentation. 29 49 30 50 Responding to Presence Subscription Request 31 51 ------------------------------------------- 32 52 By 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. 33 53 34 This can be done by implementing the âon_incoming_subscribe() method of the âAccountCallback class.54 This can be done by overriding the onIncomingSubscribe() method of the Account class. Please see the documentation of this method for more info. 35 55 36 56 Changing Account's Presence Status 57 ---------------------------------- 58 To 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: 37 59 38 The âAccount class provides two methods to change account's presence status: 60 .. code-block:: c++ 39 61 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 } 43 71 72 When 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 74 Instant Messaging(IM) 75 --------------------- 76 You can send IM using Buddy.sendInstantMessage(). The transmission status of outgoing instant messages is reported in Account.onInstantMessageStatus() callback method of Account class. 77 78 In addition to sending instant messages, you can also send typing indication to remote buddy using Buddy.sendTypingIndication(). 79 80 Incoming 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 82 Alternatively, 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 85 Class Reference 86 --------------- 87 Buddy 88 +++++ 89 .. doxygenclass:: pj::Buddy 90 :path: xml 91 :members: 92 93 Status 94 ++++++ 95 .. doxygenstruct:: pj::PresenceStatus 96 :path: xml 97 98 Info 99 ++++ 100 .. doxygenstruct:: pj::BuddyInfo 101 :path: xml 102 103 Config 104 ++++++ 105 .. doxygenstruct:: pj::BuddyConfig 106 :path: xml 107 108 -
pjproject/trunk/doc/pjsip-book/reference.rst
r4704 r4762 1 2 1 3 2 PJSUA2 API Reference Manuals -
pjproject/trunk/doc/pjsip-book/samples.rst
r4704 r4762 1 2 1 3 2 PJSUA2 Sample Applications … … 7 6 =========== 8 7 8 C++ 9 ----- 10 There 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 9 13 Python GUI 10 14 ------------------ 11 It requires Python 2.7 and above. 15 This 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:: 12 16 13 Android & Java 14 ----------------------------- 17 python application.py 15 18 16 C++ 17 ----------------------------- 19 Android 20 ---------------- 21 Please see https://trac.pjsip.org/repos/wiki/Getting-Started/Android#pjsua2 for Android sample application. 22 23 Java 24 ---------------- 25 There 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 18 27 19 28 Miscellaneous 20 29 =================== 21 30 22 How to dump call stats31 How to 23 32 ----------------------------- 24 33 25 How to âŠ26 -----------------------------27
Note: See TracChangeset
for help on using the changeset viewer.