3 Copyright (C) 2000 Simon MORLAT (simon.morlat@free.fr)
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.
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.
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.
21 #include "linphonecore.h"
23 #include "mediastreamer2/mediastream.h"
24 #include <eXosip2/eXosip.h>
25 #include <osipparser2/osip_message.h>
26 #include <osipparser2/osip_parser.h>
28 static int linphone_answer_sdp(LinphoneCore *lc, eXosip_event_t *ev, sdp_message_t *sdp);
30 static bool_t linphone_call_matches_event(LinphoneCall *call, eXosip_event_t *ev){
31 return call->cid==ev->cid;
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->cid,ev->cid);
39 eXosip_call_terminate(ev->cid,ev->did);
43 lc->call->cid=ev->cid;
44 lc->call->did=ev->did;
45 lc->call->tid=ev->tid;
48 static void linphone_connect_incoming(LinphoneCore *lc){
50 lc->vtable.display_status(lc,_("Connected."));
51 lc->call->state=LCStateAVRunning;
52 if (lc->ringstream!=NULL){
53 ring_stop(lc->ringstream);
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);
61 linphone_core_start_media_streams(lc,lc->call);
64 int linphone_call_accepted(LinphoneCore *lc, eXosip_event_t *ev)
66 LinphoneCall *call=lc->call;
68 const char *sdpanswer=NULL;
69 osip_message_t *msg=NULL;
72 ms_warning("No call to accept.");
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*/
81 linphone_call_init_media_params(call);
82 sdp=eXosip_get_sdp_info(ev->response);
83 if (!lc->sip_conf.sdp_200_ack){
85 sdp_context_read_answer(call->sdpctx,sdp);
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;
92 gstate_new_state(lc, GSTATE_CALL_OUT_CONNECTED, NULL);
93 linphone_connect_incoming(lc);
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);
101 ms_error("Incompatible SDP offer received in 200Ok, need to abort the call");
102 linphone_core_terminate_call(lc,NULL);
104 sdp_message_free(sdp);
109 int linphone_call_terminated(LinphoneCore *lc, eXosip_event_t *ev)
111 /*stop ringing if necessary*/
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);
120 ms_message("Current call terminated...");
121 if (lc->ringstream!=NULL) {
122 ring_stop(lc->ringstream);
125 linphone_core_stop_media_streams(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){
131 osip_from_to_str(ev->request->from,&from);
132 lc->vtable.bye_recv(lc,from);
136 linphone_call_destroy(lc->call);
143 int linphone_call_released(LinphoneCore *lc, int cid){
144 LinphoneCall *call=lc->call;
145 if (call!=NULL && call->cid==cid){
147 linphone_call_destroy(lc->call);
149 lc->vtable.display_status(lc,_("Could not reach destination."));
150 gstate_new_state(lc, GSTATE_CALL_ERROR, NULL);
155 int linphone_call_failure(LinphoneCore *lc, eXosip_event_t *ev)
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.");
166 LinphoneCall *call=lc->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.");
177 code=osip_message_get_status_code(ev->response);
178 reason=osip_message_get_reason_phrase(ev->response);
187 linphone_process_authentication(lc,ev);
191 lc->vtable.display_status(lc,_("Bad request"));
194 lc->vtable.display_status(lc,_("User cannot be found at given address."));
197 lc->vtable.display_status(lc,_("Remote user cannot support any of proposed codecs."));
200 /*ignore: eXosip_automatic_action will do the job of retrying with a greater Session-Expires*/
207 msg_header_getbyname(msg,"retry-after",0,&retry);
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);
215 lc->vtable.display_message(lc,tmpmsg);
218 lc->vtable.display_status(lc,msg487);
221 lc->vtable.display_message(lc,msg600);
224 lc->vtable.display_status(lc,msg603);
226 case -110: /* time out, call leg is lost */
227 lc->vtable.display_status(lc,_("Timeout."));
230 lc->vtable.display_status(lc,_("Remote host was found but refused connection."));
236 lc->vtable.display_status(lc,reason);
238 else ms_warning("failure_cb unknown code=%i\n",code);
240 if (lc->ringstream!=NULL) {
241 ring_stop(lc->ringstream);
244 linphone_core_stop_media_streams(lc);
246 linphone_call_destroy(call);
247 gstate_new_state(lc, GSTATE_CALL_ERROR, NULL);
253 extern sdp_handler_t linphone_sdphandler;
255 static int linphone_answer_sdp(LinphoneCore *lc, eXosip_event_t *ev, sdp_message_t *sdp){
257 sdp_context_t *ctx=NULL;
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);
265 linphone_core_init_media_streams(lc);
268 if (status==-1) status=415;
273 int linphone_inc_new_call(LinphoneCore *lc, eXosip_event_t *ev)
275 sdp_message_t *sdp=NULL;
276 osip_from_t *from_url=ev->request->from;
282 osip_from_to_str(ev->request->from,&from);
283 osip_to_to_str(ev->request->to,&to);
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);
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)
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);
306 else if (lc->alt_contact!=NULL && lc->presence_mode==LINPHONE_STATUS_ALT_SERVICE)
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);
314 eXosip_call_send_answer(ev->tid,486,NULL);
318 if (lc->call!=NULL){/*busy*/
320 eXosip_call_send_answer(ev->tid,486,NULL);
324 lc->call=linphone_call_new_incoming(lc,linphone_address_new(from),linphone_address_new(to),ev);
326 sdp=eXosip_get_sdp_info(ev->request);
328 ms_message("No sdp body in invite, 200-ack scheme");
331 err=linphone_answer_sdp(lc,ev,sdp);
335 if (from_2char_without_params(from_url,&tmp)!=0){
336 tmp=ms_strdup("Unknown user");
338 gstate_new_state(lc, GSTATE_CALL_IN_INVITE, tmp);
339 barmesg=ortp_strdup_printf("%s %s",tmp,_("is contacting you."));
341 lc->vtable.display_status(lc,barmesg);
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);
348 linphone_call_set_state(lc->call,LCStateRinging);
350 eXosip_call_send_answer(ev->tid,180,NULL);
353 lc->vtable.inv_recv(lc,tmp);
357 ms_error("Error during sdp negociation. ");
359 eXosip_call_send_answer(ev->tid,415,NULL);
361 linphone_call_destroy(lc->call);
367 if (sdp) sdp_message_free(sdp);
371 void linphone_handle_ack(LinphoneCore *lc, eXosip_event_t *ev){
372 sdp_message_t *sdp=eXosip_get_sdp_info(ev->ack);
374 sdp_context_read_answer(lc->call->sdpctx,sdp);
375 linphone_connect_incoming(lc);
376 sdp_message_free(sdp);
380 void linphone_handle_reinvite(LinphoneCore *lc, eXosip_event_t *ev){
381 sdp_message_t *sdp=eXosip_get_sdp_info(ev->request);
383 LinphoneCall *call=lc->call;
387 ms_warning("No sdp in reinvite !");
389 eXosip_call_send_answer(ev->tid,603,NULL);
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);
399 osip_message_t *msg=NULL;
400 linphone_core_stop_media_streams(lc);
401 linphone_core_init_media_streams(lc);
403 if (eXosip_call_build_answer(ev->tid,200,&msg)<0){
404 ms_warning("Reinvite for closed call ?");
406 linphone_core_stop_media_streams(lc);
407 sdp_message_free(sdp);
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);
414 linphone_core_start_media_streams(lc,call);
417 eXosip_call_send_answer(ev->tid,status,NULL);
420 sdp_message_free(sdp);
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);
427 if (lc->call!=NULL) linphone_call_destroy(lc->call);
429 linphone_core_invite(lc,contact);
432 void linphone_call_redirected(LinphoneCore *lc, eXosip_event_t *ev){
433 int code=osip_message_get_status_code(ev->response);
436 osip_message_get_contact(ev->response,0,&ct);
437 if (ct) osip_contact_to_str(ct,&contact);
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);
445 linphone_do_automatic_redirect(lc,contact);
448 if (contact) osip_free(contact);
452 /* these are the SdpHandler callbacks: we are called in to be aware of the content
453 of the SDP messages exchanged */
455 int linphone_set_audio_offer(sdp_context_t *ctx)
457 LinphoneCall *call=(LinphoneCall*)sdp_context_get_user_pointer(ctx);
458 LinphoneCore *lc=call->core;
461 sdp_payload_t payload;
464 elem=lc->codecs_conf.audio_codecs;
466 codec=(PayloadType*) elem->data;
467 if (linphone_core_check_payload_type_usability(lc,codec) && payload_type_enabled(codec)){
468 sdp_payload_init(&payload);
469 payload.a_rtpmap=ortp_strdup_printf("%s/%i/1",codec->mime_type,codec->clock_rate);
470 payload.pt=rtp_profile_get_payload_number_from_rtpmap(lc->local_profile,payload.a_rtpmap);
471 payload.localport=call->audio_params.natd_port > 0 ?
472 call->audio_params.natd_port : lc->rtp_conf.audio_rtp_port;
473 if (strcasecmp(codec->mime_type,"iLBC")==0){
474 /* prefer the 30 ms mode */
475 payload.a_fmtp="ptime=30";
477 sdp_context_add_audio_payload(ctx,&payload);
478 ms_free(payload.a_rtpmap);
480 elem=ms_list_next(elem);
482 /* add telephone-event payload*/
483 sdp_payload_init(&payload);
484 payload.pt=rtp_profile_get_payload_number_from_mime(lc->local_profile,"telephone-event");
485 payload.a_rtpmap="telephone-event/8000";
486 payload.a_fmtp="0-11";
487 if (lc->dw_audio_bw>0) payload.b_as_bandwidth=lc->dw_audio_bw;
488 sdp_context_add_audio_payload(ctx,&payload);
492 static int find_payload_type_number(RtpProfile *prof, PayloadType *pt){
496 it=rtp_profile_get_payload(prof,i);
497 if (it!=NULL && strcasecmp(pt->mime_type,it->mime_type)==0
498 && (pt->clock_rate==it->clock_rate || pt->clock_rate<=0) ){
499 if ( (pt->recv_fmtp && it->recv_fmtp && strcasecmp(pt->recv_fmtp,it->recv_fmtp)==0) ||
500 (pt->recv_fmtp==NULL && it->recv_fmtp==NULL) ){
506 if (candidate==-1) ms_fatal("Should not happen.");
510 static int find_payload_type_number_best_match(RtpProfile *prof, const char *rtpmap, const char *fmtp){
511 int localpt=rtp_profile_get_payload_number_from_rtpmap(prof,rtpmap);
514 if (localpt<0) return -1;
515 pt=rtp_profile_get_payload(prof,localpt);
516 if (strcasecmp(pt->mime_type,"H264")==0){
517 /*hack for H264: need to answer with same packetization-mode*/
519 memset(&tmp,0,sizeof(tmp));
520 tmp.mime_type="H264";
521 tmp.clock_rate=pt->clock_rate;
522 if (fmtp && fmtp_get_value(fmtp,"packetization-mode",value,sizeof(value))){
523 tmp.recv_fmtp=(atoi(value)==1) ? "packetization-mode=1" : NULL;
525 localpt=find_payload_type_number(prof,&tmp);
530 int linphone_set_video_offer(sdp_context_t *ctx)
532 LinphoneCall *call=(LinphoneCall*)sdp_context_get_user_pointer(ctx);
533 LinphoneCore *lc=call->core;
536 bool_t firsttime=TRUE;
538 if (!linphone_core_video_enabled(lc)) return -1;
540 for(elem=lc->codecs_conf.video_codecs;elem!=NULL;elem=ms_list_next(elem)){
541 codec=(PayloadType*) elem->data;
542 if (linphone_core_check_payload_type_usability(lc,codec) && payload_type_enabled(codec)){
543 sdp_payload_t payload;
544 sdp_payload_init(&payload);
546 payload.a_rtpmap=ortp_strdup_printf("%s/%i",codec->mime_type,codec->clock_rate);
547 payload.localport=call->video_params.natd_port>0 ?
548 call->video_params.natd_port : lc->rtp_conf.video_rtp_port;
549 payload.pt=find_payload_type_number(lc->local_profile,codec);
550 payload.a_fmtp=codec->recv_fmtp;
553 if (lc->dw_video_bw>0)
554 payload.b_as_bandwidth=lc->dw_video_bw;
556 sdp_context_add_video_payload(ctx,&payload);
557 ms_free(payload.a_rtpmap);
566 SupportedAndValid /* valid= the presence of this codec is enough to make a call */
569 SupportLevel linphone_payload_is_supported(LinphoneCore *lc, sdp_payload_t *payload,RtpProfile *local_profile,RtpProfile *dialog_profile, bool_t answering, PayloadType **local_payload_type)
573 if (payload->a_rtpmap!=NULL){
574 localpt=find_payload_type_number_best_match(local_profile,payload->a_rtpmap,payload->a_fmtp);
577 ms_warning("payload has no rtpmap.");
580 if (localpt>=0 && localpt <128 ){
581 /* this payload is understood, but does the user want to use it ?? */
582 PayloadType *rtppayload;
583 rtppayload=rtp_profile_get_payload(local_profile,localpt);
584 if (rtppayload==NULL) {
585 ms_warning("strange error !!");
588 *local_payload_type=rtppayload;
589 if (strcmp(rtppayload->mime_type,"telephone-event")!=0){
590 if (answering && !linphone_core_check_payload_type_usability(lc,rtppayload) ){
591 ms_warning("payload %s is not usable",rtppayload->mime_type);
594 if ( !payload_type_enabled(rtppayload)) {
595 ms_warning("payload %s is not enabled.",rtppayload->mime_type);
598 ret=SupportedAndValid;
600 if (dialog_profile!=NULL){
602 /* this payload is supported in our local rtp profile, so add it to the dialog rtp
604 rtppayload=payload_type_clone(rtppayload);
605 if (rtp_profile_get_payload(dialog_profile,payload->pt)!=NULL){
606 ms_error("Payload %s type already entered, should not happen !",rtppayload->mime_type);
608 rtp_profile_set_payload(dialog_profile,payload->pt,rtppayload);
609 /* add to the rtp payload type some other parameters (bandwidth) */
610 if (rtppayload->type==PAYLOAD_VIDEO){
617 if (payload->b_as_bandwidth!=0){
618 ms_message("Remote bandwidth constraint: %i",payload->b_as_bandwidth);
619 /*obey to remote bandwidth constraint AND our own upbandwidth constraint*/
620 rtppayload->normal_bitrate=1000*get_min_bandwidth(
621 payload->b_as_bandwidth, ubw);
623 /*limit to upload bandwidth if exist, else no limit*/
624 if (ubw>0) rtppayload->normal_bitrate=1000*ubw;
626 if (rtppayload->type!=PAYLOAD_VIDEO){
627 rtppayload->normal_bitrate=-1; /*allow speex to use maximum bitrate*/
631 if (payload->a_fmtp!=NULL){
632 payload_type_set_send_fmtp(rtppayload,payload->a_fmtp);
634 payload->a_fmtp=rtppayload->recv_fmtp;
635 if (payload->a_ptime>0){
637 snprintf(tmp,sizeof(tmp),"ptime=%i",payload->a_ptime);
638 payload_type_append_send_fmtp(rtppayload,tmp);
639 ms_message("%s attribute added to fmtp",tmp);
647 int linphone_accept_audio_offer(sdp_context_t *ctx,sdp_payload_t *payload)
649 RtpProfile *remote_profile;
650 StreamParams *params;
651 SupportLevel supported;
652 LinphoneCall *call=(LinphoneCall*)sdp_context_get_user_pointer(ctx);
653 LinphoneCore *lc=call->core;
654 PayloadType *lpt=NULL;
656 params=&call->audio_params;
657 remote_profile=call->profile;
658 /* see if this codec is supported in our local rtp profile*/
659 supported=linphone_payload_is_supported(lc,payload,lc->local_profile,remote_profile,TRUE,&lpt);
660 if (supported==Unsupported) {
661 ms_message("Refusing audio codec %i (%s)",payload->pt,payload->a_rtpmap);
664 if (lc->sip_conf.only_one_codec && params->initialized){
665 ms_message("Only one codec has to be accepted.");
668 if (supported==SupportedAndValid) {
669 if (params->initialized==0){
670 /* this is the first codec we accept, it is going to be used*/
671 params->localport=lc->rtp_conf.audio_rtp_port;
672 payload->localport=params->natd_port>0 ?
673 params->natd_port : lc->rtp_conf.audio_rtp_port;
674 params->line=payload->line;
675 params->pt=payload->pt; /* remember the first payload accepted */
676 if (payload->relay_host!=NULL){
677 strncpy(params->remoteaddr,payload->relay_host,sizeof(params->remoteaddr)-1);
678 params->remoteport=payload->relay_port;
679 params->remotertcpport=payload->relay_port;
680 params->relay_session_id=payload->relay_session_id;
682 strncpy(params->remoteaddr,payload->c_addr,sizeof(params->remoteaddr)-1);
683 params->remoteport=payload->remoteport;
684 params->remotertcpport=payload->remoteport+1;
686 params->initialized=1;
687 /* we can now update the allocated bandwidth for audio, and then video*/
688 linphone_core_update_allocated_audio_bandwidth_in_call(lc,lpt);
689 /* give our download bandwidth constraint*/
690 payload->b_as_bandwidth=(lc->dw_audio_bw>0) ? lc->dw_audio_bw : 0;
692 /* refuse all other audio lines*/
693 if(params->line!=payload->line) {
694 ms_message("Only one audio line can be accepted.");
695 #if !defined(_WIN32_WCE)
697 #endif /*_WIN32_WCE*/
705 int linphone_accept_video_offer(sdp_context_t *ctx,sdp_payload_t *payload)
707 LinphoneCall *call=(LinphoneCall*)sdp_context_get_user_pointer(ctx);
708 LinphoneCore *lc=call->core;
709 RtpProfile *remote_profile;
710 StreamParams *params;
711 SupportLevel supported;
712 PayloadType *lpt=NULL;
714 if (!linphone_core_video_enabled(lc)) return -1;
716 if (payload->remoteport==0) {
717 ms_message("Video stream refused by remote.");
721 params=&call->video_params;
722 remote_profile=call->profile;
723 /* see if this codec is supported in our local rtp profile*/
724 supported=linphone_payload_is_supported(lc,payload,lc->local_profile,remote_profile,TRUE,&lpt);
725 if (supported==Unsupported) {
726 ms_message("Refusing video codec %i (%s)",payload->pt,payload->a_rtpmap);
729 if (lc->sip_conf.only_one_codec && params->initialized){
732 if (supported==SupportedAndValid){
733 if (params->initialized==0){
734 /* this is the first codec we may accept*/
735 params->localport=lc->rtp_conf.video_rtp_port;
736 payload->localport=params->natd_port>0 ? params->natd_port : lc->rtp_conf.video_rtp_port;
737 params->line=payload->line;
738 params->pt=payload->pt; /* remember the first payload accepted */
739 if (payload->relay_host!=NULL){
740 strncpy(params->remoteaddr,payload->relay_host,sizeof(params->remoteaddr)-1);
741 params->remoteport=payload->relay_port;
742 params->remotertcpport=payload->relay_port;
743 params->relay_session_id=payload->relay_session_id;
745 strncpy(params->remoteaddr,payload->c_addr,sizeof(params->remoteaddr)-1);
746 params->remoteport=payload->remoteport;
747 params->remotertcpport=params->remoteport+1;
749 params->initialized=1;
750 payload->b_as_bandwidth=(lc->dw_video_bw>0) ? lc->dw_video_bw : 0;
752 /* refuse all other video lines*/
753 if(params->line!=payload->line) return -1;
759 int linphone_read_audio_answer(sdp_context_t *ctx,sdp_payload_t *payload)
761 LinphoneCall *call=(LinphoneCall*)sdp_context_get_user_pointer(ctx);
762 LinphoneCore *lc=call->core;
763 StreamParams *params;
764 SupportLevel supported;
765 PayloadType *lpt=NULL;
767 /* paranoid check: see if this codec is supported in our local rtp profile*/
768 supported=linphone_payload_is_supported(lc, payload,lc->local_profile,call->profile,FALSE,&lpt);
769 if (supported==Unsupported) {
770 ms_warning("This remote sip phone did not answer properly to my sdp offer: rtpmap=%s",payload->a_rtpmap);
773 if (supported==SupportedAndValid){
774 params=&call->audio_params;
775 if (params->initialized==0){
776 /* this is the first codec we accept, this is the one that is going to be used (at least for sending
778 params->localport=lc->rtp_conf.audio_rtp_port;
779 params->line=payload->line;
780 params->pt=payload->pt; /* remember the first payload accepted */
781 if (payload->relay_host!=NULL){
782 strncpy(params->remoteaddr,payload->relay_host,sizeof(params->remoteaddr)-1);
783 params->remoteport=payload->relay_port;
784 params->remotertcpport=payload->relay_port;
785 params->relay_session_id=payload->relay_session_id;
787 strncpy(params->remoteaddr,payload->c_addr,sizeof(params->remoteaddr)-1);
788 params->remoteport=payload->remoteport;
789 params->remotertcpport=payload->remoteport+1;
791 params->initialized=1;
792 /* we can now update the allocated bandwidth for audio, and then video*/
793 linphone_core_update_allocated_audio_bandwidth_in_call(lc,lpt);
799 int linphone_read_video_answer(sdp_context_t *ctx,sdp_payload_t *payload)
801 LinphoneCall *call=(LinphoneCall*)sdp_context_get_user_pointer(ctx);
802 LinphoneCore *lc=call->core;
803 StreamParams *params;
804 SupportLevel supported;
805 PayloadType *lpt=NULL;
807 /* paranoid check: see if this codec is supported in our local rtp profile*/
808 supported=linphone_payload_is_supported(lc, payload,lc->local_profile,call->profile,FALSE,&lpt);
809 if (supported==Unsupported) {
810 ms_warning("This remote sip phone did not answer properly to my sdp offer: rtpmap=%s",payload->a_rtpmap);
813 if (supported==SupportedAndValid){
814 params=&call->video_params;
815 if (params->initialized==0){
816 /* this is the first codec we may accept*/
817 params->localport=lc->rtp_conf.video_rtp_port;
818 params->line=payload->line;
819 params->pt=payload->pt; /* remember the first payload accepted */
820 if (payload->relay_host!=NULL){
821 strncpy(params->remoteaddr,payload->relay_host,sizeof(params->remoteaddr)-1);
822 params->remoteport=payload->relay_port;
823 params->remotertcpport=payload->relay_port;
824 params->relay_session_id=payload->relay_session_id;
826 strncpy(params->remoteaddr,payload->c_addr,sizeof(params->remoteaddr)-1);
827 params->remoteport=payload->remoteport;
828 params->remotertcpport=payload->remoteport+1;
830 params->initialized=1;
836 void linphone_call_ringing(LinphoneCore *lc, eXosip_event_t *ev){
837 sdp_message_t *sdp=eXosip_get_sdp_info(ev->response);
838 LinphoneCall *call=lc->call;
840 lc->vtable.display_status(lc,_("Remote ringing."));
841 linphone_call_proceeding(lc,ev);
842 if (call==NULL) return;
844 if (lc->ringstream!=NULL) return; /*already ringing !*/
845 if (lc->sound_conf.play_sndcard!=NULL){
846 ms_message("Remote ringing...");
847 lc->ringstream=ring_start(lc->sound_conf.remote_ring,2000,lc->sound_conf.play_sndcard);
850 /*accept early media */
851 StreamParams *audio_params;
853 ms_error("No call ?");
856 if (lc->audiostream->ticker!=NULL){
857 /*streams already started */
858 ms_message("Early media already started.");
861 audio_params=&call->audio_params;
862 sdp_context_read_answer(lc->call->sdpctx,sdp);
864 lc->vtable.display_status(lc,_("Early media."));
865 gstate_new_state(lc, GSTATE_CALL_OUT_CONNECTED, NULL);
866 if (lc->ringstream!=NULL){
867 ring_stop(lc->ringstream);
870 ms_message("Doing early media...");
871 linphone_core_start_media_streams(lc,call);
873 call->state=LCStateRinging;
876 sdp_message_free(sdp);
880 static void linphone_process_media_control_xml(LinphoneCore *lc, eXosip_event_t *ev){
881 osip_body_t *body=NULL;
882 osip_message_get_body(ev->request,0,&body);
883 if (body && body->body!=NULL &&
884 strstr(body->body,"picture_fast_update")){
885 osip_message_t *ans=NULL;
886 ms_message("Receiving VFU request !");
889 video_stream_send_vfu(lc->videostream);
891 eXosip_call_build_answer(ev->tid,200,&ans);
893 eXosip_call_send_answer(ev->tid,200,ans);
897 static void linphone_process_dtmf_relay(LinphoneCore *lc, eXosip_event_t *ev){
898 osip_body_t *body=NULL;
899 osip_message_get_body(ev->request,0,&body);
900 if (body && body->body!=NULL){
901 osip_message_t *ans=NULL;
902 const char *name=strstr(body->body,"Signal");
903 if (name==NULL) name=strstr(body->body,"signal");
905 ms_warning("Could not extract the dtmf name from the SIP INFO.");
908 name+=strlen("signal");
909 if (sscanf(name," = %1s",tmp)==1){
910 ms_message("Receiving dtmf %s via SIP INFO.",tmp);
911 if (lc->vtable.dtmf_received != NULL)
912 lc->vtable.dtmf_received(lc, tmp[0]);
916 eXosip_call_build_answer(ev->tid,200,&ans);
918 eXosip_call_send_answer(ev->tid,200,ans);
922 void linphone_call_message_new(LinphoneCore *lc, eXosip_event_t *ev){
923 osip_message_t *ans=NULL;
925 if (MSG_IS_INFO(ev->request)){
926 osip_content_type_t *ct;
927 ct=osip_message_get_content_type(ev->request);
928 if (ct && ct->subtype){
929 if (strcmp(ct->subtype,"media_control+xml")==0)
930 linphone_process_media_control_xml(lc,ev);
931 else if (strcmp(ct->subtype,"dtmf-relay")==0)
932 linphone_process_dtmf_relay(lc,ev);
934 ms_message("Unhandled SIP INFO.");
935 /*send an "Not implemented" answer*/
936 eXosip_call_build_answer(ev->tid,501,&ans);
938 eXosip_call_send_answer(ev->tid,501,ans);
941 /*empty SIP INFO, probably to test we are alive. Send an empty answer*/
942 eXosip_call_build_answer(ev->tid,200,&ans);
944 eXosip_call_send_answer(ev->tid,200,ans);
947 }else ms_warning("linphone_call_message_new: No request ?");
950 void linphone_registration_faillure(LinphoneCore *lc, eXosip_event_t *ev){
953 const char *reason=NULL;
954 osip_uri_t *requri=osip_message_get_uri(ev->request);
956 LinphoneProxyConfig *cfg;
959 status_code=osip_message_get_status_code(ev->response);
960 reason=osip_message_get_reason_phrase(ev->response);
965 linphone_process_authentication(lc,ev);
968 cfg=linphone_core_get_proxy_config_from_rid(lc,ev->rid);
969 /* if contact is up to date, process the failure, otherwise resend a new register with
970 updated contact first, just in case the faillure is due to incorrect contact */
971 if (linphone_proxy_config_register_again_with_updated_contact(cfg,ev->request,ev->response))
972 return; /*we are retrying with an updated contact*/
973 if (status_code==403) linphone_proxy_config_process_authentication_failure(lc,ev);
974 osip_uri_to_str(requri,&ru);
975 msg=ortp_strdup_printf(_("Registration on %s failed: %s"),ru,(reason!=NULL) ? reason : _("no response timeout"));
976 lc->vtable.display_status(lc,msg);
977 gstate_new_state(lc, GSTATE_REG_FAILED, msg);
983 void linphone_registration_success(LinphoneCore *lc,eXosip_event_t *ev){
984 LinphoneProxyConfig *cfg;
985 osip_uri_t *requri=osip_message_get_uri(ev->request);
988 osip_header_t *h=NULL;
990 cfg=linphone_core_get_proxy_config_from_rid(lc,ev->rid);
991 ms_return_if_fail(cfg!=NULL);
993 gstate_new_state(lc, GSTATE_REG_OK, NULL);
994 osip_message_get_expires(ev->request,0,&h);
995 if (h!=NULL && atoi(h->hvalue)!=0){
996 cfg->registered=TRUE;
997 linphone_proxy_config_register_again_with_updated_contact(cfg,ev->request,ev->response);
998 }else cfg->registered=FALSE;
1000 osip_uri_to_str(requri,&ru);
1001 if (cfg->registered) msg=ms_strdup_printf(_("Registration on %s successful."),ru);
1002 else msg=ms_strdup_printf(_("Unregistration on %s done."),ru);
1003 lc->vtable.display_status(lc,msg);
1008 static bool_t comes_from_local_if(osip_message_t *msg){
1009 osip_via_t *via=NULL;
1010 osip_message_get_via(msg,0,&via);
1013 host=osip_via_get_host(via);
1014 if (strcmp(host,"127.0.0.1")==0 || strcmp(host,"::1")==0){
1015 osip_generic_param_t *param=NULL;
1016 osip_via_param_get_byname(via,"received",¶m);
1017 if (param==NULL) return TRUE;
1018 if (param->gvalue &&
1019 (strcmp(param->gvalue,"127.0.0.1")==0 || strcmp(param->gvalue,"::1")==0)){
1027 static void linphone_inc_update(LinphoneCore *lc, eXosip_event_t *ev){
1028 osip_message_t *msg=NULL;
1029 ms_message("Processing incoming UPDATE");
1031 eXosip_message_build_answer(ev->tid,200,&msg);
1033 eXosip_message_send_answer(ev->tid,200,msg);
1037 static void linphone_other_request(LinphoneCore *lc, eXosip_event_t *ev){
1038 ms_message("in linphone_other_request");
1039 if (ev->request==NULL) return;
1040 if (strcmp(ev->request->sip_method,"MESSAGE")==0){
1041 linphone_core_text_received(lc,ev);
1042 eXosip_message_send_answer(ev->tid,200,NULL);
1043 }else if (strcmp(ev->request->sip_method,"OPTIONS")==0){
1044 osip_message_t *options=NULL;
1045 eXosip_options_build_answer(ev->tid,200,&options);
1046 osip_message_set_allow(options,"INVITE, ACK, BYE, CANCEL, OPTIONS, MESSAGE, SUBSCRIBE, NOTIFY, INFO");
1047 osip_message_set_accept(options,"application/sdp");
1048 eXosip_options_send_answer(ev->tid,200,options);
1049 }else if (strcmp(ev->request->sip_method,"WAKEUP")==0
1050 && comes_from_local_if(ev->request)) {
1051 eXosip_message_send_answer(ev->tid,200,NULL);
1052 ms_message("Receiving WAKEUP request !");
1053 if (lc->vtable.show)
1054 lc->vtable.show(lc);
1055 }else if (strncmp(ev->request->sip_method, "REFER", 5) == 0){
1056 ms_message("Receiving REFER request !");
1057 if (comes_from_local_if(ev->request)) {
1058 osip_header_t *h=NULL;
1059 osip_message_header_get_byname(ev->request,"Refer-To",0,&h);
1060 eXosip_message_send_answer(ev->tid,200,NULL);
1062 if (lc->vtable.refer_received)
1063 lc->vtable.refer_received(lc,h->hvalue);
1066 }else ms_warning("Ignored REFER not coming from this local loopback interface.");
1067 }else if (strncmp(ev->request->sip_method, "UPDATE", 6) == 0){
1068 linphone_inc_update(lc,ev);
1072 osip_message_to_str(ev->request,&tmp,&msglen);
1074 ms_message("Unsupported request received:\n%s",tmp);
1077 /*answer with a 501 Not implemented*/
1078 eXosip_message_send_answer(ev->tid,501,NULL);
1082 void linphone_core_process_event(LinphoneCore *lc,eXosip_event_t *ev)
1085 case EXOSIP_CALL_ANSWERED:
1086 ms_message("CALL_ANSWERED\n");
1087 linphone_call_accepted(lc,ev);
1088 linphone_authentication_ok(lc,ev);
1090 case EXOSIP_CALL_CLOSED:
1091 case EXOSIP_CALL_CANCELLED:
1092 ms_message("CALL_CLOSED or CANCELLED\n");
1093 linphone_call_terminated(lc,ev);
1095 case EXOSIP_CALL_TIMEOUT:
1096 case EXOSIP_CALL_NOANSWER:
1097 ms_message("CALL_TIMEOUT or NOANSWER\n");
1098 linphone_call_failure(lc,ev);
1100 case EXOSIP_CALL_REQUESTFAILURE:
1101 case EXOSIP_CALL_GLOBALFAILURE:
1102 case EXOSIP_CALL_SERVERFAILURE:
1103 ms_message("CALL_REQUESTFAILURE or GLOBALFAILURE or SERVERFAILURE\n");
1104 linphone_call_failure(lc,ev);
1106 case EXOSIP_CALL_INVITE:
1107 ms_message("CALL_NEW\n");
1108 /* CALL_NEW is used twice in qos mode :
1109 * when you receive invite (textinfo = "With QoS" or "Without QoS")
1110 * and when you receive update (textinfo = "New Call") */
1111 linphone_inc_new_call(lc,ev);
1113 case EXOSIP_CALL_REINVITE:
1114 linphone_handle_reinvite(lc,ev);
1116 case EXOSIP_CALL_ACK:
1117 ms_message("CALL_ACK");
1118 linphone_handle_ack(lc,ev);
1120 case EXOSIP_CALL_REDIRECTED:
1121 ms_message("CALL_REDIRECTED");
1122 linphone_call_redirected(lc,ev);
1124 case EXOSIP_CALL_PROCEEDING:
1125 ms_message("CALL_PROCEEDING");
1126 linphone_call_proceeding(lc,ev);
1128 case EXOSIP_CALL_RINGING:
1129 ms_message("CALL_RINGING");
1130 linphone_call_ringing(lc,ev);
1132 case EXOSIP_CALL_MESSAGE_NEW:
1133 ms_message("EXOSIP_CALL_MESSAGE_NEW");
1134 linphone_call_message_new(lc,ev);
1136 case EXOSIP_CALL_MESSAGE_REQUESTFAILURE:
1137 if (ev->did<0 && ev->response &&
1138 (ev->response->status_code==407 || ev->response->status_code==401)){
1139 eXosip_default_action(ev);
1142 case EXOSIP_IN_SUBSCRIPTION_NEW:
1143 ms_message("CALL_SUBSCRIPTION_NEW or UPDATE");
1144 linphone_subscription_new(lc,ev);
1146 case EXOSIP_SUBSCRIPTION_UPDATE:
1148 case EXOSIP_SUBSCRIPTION_NOTIFY:
1149 ms_message("CALL_SUBSCRIPTION_NOTIFY");
1150 linphone_notify_recv(lc,ev);
1152 case EXOSIP_SUBSCRIPTION_ANSWERED:
1153 ms_message("EXOSIP_SUBSCRIPTION_ANSWERED, ev->sid=%i\n",ev->sid);
1154 linphone_subscription_answered(lc,ev);
1156 case EXOSIP_SUBSCRIPTION_CLOSED:
1157 ms_message("EXOSIP_SUBSCRIPTION_CLOSED\n");
1158 linphone_subscription_closed(lc,ev);
1160 case EXOSIP_CALL_RELEASED:
1161 ms_message("CALL_RELEASED\n");
1162 linphone_call_released(lc, ev->cid);
1164 case EXOSIP_REGISTRATION_FAILURE:
1165 ms_message("REGISTRATION_FAILURE\n");
1166 linphone_registration_faillure(lc,ev);
1168 case EXOSIP_REGISTRATION_SUCCESS:
1169 linphone_authentication_ok(lc,ev);
1170 linphone_registration_success(lc,ev);
1172 case EXOSIP_MESSAGE_NEW:
1173 linphone_other_request(lc,ev);
1175 case EXOSIP_MESSAGE_REQUESTFAILURE:
1176 if (ev->response && (ev->response->status_code == 407 || ev->response->status_code == 401)){
1177 /*the user is expected to have registered to the proxy, thus password is known*/
1178 eXosip_default_action(ev);
1182 ms_message("Unhandled exosip event !");
1185 eXosip_event_free(ev);