]> sjero.net Git - linphone/blob - coreapi/help/doxygen.dox
7d0a82849f2f398fc6e1f5af8632e45d5adcc472
[linphone] / coreapi / help / doxygen.dox
1 /**
2  * @mainpage
3  *
4  * @see http://www.linphone.org
5  *
6  * @section what_is_it What is liblinphone
7  *
8  * Liblinphone is a high level library for bringing SIP video call functionnality
9  * into an application. It aims at making easy the integration of the SIP
10  * video calls into any applications. All variants of linphone are directly based
11  * on it:
12  * - linphone (gtk interface)
13  *
14  * - linphonec (console interface)
15  *
16  * Liblinphone is GPL (see COPYING file). Please understand the licencing details
17  * before using it!
18  * 
19  * For any use of this library beyond the rights granted to you by the
20  * GPL license, please contact Belledonne Communications 
21  * (contact@belledonne-communications.com)
22  * 
23  *
24 **/
25
26 /**
27  * @page liblinphone_license COPYING 
28  * @include COPYING
29  */
30
31 /**
32  * @defgroup initializing Initializing liblinphone
33 **/
34
35 /**
36  * @defgroup call_control Placing and receiving calls
37  *
38  * The #LinphoneCall object represents an incoming or outgoing call managed by the #LinphoneCore.
39  * Outgoing calls can be created using linphone_core_invite() or linphone_core_invite_address(), while incoming calls are notified to the application
40  * through the LinphoneCoreVTable::call_state_changed callback.
41  *
42  * See the basic call \ref basic_call_tutorials "tutorial".
43  *
44 **/
45
46 /**
47  * @defgroup call_misc Obtaining information about a running call: sound volumes, quality indicators
48  *
49  * When a call is running, it is possible to retrieve in real time current measured volumes and quality indicator.
50  *
51 **/
52
53 /**
54  * @defgroup media_parameters Controlling media parameters
55 **/
56
57 /**
58  * @defgroup proxies Managing proxies
59  *User registration is controled by  #LinphoneProxyConfig settings.<br> Each #LinphoneProxyConfig object can be configured with registration informations 
60  *like \link linphone_proxy_config_set_server_addr() proxy address \endlink , \link linphone_proxy_config_set_identity() user id \endlink, \link linphone_proxy_config_expires() refresh period \endlink, and so on. 
61  *<br> A created proxy config using linphone_proxy_config_new(), once configured, must be added to #LinphoneCore using function linphone_core_add_proxy_config().
62  *<br> It is recommended to set a default \link #LinphoneProxyConfig proxy config \endlink using function linphone_core_set_default_proxy(). Once done, if \link #LinphoneProxyConfig a proxy config \endlink has been configured with attribute \link linphone_proxy_config_enable_register() enable register \endlink  , next call to linphone_core_iterate() triggers a SIP register.  
63  *<br> Registration status is reported by #LinphoneRegistrationStateCb.
64  *<br>
65  *<br> This pseudo code demonstrates basic registration operations:
66  *<br> \code
67  *      
68  *      LinphoneProxyConfig* proxy_cfg;
69  *      /*create proxy config*/
70  *      proxy_cfg = linphone_proxy_config_new();
71  *      /*parse identity*/
72  *      LinphoneAddress *from = linphone_address_new("sip:toto@sip.titi.com");
73  *      LinphoneAuthInfo *info;
74  *      if (password!=NULL){
75  *              info=linphone_auth_info_new(linphone_address_get_username(from),NULL,"secret",NULL,NULL); /*create authentication structure from identity*/
76  *              linphone_core_add_auth_info(lc,info); /*add authentication info to LinphoneCore*/
77  *      }       
78  *      // configure proxy entries
79  *      linphone_proxy_config_set_identity(proxy_cfg,identity); /*set identity with user name and domain*/
80  *      const char* server_addr = linphone_address_get_domain(from); /*extract domain address from identity*/
81  *      linphone_proxy_config_set_server_addr(proxy_cfg,server_addr); /* we assume domain = proxy server address*/
82  *      linphone_proxy_config_enable_register(proxy_cfg,TRUE); /*activate registration for this proxy config*/
83  *      linphone_address_destroy(from); /*release resource*/
84  *      
85  *      linphone_core_add_proxy_config(lc,proxy_cfg); /*add proxy config to linphone core*/
86  *      linphone_core_set_default_proxy(lc,proxy_cfg); /*set to default proxy*/ \endcode
87  *<br>
88  * Registration sate call back:
89  \code
90  static void registration_state_changed(struct _LinphoneCore *lc, LinphoneProxyConfig *cfg, LinphoneRegistrationState cstate, const char *message){
91                 printf("New registration state %s for user id [%s] at proxy [%s]\n"
92                                 ,linphone_registration_state_to_string(cstate)
93                                 ,linphone_proxy_config_get_identity(cfg)
94                                 ,linphone_proxy_config_get_addr(cfg));
95 }
96  \endcode
97  *<br><b>Authentication:</b>
98  *<br>Most of the time, registration requires \ref authentication "authentication" to succed. #LinphoneAuthInfo info must be either added to #LinphoneCore  using function linphone_core_add_auth_info() before #LinphoneProxyConfig is added to Linphone core, or on demand from call back #AuthInfoRequested .    
99  *<br>
100  *<br><b>Unregistration:</b>
101  *<br> Unregistration or any changes to #LinphoneProxyConfig must be first started by a call to function linphone_proxy_config_edit() and validated by  function linphone_proxy_config_done()
102  *<br> This pseudo code shows how to unregister a user associated to a #LinphoneProxyConfig
103  *\code
104         LinphoneProxyConfig* proxy_cfg;
105         linphone_core_get_default_proxy(lc,&proxy_cfg); /* get default proxy config*/
106         linphone_proxy_config_edit(proxy_cfg); /*start editing proxy configuration*/
107         linphone_proxy_config_enable_register(proxy_cfg,FALSE); /*de-activate registration for this proxy config*/
108         linphone_proxy_config_done(proxy_cfg); /*initiate REGISTER with expire = 0*/
109 \endcode
110         <br>
111         A complete tutorial can be found at : \ref registration_tutorials "Registration tutorial" 
112 **/
113
114 /**
115  * @defgroup network_parameters Controlling network parameters (ports, mtu...)
116 **/
117
118 /**
119  * @defgroup authentication Managing authentication: userid and passwords
120 **/
121
122 /**
123 * @defgroup buddy_list Managing Buddies and buddy list and presence 
124 <b>Buddies and buddy list</b>
125 <br>Each buddy is represented by a #LinphoneFriend object created by function linphone_friend_new(). 
126 Buddy configuration parameters like \link linphone_friend_set_addr() sip uri \endlink or  \link linphone_friend_set_inc_subscribe_policy() status publication \endlink policy for this \link #LinphoneFriend friend \endlink  are configurable for each buddy.
127 <br>Here under a typical buddy creation:
128 <br>
129 \code
130 LinphoneFriend* my_friend=linphone_friend_new_with_addr("sip:joe@sip.linphone.org"); /*creates friend object for buddy joe*/
131 linphone_friend_enable_subscribes(my_friend,TRUE); /*configure this friend to emit SUBSCRIBE message after being added to LinphoneCore*/
132 linphone_friend_set_inc_subscribe_policy(my_friend,LinphoneSPAccept); /* accept Incoming subscription request for this friend*/
133 \endcode
134 \link #LinphoneFriend  friends \endlink status changes are reported by callback LinphoneCoreVTable.notify_presence_recv
135 \code
136 static void notify_presence_recv_updated (struct _LinphoneCore *lc,  LinphoneFriend *friend) {
137         const LinphoneAddress* friend_address = linphone_friend_get_address(friend);
138         printf("New state state [%s] for user id [%s] \n"
139                                 ,linphone_online_status_to_string(linphone_friend_get_status(friend))
140                                 ,linphone_address_as_string (friend_address));
141 }
142 \endcode
143 <br>Once created a buddy can be added to the buddy list using function linphone_core_add_friend() . Added friends will be notified about \link linphone_core_set_presence_info() local status changes \endlink
144 <br>
145 Any subsequente modifications to #LinphoneFriend must be first started by a call to function linphone_friend_edit() and validated by  function linphone_friend_done()
146 \code
147 linphone_friend_edit(my_friend); /* start editing friend */
148 linphone_friend_enable_subscribes(my_friend,FALSE); /*disable subscription for this friend*/
149 linphone_friend_done(my_friend); /*commit changes triggering an UNSUBSCRIBE message*/
150 \endcode
151
152
153 <b> Publishing presence status </b>
154 <br>Local presence status can be changed using function linphone_core_set_presence_info() .New status is propagated to all friends \link linphone_core_add_friend() previously added \endlink to #LinphoneCore. 
155
156 <b>Handling incoming subscription request</b>
157 <br> New incoming subscription requests are process according to \link linphone_friend_set_inc_subscribe_policy() the incoming subscription policy state \endlink for subscription initiated by \link linphone_core_add_friend() members of the buddy list. \endlink
158 <br> For incoming request comming from an unknown buddy, the call back  LinphoneCoreVTable.new_subscription_request is invoked.
159
160 <br> A complete tutorial can be found at : \ref buddy_tutorials "Registration tutorial" 
161
162
163 **/
164
165 /**
166 * @defgroup chatroom Chat room and Messaging 
167 <b> Exchanging text messages</b>
168 <br> Messages are sent using #LinphoneChatRoom object. First step is to create a \link linphone_core_create_chat_room() chat room \endlink
169 from a peer sip uri.
170 \code
171 LinphoneChatRoom* chat_room = linphone_core_create_chat_room(lc,"sip:joe@sip.linphone.org");
172 \endcode
173
174 <br>Once created, messages are sent using function linphone_chat_room_send_message()  . 
175 \code
176 linphone_chat_room_send_message(chat_room,"Hello world"); /*sending message*/
177 \endcode
178 <br>Incoming message are received from call back LinphoneCoreVTable.text_received
179 \code
180 void text_received(LinphoneCore *lc, LinphoneChatRoom *room, const LinphoneAddress *from, const char *message) {
181         printf(" Message [%s] received from [%s] \n",message,linphone_address_as_string (from));
182 }
183 \endcode
184 <br> A complete tutorial can be found at : \ref chatroom_tuto "Chat room tutorial" 
185 **/
186
187 /**
188  * @defgroup call_logs Managing call logs
189 **/
190
191
192 /**
193  * @defgroup linphone_address SIP address parser API.
194  * This api is useful for manipulating SIP addresses ('from' or 'to' headers).
195 **/
196
197 /**
198  * @defgroup misc Miscenalleous: logs, version strings, config storage
199 **/
200
201 /**
202  * @defgroup tutorials Tutorials: 
203  *
204 **/
205
206 /**
207  * @defgroup port Portability: 
208  *
209 **/
210 /**
211  * @defgroup IOS IOS
212  * @ingroup port
213  *<br>
214  <b>Multitasking</b>
215  <br> Liblinphone for IOS natively supports multitasking assuming application follows multitasking guides provided by Apple. First step is to declare application as multitasked. It means adding background mode for both audio and voip to Info.plist file.
216  <br>
217  \code
218         <key>UIBackgroundModes</key>
219         <array>
220                 <string>voip</string>
221                 <string>audio</string>
222         </array>
223 \endcode
224 <br>
225 <ul>
226 <li><b>SIP socket </b><br>Recommended mode is SIP over TCP, because UDP usually requires frequent keep alives for maintaining NAT association at the IP router level. This can be as frequent as one UDP packet every 15 seconds to maintain the NAT association accross NAT routers. Doing such drains the battery very fast, and furthermore the iOS keep-alive designed by Apple to handle this task can only be called with a minimum of 10 minutes interval.<br>
227 For TCP, liblinphone automatically configures SIP socket for voip  (I.E kCFStreamNetworkServiceType set to kCFStreamNetworkServiceTypeVoIP). <br>
228 In the event that an application really wants to use UDP, it is the responsability of application to set this property to the UDP SIP socket before entering in background. It can access the SIP socket from method #linphone_core_get_sip_socket(). Note this property is only settable on a connected socket. As liblinphone UDP sockets are not connected, application willing to enable UDP background mode must first connect the UDP sip socket before configuring the voip mode. Pseudo code below shows the different steps:
229 \code
230         //get sip socket
231         CFReadStreamRef mReadStream
232         int sipsock = linphone_core_get_sip_socket(theLinphoneCore);    
233         //get address port of the sip proxy in order to connect the udp socket to this proxy
234         const char *port;
235         addr=linphone_address_new(linphone_proxy_config_get_addr(proxyCfg));
236         memset(&hints,0,sizeof(hints));
237         hints.ai_family=linphone_core_ipv6_enabled(theLinphoneCore) ? AF_INET6 : AF_INET;
238         port=linphone_address_get_port(addr);
239         if (port==NULL) port="5060";
240         err=getaddrinfo(linphone_address_get_domain(addr),port,&hints,&res);
241         if (err!=0){
242                 ms_error("getaddrinfo() failed for %s: %s",linphone_address_get_domain(addr),gai_strerror(err));
243                 linphone_address_destroy(addr);
244                 return;
245         }
246         //connect the udp socket
247         err=connect(sipsock,res->ai_addr,res->ai_addrlen);
248         if (err==-1){
249                 ms_error("Connect failed: %s",strerror(errno));
250         }
251         freeaddrinfo(res);
252         //create CFRead stream from the sip socket id
253         CFStreamCreatePairWithSocket(NULL, (CFSocketNativeHandle)sipsock, &mReadStream,nil);
254         //configure for persistante connection
255         if (!CFReadStreamSetProperty(mReadStream, kCFStreamNetworkServiceType, kCFStreamNetworkServiceTypeVoIP)) {
256                 ms_error("cannot set service type to voip for read stream");
257         }
258         if (!CFReadStreamOpen(mReadStream)) {
259                 ms_error("cannot open read stream");
260         }               
261
262 \endcode
263 <br> Note this operation has to be performed every time the application enters in background mode.
264 <br> Anyway, for battery saving and interoperability with NAT routers reasons, <b>UDP background mode is not recomended</b>.<br>
265 The choice between UDP and TCP transport for sip can be configured with linphone_core_set_sip_transports().
266 <li><b>Entering background mode</b>
267 <br> Before entering in background mode (through \code - (void)applicationDidEnterBackground:(UIApplication *)application \endcode  ), the application must first refresh sip registration using function #linphone_core_refresh_registers();
268 and register a keep-alive handler for periodically refreshing the registration. The speudo code below shows how to register a keep alive handler:
269 \code
270         //First refresh registration
271         linphone_core_refresh_registers(theLinphoneCore);
272         //wait for registration answer
273         int i=0;
274         while (!linphone_proxy_config_is_registered(proxyCfg) && i++<40 ) {
275                 linphone_core_iterate(theLinphoneCore);
276                 usleep(100000);
277         }
278         //register keepalive handler
279         [[UIApplication sharedApplication] setKeepAliveTimeout:600/*minimal interval is 600 s*/ 
280                                                        handler:^{
281                                                                 //refresh sip registration
282                                                                 linphone_core_refresh_registers(theLinphoneCore);
283                                                                 //make sure sip REGISTER is sent
284                                                                 linphone_core_iterate(theLinphoneCore);
285                                                                  }];
286 \endcode
287 <li><b>Incoming call notification while in background mode</b>
288 <br>Assuming application using liblinphone is well configured for multitasking, incoming calls arriving while liblinphone is in background mode will simply wakeup liblinphone thread but not resume GUI. To wakeup GUI, it is recommended to send a Local Notification to the user from the #LinphoneCallStateCb. Here under a speudo code for this operation:
289 \code
290         if ([UIApplication sharedApplication].applicationState ==  UIApplicationStateBackground) {
291                 // Create a new notification
292                 UILocalNotification* notif = [[[UILocalNotification alloc] init] autorelease];
293                 if (notif) {
294                         notif.repeatInterval = 0;
295                         notif.alertBody =@"New incoming call";
296                         notif.alertAction = @"Answer";
297                         notif.soundName = @"oldphone-mono-30s.caf";
298                         
299                         [[UIApplication sharedApplication]  presentLocalNotificationNow:notif];
300                 }
301 \endcode
302 </ul>
303 <b>Networking</b>
304 <br>
305 <ul><li><b>WWAN connection</b>
306 <br>Liblinphone relies on iOS's standard BSD socket layer for sip/rtp networking. On IOS, WWAN connection is supposed to automatically bring up on any networking resquest issued by an application. At least on iPhone OS 3.x, BSD sockets do not implement this behavior. So it is recomended to add a special code to make sure the WWAN connection is properly setup. Pseudo code below describes a way to force WWAN connection by setting up a dummy TCP connection.
307 \code
308 /*start a new thread to avoid blocking the main ui in case of peer host failure*/
309 [NSThread detachNewThreadSelector:@selector(runNetworkConnection) toTarget:self withObject:nil];
310 -(void) runNetworkConnection {
311         CFWriteStreamRef writeStream;
312         //create a dummy socket
313         CFStreamCreatePairWithSocketToHost(NULL, (CFStringRef)@"192.168.0.200", 15000, nil, &writeStream);
314         CFWriteStreamOpen (writeStream);
315         const char* buff="hello";
316         //try to write on this socket
317         CFWriteStreamWrite (writeStream,(const UInt8*)buff,strlen(buff));
318         CFWriteStreamClose (writeStream);
319 }       
320 \endcode  
321 It is recommanded to perform this task each time the application is woken up, including keep alive handler.
322 <li><b>Managing IP connection state</b>
323 <br>Liblinphone for IOS relies on the application to be informed of network connectivity changes. Network state changes when the IP connection moves from DOWN to UP, or from WIFI to WWAN. Applications using liblinphone must inform libliblinphone of this changes using function #linphone_core_set_network_reachable(). Usually this method is called from the IOS NetworkReachability callback. Here under a sample code:
324 \code
325 //typical reachability callback
326 void networkReachabilityCallBack(SCNetworkReachabilityRef target, SCNetworkReachabilityFlags flags, void * info) {
327         if ((flags == 0) | (flags & (kSCNetworkReachabilityFlagsConnectionRequired |kSCNetworkReachabilityFlagsConnectionOnTraffic))) {
328                 //network state is off
329                 linphone_core_set_network_reachable(lc,false);
330                 ((LinphoneManager*)info).connectivity = none;
331         } else {
332                 Connectivity  newConnectivity = flags & kSCNetworkReachabilityFlagsIsWWAN ? wwan:wifi;
333                 if (lLinphoneMgr.connectivity == none) {
334                         //notify new network state
335                         linphone_core_set_network_reachable(lc,true);
336                 } else if (lLinphoneMgr.connectivity != newConnectivity) {
337                         // connectivity has changed
338                         linphone_core_set_network_reachable(lc,false);
339                         linphone_core_set_network_reachable(lc,true);
340                 }
341                 //store new connectivity status
342                 lLinphoneMgr.connectivity=newConnectivity;
343         }
344 }
345 }
346         
347 \endcode  
348 </ul>
349 <b>DTMF feebacks</b>
350 <br>Liblinphone provides functions \link #linphone_core_play_dtmf() to play dtmf \endlink to the local user. Usually this is used to play a sound when the user presses a digit, inside or outside of any call. On IOS, libLinphone relies on AudioUnits for interfacing with the audio system. Unfortunately the Audio Unit initialization is a quite long operation that may trigger a bad user experience if performed each time a DTMF is played, the sound being delayed half a second after the press. To solve this issue and thus insure real-time precision, liblinphone introduces 2 functions for \link linphone_core_start_dtmf_stream() preloading \endlink and \link #linphone_core_start_dtmf_stream() unloading \endlink the underlying audio graph responsible for playing DTMFs.  
351 <br> For an application using function #linphone_core_play_dtmf(), it is recommanded to call #linphone_core_start_dtmf_stream() when entering in foreground and #linphone_core_stop_dtmf_stream() upon entering background mode. 
352 */
353