]> sjero.net Git - linphone/blob - coreapi/exevents.c
Merge branch 'dev_sal'
[linphone] / coreapi / exevents.c
1 /*
2 linphone
3 Copyright (C) 2000  Simon MORLAT (simon.morlat@free.fr)
4
5 This program is free software; you can redistribute it and/or
6 modify it under the terms of the GNU General Public License
7 as published by the Free Software Foundation; either version 2
8 of the License, or (at your option) any later version.
9
10 This program is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13 GNU General Public License for more details.
14
15 You should have received a copy of the GNU General Public License
16 along with this program; if not, write to the Free Software
17 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
18 */
19
20 #include "exevents.h"
21 #include "linphonecore.h"
22 #include "private.h"
23 #include "mediastreamer2/mediastream.h"
24 #include <eXosip2/eXosip.h>
25 #include <osipparser2/osip_message.h>
26 #include <osipparser2/osip_parser.h>
27
28 static int linphone_answer_sdp(LinphoneCore *lc, eXosip_event_t *ev, sdp_message_t *sdp);
29
30 static bool_t linphone_call_matches_event(LinphoneCall *call, eXosip_event_t *ev){
31         return call->cid==ev->cid;
32 }
33
34 static void linphone_call_proceeding(LinphoneCore *lc, eXosip_event_t *ev){
35         if (lc->call==NULL || (lc->call->cid!=-1 && !linphone_call_matches_event(lc->call,ev)) ) {
36                 ms_warning("This call has been canceled: call=%p, call->cid=%i, ev->cid=%i",
37                                    lc->call,lc->call?lc->call->cid:-1,ev->cid);
38                 eXosip_lock();
39                 eXosip_call_terminate(ev->cid,ev->did);
40                 eXosip_unlock();
41                 return;
42         }
43         lc->call->cid=ev->cid;
44         lc->call->did=ev->did;
45         lc->call->tid=ev->tid;
46 }
47
48 static void linphone_connect_incoming(LinphoneCore *lc){
49         lc->vtable.show(lc);
50         lc->vtable.display_status(lc,_("Connected."));
51         lc->call->state=LCStateAVRunning;
52         if (lc->ringstream!=NULL){
53                 ring_stop(lc->ringstream);
54                 lc->ringstream=NULL;
55         }
56         if (lc->audiostream->ticker!=NULL){
57                 /*case where we accepted early media */
58                 linphone_core_stop_media_streams(lc);
59                 linphone_core_init_media_streams(lc);
60         }
61         linphone_core_start_media_streams(lc,lc->call);
62 }
63
64 int linphone_call_accepted(LinphoneCore *lc, eXosip_event_t *ev)
65 {
66         LinphoneCall *call=lc->call;
67         sdp_message_t *sdp;
68         const char *sdpanswer=NULL;
69         osip_message_t *msg=NULL;
70         int err;
71         if (call==NULL){
72                 ms_warning("No call to accept.");
73                 return 0;
74         }
75         linphone_call_proceeding(lc,ev);
76         if (!linphone_call_matches_event(lc->call,ev)) return 0;
77         call->auth_pending=FALSE;
78         if (call->state==LCStateAVRunning){
79                 return 0; /*already accepted*/
80         }
81         linphone_call_init_media_params(call);
82         sdp=eXosip_get_sdp_info(ev->response);
83         if (!lc->sip_conf.sdp_200_ack){
84                 err=0;
85                 sdp_context_read_answer(call->sdpctx,sdp);
86         }else{
87                 /*we receive a 200OK with an sdp offer*/
88                 err=linphone_answer_sdp(lc,ev,sdp);
89                 if (err==0) sdpanswer=call->sdpctx->answerstr;
90         }
91         if (err==0){
92                 gstate_new_state(lc, GSTATE_CALL_OUT_CONNECTED, NULL);
93                 linphone_connect_incoming(lc);
94         }
95         /*send the ack once streams are started*/
96         eXosip_call_build_ack(ev->did,&msg);
97         if (sdpanswer!=NULL) linphone_set_sdp(msg,sdpanswer);
98         eXosip_call_send_ack(ev->did,msg);
99         if (err!=0){
100                 /*send a bye*/
101                 ms_error("Incompatible SDP offer received in 200Ok, need to abort the call");
102                 linphone_core_terminate_call(lc,NULL);
103         }
104         sdp_message_free(sdp);
105         return 0;
106 }
107
108
109 int linphone_call_terminated(LinphoneCore *lc, eXosip_event_t *ev)
110 {
111         /*stop ringing if necessary*/
112         if (lc->call!=NULL){
113                 if (lc->call->cid!=ev->cid){
114                         /* this is not current call */
115                         ms_message("call %i terminated, this was not current call.",ev->cid);
116                         return 0;
117                 }
118         }
119
120         ms_message("Current call terminated...");
121         if (lc->ringstream!=NULL) {
122                 ring_stop(lc->ringstream);
123                 lc->ringstream=NULL;
124         }
125         linphone_core_stop_media_streams(lc);
126         lc->vtable.show(lc);
127         lc->vtable.display_status(lc,_("Call terminated."));
128         gstate_new_state(lc, GSTATE_CALL_END, NULL);
129         if (lc->vtable.bye_recv!=NULL){
130                 char *from;
131                 osip_from_to_str(ev->request->from,&from);
132                 lc->vtable.bye_recv(lc,from);
133                 osip_free(from);
134         }
135         if (lc->call!=NULL){
136                 linphone_call_destroy(lc->call);
137                 lc->call=NULL;
138         }
139         return 0;
140 }
141
142
143 int linphone_call_released(LinphoneCore *lc, int cid){
144         LinphoneCall *call=lc->call;
145         if (call!=NULL && call->cid==cid){
146
147                 linphone_call_destroy(lc->call);
148                 lc->call=NULL;
149                 lc->vtable.display_status(lc,_("Could not reach destination."));
150                 gstate_new_state(lc, GSTATE_CALL_ERROR, NULL);
151         }
152         return 0;
153 }
154
155 int linphone_call_failure(LinphoneCore *lc, eXosip_event_t *ev)
156 {
157         const char *reason="";
158         char *msg486=_("User is busy.");
159         char *msg480=_("User is temporarily unavailable.");
160         char *msg487=_("Request Cancelled.");
161         /*char *retrymsg=_("%s. Retry after %i minute(s).");*/
162         char *msg600=_("User does not want to be disturbed.");
163         char *msg603=_("Call declined.");
164         char* tmpmsg=msg486;
165         int code;
166         LinphoneCall *call=lc->call;
167
168         if (call){
169                 /*check that the faillure is related to this call, not an old one*/
170                 if (!linphone_call_matches_event(call,ev)) {
171                         ms_warning("Failure reported for an old call.");
172                         return 0;
173                 }
174         }
175
176         if (ev->response){
177                 code=osip_message_get_status_code(ev->response);
178                 reason=osip_message_get_reason_phrase(ev->response);
179         }else code=-110;
180         lc->vtable.show(lc);
181
182         switch(code)
183         {
184                 case 401:
185                 case 407:
186                         if (lc->call!=NULL)
187                                 linphone_process_authentication(lc,ev);
188                         return 0;
189                         break;
190                 case 400:
191                         lc->vtable.display_status(lc,_("Bad request"));
192                 break;
193                 case 404:
194                         lc->vtable.display_status(lc,_("User cannot be found at given address."));
195                 break;
196                 case 415:
197                         lc->vtable.display_status(lc,_("Remote user cannot support any of proposed codecs."));
198                 break;
199                 case 422:
200                         /*ignore: eXosip_automatic_action will do the job of retrying with a greater Session-Expires*/
201                         return 0;
202                 break;
203                 case 480:
204                         tmpmsg=msg480;
205                 case 486:
206                         /*
207                         msg_header_getbyname(msg,"retry-after",0,&retry);
208                         if (retry!=NULL)
209                         {
210                                 umsg=g_malloc(strlen(tmpmsg)+strlen(retrymsg)+13);
211                                 sprintf(umsg,retrymsg,tmpmsg,atoi(retry->hvalue)/60);
212                                 lc->vtable.display_message(lc,umsg);
213                                 ms_free(umsg);
214                         }*/
215                         lc->vtable.display_message(lc,tmpmsg);
216                 break;
217                 case 487: /*request terminated*/
218                         lc->vtable.display_status(lc,msg487);
219                 break;
220                 case 600:
221                         lc->vtable.display_message(lc,msg600);
222                 break;
223                 case 603:
224                         lc->vtable.display_status(lc,msg603);
225                 break;
226                 case -110:  /* time out, call leg is lost */
227                         lc->vtable.display_status(lc,_("Timeout."));
228                 break;
229                 case -111:
230                         lc->vtable.display_status(lc,_("Remote host was found but refused connection."));
231                 break;
232
233                 default:
234                         if (code>0)
235                         {
236                                 lc->vtable.display_status(lc,reason);
237                         }
238                         else ms_warning("failure_cb unknown code=%i\n",code);
239         }
240         if (lc->ringstream!=NULL) {
241                 ring_stop(lc->ringstream);
242                 lc->ringstream=NULL;
243         }
244         linphone_core_stop_media_streams(lc);
245         if (call!=NULL) {
246                 linphone_call_destroy(call);
247                 gstate_new_state(lc, GSTATE_CALL_ERROR, NULL);
248                 lc->call=NULL;
249         }
250         return 0;
251 }
252
253 extern sdp_handler_t linphone_sdphandler;
254
255 static int linphone_answer_sdp(LinphoneCore *lc, eXosip_event_t *ev, sdp_message_t *sdp){
256         int status=200;
257         sdp_context_t *ctx=NULL;
258
259         ctx=lc->call->sdpctx;
260         /* get the result of the negociation */
261         sdp_context_get_answer(ctx,sdp);
262         status=sdp_context_get_status(ctx);
263
264         if (status==200){
265                 linphone_core_init_media_streams(lc);
266                 return 0;
267         }else{
268                 if (status==-1) status=415;
269         }
270         return -1;
271 }
272
273 int linphone_inc_new_call(LinphoneCore *lc, eXosip_event_t *ev)
274 {
275         sdp_message_t *sdp=NULL;
276         osip_from_t *from_url=ev->request->from;
277         char *barmesg;
278         char *from;
279         char *to;
280         int err;
281
282         osip_from_to_str(ev->request->from,&from);
283         osip_to_to_str(ev->request->to,&to);
284
285         /* first check if we can answer successfully to this invite */
286         if (lc->presence_mode!=LINPHONE_STATUS_ONLINE){
287                 ms_message("Not present !! presence mode : %d\n",lc->presence_mode);
288                 eXosip_lock();
289                 if (lc->presence_mode==LINPHONE_STATUS_BUSY)
290                         eXosip_call_send_answer(ev->tid,486,NULL);
291                 else if (lc->presence_mode==LINPHONE_STATUS_AWAY
292                          ||lc->presence_mode==LINPHONE_STATUS_BERIGHTBACK
293                          ||lc->presence_mode==LINPHONE_STATUS_ONTHEPHONE
294                          ||lc->presence_mode==LINPHONE_STATUS_OUTTOLUNCH
295                          ||lc->presence_mode==LINPHONE_STATUS_OFFLINE)
296                   eXosip_call_send_answer(ev->tid,480,NULL);
297                 else if (lc->presence_mode==LINPHONE_STATUS_NOT_DISTURB)
298                   eXosip_call_send_answer(ev->tid,480,NULL);
299                 else if (lc->alt_contact!=NULL && lc->presence_mode==LINPHONE_STATUS_MOVED)
300                   {
301                         osip_message_t *msg;
302                         eXosip_call_build_answer(ev->tid,302,&msg);
303                         osip_message_set_contact(msg,lc->alt_contact);
304                         eXosip_call_send_answer(ev->tid,302,msg);
305                   }
306                 else if (lc->alt_contact!=NULL && lc->presence_mode==LINPHONE_STATUS_ALT_SERVICE)
307                   {
308                         osip_message_t *msg;
309                         eXosip_call_build_answer(ev->tid,380,&msg);
310                         osip_message_set_contact(msg,lc->alt_contact);
311                         eXosip_call_send_answer(ev->tid,380,msg);
312                   }
313                 else
314                   eXosip_call_send_answer(ev->tid,486,NULL);
315                 eXosip_unlock();
316                 goto end;
317         }
318         if (lc->call!=NULL){/*busy*/
319                 eXosip_lock();
320                 eXosip_call_send_answer(ev->tid,486,NULL);
321                 eXosip_unlock();
322                 goto end;
323         }
324         lc->call=linphone_call_new_incoming(lc,linphone_address_new(from),linphone_address_new(to),ev);
325
326         sdp=eXosip_get_sdp_info(ev->request);
327         if (sdp==NULL){
328                 ms_message("No sdp body in invite, 200-ack scheme");
329                 err=0;
330         }else{
331                 err=linphone_answer_sdp(lc,ev,sdp);
332         }
333         if (!err){
334                 char *tmp;
335                 if (from_2char_without_params(from_url,&tmp)!=0){
336                         tmp=ms_strdup("Unknown user");
337                 }
338                 gstate_new_state(lc, GSTATE_CALL_IN_INVITE, tmp);
339                 barmesg=ortp_strdup_printf("%s %s",tmp,_("is contacting you."));
340                 lc->vtable.show(lc);
341                 lc->vtable.display_status(lc,barmesg);
342
343                 /* play the ring */
344                 if (lc->sound_conf.ring_sndcard!=NULL){
345                         ms_message("Starting local ring...");
346                         lc->ringstream=ring_start(lc->sound_conf.local_ring,2000,lc->sound_conf.ring_sndcard);
347                 }
348                 linphone_call_set_state(lc->call,LCStateRinging);
349                 eXosip_lock();
350                 eXosip_call_send_answer(ev->tid,180,NULL);
351                 eXosip_unlock();
352
353                 lc->vtable.inv_recv(lc,tmp);
354                 ms_free(barmesg);
355                 osip_free(tmp);
356         }else{
357                 ms_error("Error during sdp negociation. ");
358                 eXosip_lock();
359                 eXosip_call_send_answer(ev->tid,415,NULL);
360                 eXosip_unlock();
361                 linphone_call_destroy(lc->call);
362                 lc->call=NULL;
363         }
364         end:
365         osip_free(from);
366         osip_free(to);
367         if (sdp) sdp_message_free(sdp);
368         return 0;
369 }
370
371 void linphone_handle_ack(LinphoneCore *lc, eXosip_event_t *ev){
372         sdp_message_t *sdp=eXosip_get_sdp_info(ev->ack);
373         if (sdp){
374                 sdp_context_read_answer(lc->call->sdpctx,sdp);
375                 linphone_connect_incoming(lc);
376                 sdp_message_free(sdp);
377         }
378 }
379
380 void linphone_handle_reinvite(LinphoneCore *lc, eXosip_event_t *ev){
381         sdp_message_t *sdp=eXosip_get_sdp_info(ev->request);
382         sdp_context_t *ctx;
383         LinphoneCall *call=lc->call;
384         char *answer;
385         int status;
386         if (sdp==NULL){
387                 ms_warning("No sdp in reinvite !");
388                 eXosip_lock();
389                 eXosip_call_send_answer(ev->tid,603,NULL);
390                 eXosip_unlock();
391                 return;
392         }
393         ctx=call->sdpctx;
394         /* get the result of the negociation */
395         linphone_call_init_media_params(call);
396         answer=sdp_context_get_answer(ctx,sdp);
397         status=sdp_context_get_status(ctx);
398         if (status==200){
399                 osip_message_t *msg=NULL;
400                 linphone_core_stop_media_streams(lc);
401                 linphone_core_init_media_streams(lc);
402                 eXosip_lock();
403                 if (eXosip_call_build_answer(ev->tid,200,&msg)<0){
404                         ms_warning("Reinvite for closed call ?");
405                         eXosip_unlock();
406                         linphone_core_stop_media_streams(lc);
407                         sdp_message_free(sdp);
408                         return ;
409                 }
410                 answer=call->sdpctx->answerstr; /* takes the sdp already computed*/
411                 linphone_set_sdp(msg,answer);
412                 eXosip_call_send_answer(ev->tid,200,msg);
413                 eXosip_unlock();
414                 linphone_core_start_media_streams(lc,call);
415         }else{
416                 eXosip_lock();
417                 eXosip_call_send_answer(ev->tid,status,NULL);
418                 eXosip_unlock();
419         }
420         sdp_message_free(sdp);
421 }
422
423 void linphone_do_automatic_redirect(LinphoneCore *lc, const char *contact){
424         char *msg=ortp_strdup_printf(_("Redirected to %s..."),contact);
425         lc->vtable.display_status(lc,msg);
426         ms_free(msg);
427         if (lc->call!=NULL) linphone_call_destroy(lc->call);
428         lc->call=NULL;
429         linphone_core_invite(lc,contact);
430 }
431
432 void linphone_call_redirected(LinphoneCore *lc, eXosip_event_t *ev){
433         int code=osip_message_get_status_code(ev->response);
434         char *contact=NULL;
435         osip_contact_t *ct;
436         osip_message_get_contact(ev->response,0,&ct);
437         if (ct) osip_contact_to_str(ct,&contact);
438         switch(code){
439                 case 380:
440                         lc->vtable.display_url(lc,_("User is not reachable at the moment but he invites you\nto contact him using the following alternate resource:"),contact);
441                         if (lc->call!=NULL) linphone_call_destroy(lc->call);
442                         lc->call=NULL;
443                         break;
444                 case 302:
445                         linphone_do_automatic_redirect(lc,contact);
446                         break;
447         }
448         if (contact) osip_free(contact);
449 }
450
451
452 /* these are the SdpHandler callbacks: we are called in to be aware of the content
453 of the SDP messages exchanged */
454
455 int linphone_set_audio_offer(sdp_context_t *ctx)
456 {
457         LinphoneCall *call=(LinphoneCall*)sdp_context_get_user_pointer(ctx);
458         LinphoneCore *lc=call->core;
459         PayloadType *codec;
460         MSList *elem;
461         sdp_payload_t payload;
462
463
464         elem=lc->codecs_conf.audio_codecs;
465         while(elem!=NULL){
466                 codec=(PayloadType*) elem->data;
467                 if (linphone_core_check_payload_type_usability(lc,codec) && 
468                     linphone_core_payload_type_enabled(lc,codec)){
469                         sdp_payload_init(&payload);
470                         payload.a_rtpmap=ortp_strdup_printf("%s/%i/1",codec->mime_type,codec->clock_rate);
471                         payload.pt=rtp_profile_get_payload_number_from_rtpmap(lc->local_profile,payload.a_rtpmap);
472                         payload.localport=call->audio_params.natd_port > 0 ?
473                                                 call->audio_params.natd_port : lc->rtp_conf.audio_rtp_port;
474                         sdp_context_add_audio_payload(ctx,&payload);
475                         ms_free(payload.a_rtpmap);
476                 }
477                 elem=ms_list_next(elem);
478         }
479         /* add telephone-event payload*/
480         sdp_payload_init(&payload);
481         payload.pt=rtp_profile_get_payload_number_from_mime(lc->local_profile,"telephone-event");
482         payload.a_rtpmap="telephone-event/8000";
483         payload.a_fmtp="0-11";
484         if (lc->dw_audio_bw>0) payload.b_as_bandwidth=lc->dw_audio_bw;
485         if (lc->down_ptime>0) {
486                 payload.a_ptime=lc->down_ptime;
487                 ms_message("ptime [%i]",payload.a_ptime);
488         }
489         sdp_context_add_audio_payload(ctx,&payload);
490         return 0;
491 }
492
493 static int find_payload_type_number(RtpProfile *prof, PayloadType *pt){
494         int candidate=-1,i;
495         PayloadType *it;
496         for(i=0;i<127;++i){
497                 it=rtp_profile_get_payload(prof,i);
498                 if (it!=NULL && strcasecmp(pt->mime_type,it->mime_type)==0
499                         && (pt->clock_rate==it->clock_rate || pt->clock_rate<=0) ){
500                         if ( (pt->recv_fmtp && it->recv_fmtp && strcasecmp(pt->recv_fmtp,it->recv_fmtp)==0) ||
501                                 (pt->recv_fmtp==NULL && it->recv_fmtp==NULL) ){
502                                 /*exact match*/
503                                 return i;
504                         }else candidate=i;
505                 }
506         }
507         if (candidate==-1) ms_fatal("Should not happen.");
508         return candidate;
509 }
510
511 static int find_payload_type_number_best_match(RtpProfile *prof, const char *rtpmap, const char *fmtp){
512         int localpt=rtp_profile_get_payload_number_from_rtpmap(prof,rtpmap);
513         PayloadType *pt;
514         char value[10];
515         if (localpt<0) return -1;
516         pt=rtp_profile_get_payload(prof,localpt);
517         if (strcasecmp(pt->mime_type,"H264")==0){
518                 /*hack for H264: need to answer with same packetization-mode*/
519                 PayloadType tmp;
520                 memset(&tmp,0,sizeof(tmp));
521                 tmp.mime_type="H264";
522                 tmp.clock_rate=pt->clock_rate;
523                 if (fmtp && fmtp_get_value(fmtp,"packetization-mode",value,sizeof(value))){
524                         tmp.recv_fmtp=(atoi(value)==1) ? "packetization-mode=1" : NULL;
525                 }
526                 localpt=find_payload_type_number(prof,&tmp);
527         }
528         return localpt;
529 }
530
531 int linphone_set_video_offer(sdp_context_t *ctx)
532 {
533         LinphoneCall *call=(LinphoneCall*)sdp_context_get_user_pointer(ctx);
534         LinphoneCore *lc=call->core;
535         PayloadType *codec;
536         MSList *elem;
537         bool_t firsttime=TRUE;
538
539         if (!linphone_core_video_enabled(lc)) return -1;
540
541         for(elem=lc->codecs_conf.video_codecs;elem!=NULL;elem=ms_list_next(elem)){
542                 codec=(PayloadType*) elem->data;
543                 if (linphone_core_check_payload_type_usability(lc,codec) && 
544                     linphone_core_payload_type_enabled(lc,codec)){
545                         sdp_payload_t payload;
546                         sdp_payload_init(&payload);
547                         payload.line=1;
548                         payload.a_rtpmap=ortp_strdup_printf("%s/%i",codec->mime_type,codec->clock_rate);
549                         payload.localport=call->video_params.natd_port>0 ?
550                                         call->video_params.natd_port : lc->rtp_conf.video_rtp_port;
551                         payload.pt=find_payload_type_number(lc->local_profile,codec);
552                         payload.a_fmtp=codec->recv_fmtp;
553                         if(firsttime){
554                                 firsttime=FALSE;
555                                 if (lc->dw_video_bw>0)
556                                         payload.b_as_bandwidth=lc->dw_video_bw;
557                         }
558                         sdp_context_add_video_payload(ctx,&payload);
559                         ms_free(payload.a_rtpmap);
560                 }
561         }
562         return 0;
563 }
564
565 typedef enum {
566         Unsupported,
567         Supported,
568         SupportedAndValid  /* valid= the presence of this codec is enough to make a call */
569 }SupportLevel;
570
571 SupportLevel linphone_payload_is_supported(LinphoneCore *lc, sdp_payload_t *payload,RtpProfile *local_profile,RtpProfile *dialog_profile, bool_t answering, PayloadType **local_payload_type)
572 {
573         int localpt;
574         SupportLevel ret;
575         if (payload->a_rtpmap!=NULL){
576                 localpt=find_payload_type_number_best_match(local_profile,payload->a_rtpmap,payload->a_fmtp);
577         }else{
578                 localpt=payload->pt;
579                 ms_warning("payload has no rtpmap.");
580         }
581
582         if (localpt>=0 && localpt <128 ){
583                 /* this payload is understood, but does the user want to use it ?? */
584                 PayloadType *rtppayload;
585                 rtppayload=rtp_profile_get_payload(local_profile,localpt);
586                 if (rtppayload==NULL) {
587                         ms_warning("strange error !!");
588                         return Unsupported;
589                 }
590                 *local_payload_type=rtppayload;
591                 if (strcmp(rtppayload->mime_type,"telephone-event")!=0){
592                         if (answering && !linphone_core_check_payload_type_usability(lc,rtppayload) ){
593                                 ms_warning("payload %s is not usable",rtppayload->mime_type);
594                                 return Unsupported;
595                         }
596                         if ( !linphone_core_payload_type_enabled(lc,rtppayload)) {
597                                 ms_warning("payload %s is not enabled.",rtppayload->mime_type);
598                                 return Unsupported;
599                         }
600                         ret=SupportedAndValid;
601                 }else ret=Supported;
602                 if (dialog_profile!=NULL){
603                         int dbw,ubw;
604                         /* this payload is supported in our local rtp profile, so add it to the dialog rtp
605                         profile */
606                         rtppayload=payload_type_clone(rtppayload);
607                         if (rtp_profile_get_payload(dialog_profile,payload->pt)!=NULL){
608                                 ms_error("Payload %s type already entered, should not happen !",rtppayload->mime_type);
609                         }
610                         rtp_profile_set_payload(dialog_profile,payload->pt,rtppayload);
611                         /* add to the rtp payload type some other parameters (bandwidth) */
612                         if (rtppayload->type==PAYLOAD_VIDEO){
613                                 dbw=lc->dw_video_bw;
614                                 ubw=lc->up_video_bw;
615                         }else{
616                                 dbw=lc->dw_audio_bw;
617                                 ubw=lc->up_audio_bw;
618                         }
619                         if (payload->b_as_bandwidth!=0){
620                                 ms_message("Remote bandwidth constraint: %i",payload->b_as_bandwidth);
621                                 /*obey to remote bandwidth constraint AND our own upbandwidth constraint*/
622                                 rtppayload->normal_bitrate=1000*get_min_bandwidth(
623                                         payload->b_as_bandwidth, ubw);
624                         }else{
625                                 /*limit to upload bandwidth if exist, else no limit*/
626                                 if (ubw>0) rtppayload->normal_bitrate=1000*ubw;
627                                 else {
628                                         if (rtppayload->type!=PAYLOAD_VIDEO){
629                                                 rtppayload->normal_bitrate=-1; /*allow speex to use maximum bitrate*/
630                                         }
631                                 }
632                         }
633                         if (payload->a_fmtp!=NULL){
634                                 payload_type_set_send_fmtp(rtppayload,payload->a_fmtp);
635                         }
636                         payload->a_fmtp=rtppayload->recv_fmtp;
637                         if (payload->a_ptime>0){
638                                 char tmp[30];
639                                 snprintf(tmp,sizeof(tmp),"ptime=%i",payload->a_ptime);
640                                 payload_type_append_send_fmtp(rtppayload,tmp);
641                                 ms_message("%s attribute added to fmtp",tmp);
642                         }
643                 }
644                 return ret;
645         }
646         return Unsupported;
647 }
648
649 int linphone_accept_audio_offer(sdp_context_t *ctx,sdp_payload_t *payload)
650 {
651         RtpProfile *remote_profile;
652         StreamParams *params;
653         SupportLevel supported;
654         LinphoneCall *call=(LinphoneCall*)sdp_context_get_user_pointer(ctx);
655         LinphoneCore *lc=call->core;
656         PayloadType *lpt=NULL;
657
658         params=&call->audio_params;
659         remote_profile=call->profile;
660         /* see if this codec is supported in our local rtp profile*/
661         supported=linphone_payload_is_supported(lc,payload,lc->local_profile,remote_profile,TRUE,&lpt);
662         if (supported==Unsupported) {
663                 ms_message("Refusing audio codec %i (%s)",payload->pt,payload->a_rtpmap);
664                 return -1;
665         }
666         if (lc->sip_conf.only_one_codec && params->initialized){
667                 ms_message("Only one codec has to be accepted.");
668                 return -1;
669         }
670         if (supported==SupportedAndValid) {
671                 if (params->initialized==0){
672                         /* this is the first codec we accept, it is going to be used*/
673                         params->localport=lc->rtp_conf.audio_rtp_port;
674                         payload->localport=params->natd_port>0 ?
675                                 params->natd_port : lc->rtp_conf.audio_rtp_port;
676                         params->line=payload->line;
677                         params->pt=payload->pt; /* remember the first payload accepted */
678                         if (payload->relay_host!=NULL){
679                                 strncpy(params->remoteaddr,payload->relay_host,sizeof(params->remoteaddr)-1);
680                                 params->remoteport=payload->relay_port;
681                                 params->remotertcpport=payload->relay_port;
682                                 params->relay_session_id=payload->relay_session_id;
683                         }else{
684                                 strncpy(params->remoteaddr,payload->c_addr,sizeof(params->remoteaddr)-1);
685                                 params->remoteport=payload->remoteport;
686                                 params->remotertcpport=payload->remoteport+1;
687                         }
688                         params->initialized=1;
689                         /* we can now update the allocated bandwidth for audio, and then video*/
690                         linphone_core_update_allocated_audio_bandwidth_in_call(lc,lpt);
691                         /* give our download bandwidth constraint*/
692                         payload->b_as_bandwidth=(lc->dw_audio_bw>0) ? lc->dw_audio_bw : 0;
693                 }else{
694                         /* refuse all other audio lines*/
695                         if(params->line!=payload->line) {
696                                 ms_message("Only one audio line can be accepted.");
697 #if !defined(_WIN32_WCE)
698                                 abort();
699 #endif /*_WIN32_WCE*/
700                                 return -1;
701                         }
702                 }
703         }
704         return 0;
705 }
706
707 int linphone_accept_video_offer(sdp_context_t *ctx,sdp_payload_t *payload)
708 {
709         LinphoneCall *call=(LinphoneCall*)sdp_context_get_user_pointer(ctx);
710         LinphoneCore *lc=call->core;
711         RtpProfile *remote_profile;
712         StreamParams *params;
713         SupportLevel supported;
714         PayloadType *lpt=NULL;
715
716         if (!linphone_core_video_enabled(lc)) return -1;
717
718         if (payload->remoteport==0) {
719                 ms_message("Video stream refused by remote.");
720                 return 0;
721         }
722
723         params=&call->video_params;
724         remote_profile=call->profile;
725         /* see if this codec is supported in our local rtp profile*/
726         supported=linphone_payload_is_supported(lc,payload,lc->local_profile,remote_profile,TRUE,&lpt);
727         if (supported==Unsupported) {
728                 ms_message("Refusing video codec %i (%s)",payload->pt,payload->a_rtpmap);
729                 return -1;
730         }
731         if (lc->sip_conf.only_one_codec && params->initialized){
732                 return -1;
733         }
734         if (supported==SupportedAndValid){
735                 if (params->initialized==0){
736                         /* this is the first codec we may accept*/
737                         params->localport=lc->rtp_conf.video_rtp_port;
738                         payload->localport=params->natd_port>0 ? params->natd_port : lc->rtp_conf.video_rtp_port;
739                         params->line=payload->line;
740                         params->pt=payload->pt; /* remember the first payload accepted */
741                         if (payload->relay_host!=NULL){
742                                 strncpy(params->remoteaddr,payload->relay_host,sizeof(params->remoteaddr)-1);
743                                 params->remoteport=payload->relay_port;
744                                 params->remotertcpport=payload->relay_port;
745                                 params->relay_session_id=payload->relay_session_id;
746                         }else{
747                                 strncpy(params->remoteaddr,payload->c_addr,sizeof(params->remoteaddr)-1);
748                                 params->remoteport=payload->remoteport;
749                                 params->remotertcpport=params->remoteport+1;
750                         }
751                         params->initialized=1;
752                         payload->b_as_bandwidth=(lc->dw_video_bw>0) ? lc->dw_video_bw : 0;
753                 }else{
754                         /* refuse all other video lines*/
755                         if(params->line!=payload->line) return -1;
756                 }
757         }
758         return 0;
759 }
760
761 int linphone_read_audio_answer(sdp_context_t *ctx,sdp_payload_t *payload)
762 {
763         LinphoneCall *call=(LinphoneCall*)sdp_context_get_user_pointer(ctx);
764         LinphoneCore *lc=call->core;
765         StreamParams *params;
766         SupportLevel supported;
767         PayloadType *lpt=NULL;
768
769         /* paranoid check: see if this codec is supported in our local rtp profile*/
770         supported=linphone_payload_is_supported(lc, payload,lc->local_profile,call->profile,FALSE,&lpt);
771         if (supported==Unsupported) {
772                 ms_warning("This remote sip phone did not answer properly to my sdp offer: rtpmap=%s",payload->a_rtpmap);
773                 return 0;
774         }
775         if (supported==SupportedAndValid){
776                 params=&call->audio_params;
777                 if (params->initialized==0){
778                         /* this is the first codec we accept, this is the one that is going to be used (at least for sending
779                         data.*/
780                         params->localport=lc->rtp_conf.audio_rtp_port;
781                         params->line=payload->line;
782                         params->pt=payload->pt; /* remember the first payload accepted */
783                         if (payload->relay_host!=NULL){
784                                 strncpy(params->remoteaddr,payload->relay_host,sizeof(params->remoteaddr)-1);
785                                 params->remoteport=payload->relay_port;
786                                 params->remotertcpport=payload->relay_port;
787                                 params->relay_session_id=payload->relay_session_id;
788                         }else{
789                                 strncpy(params->remoteaddr,payload->c_addr,sizeof(params->remoteaddr)-1);
790                                 params->remoteport=payload->remoteport;
791                                 params->remotertcpport=payload->remoteport+1;
792                         }
793                         params->initialized=1;
794                         /* we can now update the allocated bandwidth for audio, and then video*/
795                         linphone_core_update_allocated_audio_bandwidth_in_call(lc,lpt);
796                 }
797         }
798         return 0;
799 }
800
801 int linphone_read_video_answer(sdp_context_t *ctx,sdp_payload_t *payload)
802 {
803         LinphoneCall *call=(LinphoneCall*)sdp_context_get_user_pointer(ctx);
804         LinphoneCore *lc=call->core;
805         StreamParams *params;
806         SupportLevel supported;
807         PayloadType *lpt=NULL;
808
809         /* paranoid check: see if this codec is supported in our local rtp profile*/
810         supported=linphone_payload_is_supported(lc, payload,lc->local_profile,call->profile,FALSE,&lpt);
811         if (supported==Unsupported) {
812                 ms_warning("This remote sip phone did not answer properly to my sdp offer: rtpmap=%s",payload->a_rtpmap);
813                 return 0;
814         }
815         if (supported==SupportedAndValid){
816                 params=&call->video_params;
817                 if (params->initialized==0){
818                         /* this is the first codec we may accept*/
819                         params->localport=lc->rtp_conf.video_rtp_port;
820                         params->line=payload->line;
821                         params->pt=payload->pt; /* remember the first payload accepted */
822                         if (payload->relay_host!=NULL){
823                                 strncpy(params->remoteaddr,payload->relay_host,sizeof(params->remoteaddr)-1);
824                                 params->remoteport=payload->relay_port;
825                                 params->remotertcpport=payload->relay_port;
826                                 params->relay_session_id=payload->relay_session_id;
827                         }else{
828                                 strncpy(params->remoteaddr,payload->c_addr,sizeof(params->remoteaddr)-1);
829                                 params->remoteport=payload->remoteport;
830                                 params->remotertcpport=payload->remoteport+1;
831                         }
832                         params->initialized=1;
833                 }
834         }
835         return 0;
836 }
837
838 void linphone_call_ringing(LinphoneCore *lc, eXosip_event_t *ev){
839         sdp_message_t *sdp=eXosip_get_sdp_info(ev->response);
840         LinphoneCall *call=lc->call;
841
842         lc->vtable.display_status(lc,_("Remote ringing."));
843         linphone_call_proceeding(lc,ev);
844         if (call==NULL) return;
845         if (sdp==NULL){
846                 if (lc->ringstream!=NULL) return;       /*already ringing !*/
847                 if (lc->sound_conf.play_sndcard!=NULL){
848                         ms_message("Remote ringing...");
849                         lc->ringstream=ring_start(lc->sound_conf.remote_ring,2000,lc->sound_conf.play_sndcard);
850                 }
851         }else{
852                 /*accept early media */
853                 StreamParams *audio_params;
854                 if (call==NULL){
855                         ms_error("No call ?");
856                         goto end;
857                 }
858                 if (lc->audiostream->ticker!=NULL){
859                         /*streams already started */
860                         ms_message("Early media already started.");
861                         goto end;
862                 }
863                 audio_params=&call->audio_params;
864                 sdp_context_read_answer(lc->call->sdpctx,sdp);
865                 lc->vtable.show(lc);
866                 lc->vtable.display_status(lc,_("Early media."));
867                 gstate_new_state(lc, GSTATE_CALL_OUT_CONNECTED, NULL);
868                 if (lc->ringstream!=NULL){
869                         ring_stop(lc->ringstream);
870                         lc->ringstream=NULL;
871                 }
872                 ms_message("Doing early media...");
873                 linphone_core_start_media_streams(lc,call);
874         }
875         call->state=LCStateRinging;
876         goto end;
877         end:
878                 sdp_message_free(sdp);
879
880 }
881
882 static void linphone_process_media_control_xml(LinphoneCore *lc, eXosip_event_t *ev){
883         osip_body_t *body=NULL;
884         osip_message_get_body(ev->request,0,&body);
885         if (body && body->body!=NULL &&
886                 strstr(body->body,"picture_fast_update")){
887                 osip_message_t *ans=NULL;
888                 ms_message("Receiving VFU request !");
889 #ifdef VIDEO_ENABLED
890                 if (lc->videostream)
891                         video_stream_send_vfu(lc->videostream);
892 #endif
893                 eXosip_call_build_answer(ev->tid,200,&ans);
894                 if (ans)
895                         eXosip_call_send_answer(ev->tid,200,ans);
896         }
897 }
898
899 static void linphone_process_dtmf_relay(LinphoneCore *lc, eXosip_event_t *ev){
900         osip_body_t *body=NULL;
901         osip_message_get_body(ev->request,0,&body);
902         if (body && body->body!=NULL){
903                 osip_message_t *ans=NULL;
904                 const char *name=strstr(body->body,"Signal");
905                 if (name==NULL) name=strstr(body->body,"signal");
906                 if (name==NULL) {
907                         ms_warning("Could not extract the dtmf name from the SIP INFO.");
908                 }else{
909                         char tmp[2];
910                         name+=strlen("signal");
911                         if (sscanf(name," = %1s",tmp)==1){
912                                 ms_message("Receiving dtmf %s via SIP INFO.",tmp);
913                                 if (lc->vtable.dtmf_received != NULL)
914                                         lc->vtable.dtmf_received(lc, tmp[0]);
915                         }
916                 }
917
918                 eXosip_call_build_answer(ev->tid,200,&ans);
919                 if (ans)
920                         eXosip_call_send_answer(ev->tid,200,ans);
921         }
922 }
923
924 void linphone_call_message_new(LinphoneCore *lc, eXosip_event_t *ev){
925         osip_message_t *ans=NULL;
926         if (ev->request){
927                 if (MSG_IS_INFO(ev->request)){
928                         osip_content_type_t *ct;
929                         ct=osip_message_get_content_type(ev->request);
930                         if (ct && ct->subtype){
931                                 if (strcmp(ct->subtype,"media_control+xml")==0)
932                                         linphone_process_media_control_xml(lc,ev);
933                                 else if (strcmp(ct->subtype,"dtmf-relay")==0)
934                                         linphone_process_dtmf_relay(lc,ev);
935                                 else {
936                                         ms_message("Unhandled SIP INFO.");
937                                         /*send an "Not implemented" answer*/
938                                         eXosip_call_build_answer(ev->tid,501,&ans);
939                                         if (ans)
940                                                 eXosip_call_send_answer(ev->tid,501,ans);
941                                 }
942                         }else{
943                                 /*empty SIP INFO, probably to test we are alive. Send an empty answer*/
944                                 eXosip_call_build_answer(ev->tid,200,&ans);
945                                         if (ans)
946                                                 eXosip_call_send_answer(ev->tid,200,ans);
947                         }
948                 }
949         }else ms_warning("linphone_call_message_new: No request ?");
950 }
951
952 void linphone_registration_faillure(LinphoneCore *lc, eXosip_event_t *ev){
953         int status_code=0;
954         char *msg;
955         const char *reason=NULL;
956         osip_uri_t *requri=osip_message_get_uri(ev->request);
957         char *ru;
958         LinphoneProxyConfig *cfg;
959
960         if (ev->response){
961                 status_code=osip_message_get_status_code(ev->response);
962                 reason=osip_message_get_reason_phrase(ev->response);
963         }
964         switch(status_code){
965                 case 401:
966                 case 407:
967                         linphone_process_authentication(lc,ev);
968                         break;
969                 default:
970                         cfg=linphone_core_get_proxy_config_from_rid(lc,ev->rid);
971                         /* if contact is up to date, process the failure, otherwise resend a new register with
972                                 updated contact first, just in case the faillure is due to incorrect contact */
973                         if (linphone_proxy_config_register_again_with_updated_contact(cfg,ev->request,ev->response))
974                                 return; /*we are retrying with an updated contact*/
975                         linphone_proxy_config_process_authentication_failure(lc,status_code,ev);
976                         osip_uri_to_str(requri,&ru);
977                         msg=ortp_strdup_printf(_("Registration on %s failed: %s"),ru,(reason!=NULL) ? reason : _("no response timeout"));
978                         lc->vtable.display_status(lc,msg);
979                         gstate_new_state(lc, GSTATE_REG_FAILED, msg);
980                         ms_free(msg);
981                         osip_free(ru);
982         }
983 }
984
985 void linphone_registration_success(LinphoneCore *lc,eXosip_event_t *ev){
986         LinphoneProxyConfig *cfg;
987         osip_uri_t *requri=osip_message_get_uri(ev->request);
988         char *msg;
989         char *ru;
990         osip_header_t *h=NULL;
991
992         cfg=linphone_core_get_proxy_config_from_rid(lc,ev->rid);
993         ms_return_if_fail(cfg!=NULL);
994
995         osip_message_get_expires(ev->request,0,&h);
996         if (h!=NULL && atoi(h->hvalue)!=0){
997                 cfg->registered=TRUE;
998                 linphone_proxy_config_register_again_with_updated_contact(cfg,ev->request,ev->response);
999         }else cfg->registered=FALSE;
1000         
1001         gstate_new_state(lc, GSTATE_REG_OK, NULL);
1002
1003         osip_uri_to_str(requri,&ru);
1004         if (cfg->registered) msg=ms_strdup_printf(_("Registration on %s successful."),ru);
1005         else msg=ms_strdup_printf(_("Unregistration on %s done."),ru);
1006         lc->vtable.display_status(lc,msg);
1007         ms_free(msg);
1008         osip_free(ru);
1009 }
1010
1011 static bool_t comes_from_local_if(osip_message_t *msg){
1012         osip_via_t *via=NULL;
1013         osip_message_get_via(msg,0,&via);
1014         if (via){
1015                 const char *host;
1016                 host=osip_via_get_host(via);
1017                 if (strcmp(host,"127.0.0.1")==0 || strcmp(host,"::1")==0){
1018                         osip_generic_param_t *param=NULL;
1019                         osip_via_param_get_byname(via,"received",&param);
1020                         if (param==NULL) return TRUE;
1021                         if (param->gvalue &&
1022                                 (strcmp(param->gvalue,"127.0.0.1")==0 || strcmp(param->gvalue,"::1")==0)){
1023                                 return TRUE;
1024                         }
1025                 }
1026         }
1027         return FALSE;
1028 }
1029
1030 static void linphone_inc_update(LinphoneCore *lc, eXosip_event_t *ev){
1031         osip_message_t *msg=NULL;
1032         ms_message("Processing incoming UPDATE");
1033         eXosip_lock();
1034         eXosip_message_build_answer(ev->tid,200,&msg);
1035         if (msg!=NULL)
1036                 eXosip_message_send_answer(ev->tid,200,msg);
1037         eXosip_unlock();
1038 }
1039
1040 static void linphone_other_request(LinphoneCore *lc, eXosip_event_t *ev){
1041         ms_message("in linphone_other_request");
1042         if (ev->request==NULL) return;
1043         if (strcmp(ev->request->sip_method,"MESSAGE")==0){
1044                 linphone_core_text_received(lc,ev);
1045                 eXosip_message_send_answer(ev->tid,200,NULL);
1046         }else if (strcmp(ev->request->sip_method,"OPTIONS")==0){
1047                 osip_message_t *options=NULL;
1048                 eXosip_options_build_answer(ev->tid,200,&options);
1049                 osip_message_set_allow(options,"INVITE, ACK, BYE, CANCEL, OPTIONS, MESSAGE, SUBSCRIBE, NOTIFY, INFO");
1050                 osip_message_set_accept(options,"application/sdp");
1051                 eXosip_options_send_answer(ev->tid,200,options);
1052         }else if (strcmp(ev->request->sip_method,"WAKEUP")==0
1053                 && comes_from_local_if(ev->request)) {
1054                 eXosip_message_send_answer(ev->tid,200,NULL);
1055                 ms_message("Receiving WAKEUP request !");
1056                 if (lc->vtable.show)
1057                         lc->vtable.show(lc);
1058         }else if (strncmp(ev->request->sip_method, "REFER", 5) == 0){
1059                 ms_message("Receiving REFER request !");
1060                 if (comes_from_local_if(ev->request)) {
1061                         osip_header_t *h=NULL;
1062                         osip_message_header_get_byname(ev->request,"Refer-To",0,&h);
1063                         eXosip_message_send_answer(ev->tid,200,NULL);
1064                         if (h){
1065                                 if (lc->vtable.refer_received)
1066                                         lc->vtable.refer_received(lc,h->hvalue);
1067                         }
1068
1069                 }else ms_warning("Ignored REFER not coming from this local loopback interface.");
1070         }else if (strncmp(ev->request->sip_method, "UPDATE", 6) == 0){
1071                 linphone_inc_update(lc,ev);
1072         }else {
1073                 char *tmp=NULL;
1074                 size_t msglen=0;
1075                 osip_message_to_str(ev->request,&tmp,&msglen);
1076                 if (tmp){
1077                         ms_message("Unsupported request received:\n%s",tmp);
1078                         osip_free(tmp);
1079                 }
1080                 /*answer with a 501 Not implemented*/
1081                 eXosip_message_send_answer(ev->tid,501,NULL);
1082         }
1083 }
1084
1085 void linphone_core_process_event(LinphoneCore *lc,eXosip_event_t *ev)
1086 {
1087         switch(ev->type){
1088                 case EXOSIP_CALL_ANSWERED:
1089                         ms_message("CALL_ANSWERED\n");
1090                         linphone_call_accepted(lc,ev);
1091                         linphone_authentication_ok(lc,ev);
1092                         break;
1093                 case EXOSIP_CALL_CLOSED:
1094                 case EXOSIP_CALL_CANCELLED:
1095                         ms_message("CALL_CLOSED or CANCELLED\n");
1096                         linphone_call_terminated(lc,ev);
1097                         break;
1098                 case EXOSIP_CALL_TIMEOUT:
1099                 case EXOSIP_CALL_NOANSWER:
1100                         ms_message("CALL_TIMEOUT or NOANSWER\n");
1101                         linphone_call_failure(lc,ev);
1102                         break;
1103                 case EXOSIP_CALL_REQUESTFAILURE:
1104                 case EXOSIP_CALL_GLOBALFAILURE:
1105                 case EXOSIP_CALL_SERVERFAILURE:
1106                         ms_message("CALL_REQUESTFAILURE or GLOBALFAILURE or SERVERFAILURE\n");
1107                         linphone_call_failure(lc,ev);
1108                         break;
1109                 case EXOSIP_CALL_INVITE:
1110                         ms_message("CALL_NEW\n");
1111                         /* CALL_NEW is used twice in qos mode :
1112                          * when you receive invite (textinfo = "With QoS" or "Without QoS")
1113                          * and when you receive update (textinfo = "New Call") */
1114                         linphone_inc_new_call(lc,ev);
1115                         break;
1116                 case EXOSIP_CALL_REINVITE:
1117                         linphone_handle_reinvite(lc,ev);
1118                         break;
1119                 case EXOSIP_CALL_ACK:
1120                         ms_message("CALL_ACK");
1121                         linphone_handle_ack(lc,ev);
1122                         break;
1123                 case EXOSIP_CALL_REDIRECTED:
1124                         ms_message("CALL_REDIRECTED");
1125                         linphone_call_redirected(lc,ev);
1126                         break;
1127                 case EXOSIP_CALL_PROCEEDING:
1128                         ms_message("CALL_PROCEEDING");
1129                         linphone_call_proceeding(lc,ev);
1130                         break;
1131                 case EXOSIP_CALL_RINGING:
1132                         ms_message("CALL_RINGING");
1133                         linphone_call_ringing(lc,ev);
1134                         break;
1135                 case EXOSIP_CALL_MESSAGE_NEW:
1136                         ms_message("EXOSIP_CALL_MESSAGE_NEW");
1137                         linphone_call_message_new(lc,ev);
1138                         break;
1139                 case EXOSIP_CALL_MESSAGE_REQUESTFAILURE:
1140                         if (ev->did<0 && ev->response &&
1141                                 (ev->response->status_code==407 || ev->response->status_code==401)){
1142                                  eXosip_default_action(ev);
1143                         }
1144                         break;
1145                 case EXOSIP_IN_SUBSCRIPTION_NEW:
1146                         ms_message("CALL_SUBSCRIPTION_NEW or UPDATE");
1147                         linphone_subscription_new(lc,ev);
1148                         break;
1149                 case EXOSIP_SUBSCRIPTION_UPDATE:
1150                         break;
1151                 case EXOSIP_SUBSCRIPTION_NOTIFY:
1152                         ms_message("CALL_SUBSCRIPTION_NOTIFY");
1153                         linphone_notify_recv(lc,ev);
1154                         break;
1155                 case EXOSIP_SUBSCRIPTION_ANSWERED:
1156                         ms_message("EXOSIP_SUBSCRIPTION_ANSWERED, ev->sid=%i\n",ev->sid);
1157                         linphone_subscription_answered(lc,ev);
1158                         break;
1159                 case EXOSIP_SUBSCRIPTION_CLOSED:
1160                         ms_message("EXOSIP_SUBSCRIPTION_CLOSED\n");
1161                         linphone_subscription_closed(lc,ev);
1162                         break;
1163                 case EXOSIP_CALL_RELEASED:
1164                         ms_message("CALL_RELEASED\n");
1165                         linphone_call_released(lc, ev->cid);
1166                         break;
1167                 case EXOSIP_REGISTRATION_FAILURE:
1168                         ms_message("REGISTRATION_FAILURE\n");
1169                         linphone_registration_faillure(lc,ev);
1170                         break;
1171                 case EXOSIP_REGISTRATION_SUCCESS:
1172                         linphone_authentication_ok(lc,ev);
1173                         linphone_registration_success(lc,ev);
1174                         break;
1175                 case EXOSIP_MESSAGE_NEW:
1176                         linphone_other_request(lc,ev);
1177                         break;
1178                 case EXOSIP_MESSAGE_REQUESTFAILURE:
1179                         if (ev->response && (ev->response->status_code == 407 || ev->response->status_code == 401)){
1180                                 /*the user is expected to have registered to the proxy, thus password is known*/
1181                                 eXosip_default_action(ev);
1182                         }
1183                         break;
1184                 default:
1185                         ms_message("Unhandled exosip event !");
1186                         break;
1187         }
1188         eXosip_event_free(ev);
1189 }