1 /*
2 linphone
3 Copyright (C) 2012 Belledonne Communications, Grenoble, France
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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
18 */
19 #include "sal_impl.h"
20 #include "offeranswer.h"
21
22 #include <bctoolbox/defs.h>
23
24 static int extract_sdp(SalOp* op,belle_sip_message_t* message,belle_sdp_session_description_t** session_desc, SalReason *error);
25
26 /*used for calls terminated before creation of a dialog*/
call_set_released(SalOp * op)27 static void call_set_released(SalOp* op){
28 if (!op->call_released){
29 op->state=SalOpStateTerminated;
30 op->base.root->callbacks.call_released(op);
31 op->call_released=TRUE;
32 /*be aware that the following line may destroy the op*/
33 set_or_update_dialog(op,NULL);
34 }
35 }
36
call_set_error(SalOp * op,belle_sip_response_t * response,bool_t fatal)37 static void call_set_error(SalOp* op,belle_sip_response_t* response, bool_t fatal){
38 sal_op_set_error_info_from_response(op,response);
39 if (fatal) op->state = SalOpStateTerminating;
40 op->base.root->callbacks.call_failure(op);
41 }
set_addr_to_0000(char value[],size_t sz)42 static void set_addr_to_0000(char value[], size_t sz) {
43 if (ms_is_ipv6(value)) {
44 strncpy(value,"::0", sz);
45 } else {
46 strncpy(value,"0.0.0.0", sz);
47 }
48 return;
49 }
sdp_process(SalOp * h)50 static void sdp_process(SalOp *h){
51 ms_message("Doing SDP offer/answer process of type %s",h->sdp_offering ? "outgoing" : "incoming");
52 if (h->result){
53 sal_media_description_unref(h->result);
54 h->result = NULL;
55 }
56
57 /* if SDP was invalid */
58 if (h->base.remote_media == NULL) return;
59
60 h->result=sal_media_description_new();
61 if (h->sdp_offering){
62 offer_answer_initiate_outgoing(h->base.root->factory, h->base.local_media,h->base.remote_media,h->result);
63 }else{
64 int i;
65 if (h->sdp_answer){
66 belle_sip_object_unref(h->sdp_answer);
67 }
68 offer_answer_initiate_incoming(h->base.root->factory, h->base.local_media,h->base.remote_media,h->result,h->base.root->one_matching_codec);
69 /*for backward compatibility purpose*/
70 if(h->cnx_ip_to_0000_if_sendonly_enabled && sal_media_description_has_dir(h->result,SalStreamSendOnly)) {
71 set_addr_to_0000(h->result->addr, sizeof(h->result->addr));
72 for(i=0;i<SAL_MEDIA_DESCRIPTION_MAX_STREAMS;++i){
73 if (h->result->streams[i].dir == SalStreamSendOnly) {
74 set_addr_to_0000(h->result->streams[i].rtp_addr, sizeof(h->result->streams[i].rtp_addr));
75 set_addr_to_0000(h->result->streams[i].rtcp_addr, sizeof(h->result->streams[i].rtcp_addr));
76 }
77 }
78 }
79 h->sdp_answer=(belle_sdp_session_description_t *)belle_sip_object_ref(media_description_to_sdp(h->result));
80 /*once we have generated the SDP answer, we modify the result description for processing by the upper layer.
81 It should contains media parameters constraint from the remote offer, not our response*/
82 strcpy(h->result->addr,h->base.remote_media->addr);
83 h->result->bandwidth=h->base.remote_media->bandwidth;
84
85 for(i=0;i<SAL_MEDIA_DESCRIPTION_MAX_STREAMS;++i){
86 /*copy back parameters from remote description that we need in our result description*/
87 if (h->result->streams[i].rtp_port!=0){ /*if stream was accepted*/
88 strcpy(h->result->streams[i].rtp_addr,h->base.remote_media->streams[i].rtp_addr);
89 h->result->streams[i].ptime=h->base.remote_media->streams[i].ptime;
90 h->result->streams[i].bandwidth=h->base.remote_media->streams[i].bandwidth;
91 h->result->streams[i].rtp_port=h->base.remote_media->streams[i].rtp_port;
92 strcpy(h->result->streams[i].rtcp_addr,h->base.remote_media->streams[i].rtcp_addr);
93 h->result->streams[i].rtcp_port=h->base.remote_media->streams[i].rtcp_port;
94
95 if (sal_stream_description_has_srtp(&h->result->streams[i])) {
96 h->result->streams[i].crypto[0] = h->base.remote_media->streams[i].crypto[0];
97 }
98 }
99 }
100 }
101 }
102
set_sdp(belle_sip_message_t * msg,belle_sdp_session_description_t * session_desc)103 static int set_sdp(belle_sip_message_t *msg,belle_sdp_session_description_t* session_desc) {
104 belle_sip_header_content_type_t* content_type ;
105 belle_sip_header_content_length_t* content_length;
106 belle_sip_error_code error = BELLE_SIP_BUFFER_OVERFLOW;
107 size_t length = 0;
108
109 if (session_desc) {
110 size_t bufLen = 2048;
111 size_t hardlimit = 16*1024; /* 16k SDP limit seems reasonable */
112 char* buff = belle_sip_malloc(bufLen);
113 content_type = belle_sip_header_content_type_create("application","sdp");
114
115 /* try to marshal the description. This could go higher than 2k so we iterate */
116 while( error != BELLE_SIP_OK && bufLen <= hardlimit && buff != NULL){
117 error = belle_sip_object_marshal(BELLE_SIP_OBJECT(session_desc),buff,bufLen,&length);
118 if( error != BELLE_SIP_OK ){
119 bufLen *= 2;
120 length = 0;
121 buff = belle_sip_realloc(buff,bufLen);
122 }
123 }
124 /* give up if hard limit reached */
125 if (error != BELLE_SIP_OK || buff == NULL) {
126 ms_error("Buffer too small (%d) or not enough memory, giving up SDP", (int)bufLen);
127 return -1;
128 }
129
130 content_length = belle_sip_header_content_length_create(length);
131 belle_sip_message_add_header(msg,BELLE_SIP_HEADER(content_type));
132 belle_sip_message_add_header(msg,BELLE_SIP_HEADER(content_length));
133 belle_sip_message_assign_body(msg,buff,length);
134 return 0;
135 } else {
136 return -1;
137 }
138 }
set_sdp_from_desc(belle_sip_message_t * msg,const SalMediaDescription * desc)139 static int set_sdp_from_desc(belle_sip_message_t *msg, const SalMediaDescription *desc){
140 int err;
141 belle_sdp_session_description_t *sdp=media_description_to_sdp(desc);
142 err=set_sdp(msg,sdp);
143 belle_sip_object_unref(sdp);
144 return err;
145
146 }
147
call_process_io_error(void * user_ctx,const belle_sip_io_error_event_t * event)148 static void call_process_io_error(void *user_ctx, const belle_sip_io_error_event_t *event) {
149 SalOp *op = (SalOp *)user_ctx;
150
151 if (op->state == SalOpStateTerminated) return;
152
153 if (op->pending_client_trans && (belle_sip_transaction_get_state(BELLE_SIP_TRANSACTION(op->pending_client_trans)) == BELLE_SIP_TRANSACTION_INIT)) {
154
155 sal_error_info_set(&op->error_info, SalReasonIOError, "SIP", 503, "IO error", NULL);
156 op->base.root->callbacks.call_failure(op);
157
158 if (!op->dialog || belle_sip_dialog_get_state(op->dialog) != BELLE_SIP_DIALOG_CONFIRMED){
159 /* Call terminated very very early, before INVITE is even sent, probably DNS resolution timeout. */
160 op->state = SalOpStateTerminating;
161 call_set_released(op);
162 }
163 } else {
164 /* Nothing to be done. If the error comes from a connectivity loss,
165 * the call will be marked as broken, and an attempt to repair it will be done. */
166 }
167 }
168
process_dialog_terminated(void * ctx,const belle_sip_dialog_terminated_event_t * event)169 static void process_dialog_terminated(void *ctx, const belle_sip_dialog_terminated_event_t *event) {
170 SalOp* op=(SalOp*)ctx;
171
172 if (op->dialog && op->dialog==belle_sip_dialog_terminated_event_get_dialog(event)) {
173 /*belle_sip_transaction_t* trans=belle_sip_dialog_get_last_transaction(op->dialog);*/
174 ms_message("Dialog [%p] terminated for op [%p]",belle_sip_dialog_terminated_event_get_dialog(event),op);
175
176 switch(belle_sip_dialog_get_previous_state(op->dialog)) {
177 case BELLE_SIP_DIALOG_EARLY:
178 case BELLE_SIP_DIALOG_NULL:
179 if (op->state!=SalOpStateTerminated && op->state!=SalOpStateTerminating) {
180 /*this is an early termination due to incorrect response received*/
181 op->base.root->callbacks.call_failure(op);
182 op->state=SalOpStateTerminating;
183 }
184 break;
185 case BELLE_SIP_DIALOG_CONFIRMED:
186 if (op->state!=SalOpStateTerminated && op->state!=SalOpStateTerminating) {
187 /*this is probably a normal termination from a BYE*/
188 op->base.root->callbacks.call_terminated(op,op->dir==SalOpDirIncoming?sal_op_get_from(op):sal_op_get_to(op));
189 op->state=SalOpStateTerminating;
190 }
191 break;
192 default:
193 break;
194 }
195 belle_sip_main_loop_do_later(belle_sip_stack_get_main_loop(op->base.root->stack)
196 ,(belle_sip_callback_t) call_set_released
197 , op);
198 } else {
199 ms_error("dialog unknown for op ");
200 }
201 }
202
handle_sdp_from_response(SalOp * op,belle_sip_response_t * response)203 static void handle_sdp_from_response(SalOp* op,belle_sip_response_t* response) {
204 belle_sdp_session_description_t* sdp;
205 SalReason reason;
206 if (op->base.remote_media){
207 sal_media_description_unref(op->base.remote_media);
208 op->base.remote_media=NULL;
209 }
210 if (extract_sdp(op,BELLE_SIP_MESSAGE(response),&sdp,&reason)==0) {
211 if (sdp){
212 op->base.remote_media=sal_media_description_new();
213 sdp_to_media_description(sdp,op->base.remote_media);
214 }/*if no sdp in response, what can we do ?*/
215 }
216 /* process sdp in any case to reset result media description*/
217 if (op->base.local_media) sdp_process(op);
218 }
219
sal_call_cancel_invite(SalOp * op)220 void sal_call_cancel_invite(SalOp *op) {
221 sal_call_cancel_invite_with_info(op,NULL);
222 }
223
cancelling_invite(SalOp * op,const SalErrorInfo * info)224 static void cancelling_invite(SalOp *op, const SalErrorInfo *info) {
225 sal_call_cancel_invite_with_info(op, info);
226 op->state=SalOpStateTerminating;
227 }
228
vfu_retry(void * user_data,unsigned int events)229 static int vfu_retry (void *user_data, unsigned int events) {
230 SalOp *op=(SalOp *)user_data;
231 sal_call_send_vfu_request(op);
232 sal_op_unref(op);
233 return BELLE_SIP_STOP;
234 }
235
call_process_response(void * op_base,const belle_sip_response_event_t * event)236 static void call_process_response(void *op_base, const belle_sip_response_event_t *event){
237 SalOp* op = (SalOp*)op_base;
238 belle_sip_request_t* ack;
239 belle_sip_dialog_state_t dialog_state;
240 belle_sip_client_transaction_t* client_transaction = belle_sip_response_event_get_client_transaction(event);
241 belle_sip_request_t* req;
242 belle_sip_response_t* response=belle_sip_response_event_get_response(event);
243 int code = belle_sip_response_get_status_code(response);
244 belle_sip_header_content_type_t *header_content_type=NULL;
245 belle_sip_dialog_t *dialog=belle_sip_response_event_get_dialog(event);
246 const char *method;
247
248 if (!client_transaction) {
249 ms_warning("Discarding stateless response [%i] on op [%p]",code,op);
250 return;
251 }
252 req=belle_sip_transaction_get_request(BELLE_SIP_TRANSACTION(client_transaction));
253 set_or_update_dialog(op,dialog);
254 dialog_state=dialog ? belle_sip_dialog_get_state(dialog) : BELLE_SIP_DIALOG_NULL;
255 method=belle_sip_request_get_method(req);
256 ms_message("Op [%p] receiving call response [%i], dialog is [%p] in state [%s]",op,code,dialog,belle_sip_dialog_state_to_string(dialog_state));
257 /*to make sure no cb will destroy op*/
258 sal_op_ref(op);
259 switch(dialog_state) {
260 case BELLE_SIP_DIALOG_NULL:
261 case BELLE_SIP_DIALOG_EARLY: {
262 if (strcmp("INVITE",method)==0 ) {
263 if (op->state == SalOpStateTerminating) {
264 /*check if CANCEL was sent before*/
265 if (strcmp("CANCEL",belle_sip_request_get_method(belle_sip_transaction_get_request(BELLE_SIP_TRANSACTION(op->pending_client_trans))))!=0) {
266 /*it wasn't sent */
267 if (code<200) {
268 cancelling_invite(op, NULL);
269 }else{
270 /* no need to send the INVITE because the UAS rejected the INVITE*/
271 if (op->dialog==NULL) call_set_released(op);
272 }
273 } else {
274 /*it was sent already, so just expect the 487 or any error response to send the call_released() notification*/
275 if (code>=300){
276 if (op->dialog==NULL) call_set_released(op);
277 }
278 }
279 } else if (code >= 180 && code<200) {
280 belle_sip_response_t *prev_response=belle_sip_object_data_get(BELLE_SIP_OBJECT(dialog),"early_response");
281 if (!prev_response || code>belle_sip_response_get_status_code(prev_response)){
282 handle_sdp_from_response(op,response);
283 op->base.root->callbacks.call_ringing(op);
284 }
285 belle_sip_object_data_set(BELLE_SIP_OBJECT(dialog),"early_response",belle_sip_object_ref(response),belle_sip_object_unref);
286 } else if (code>=300){
287 call_set_error(op, response, TRUE);
288 if (op->dialog==NULL) call_set_released(op);
289 }
290 } else if (code >=200 && code<300) {
291 if (strcmp("UPDATE",method)==0) {
292 handle_sdp_from_response(op,response);
293 op->base.root->callbacks.call_accepted(op);
294 } else if (strcmp("CANCEL", method) == 0) {
295 op->base.root->callbacks.call_cancel_done(op);
296 }
297 }
298 }
299 break;
300 case BELLE_SIP_DIALOG_CONFIRMED: {
301 switch (op->state) {
302 case SalOpStateEarly:/*invite case*/
303 case SalOpStateActive: /*re-invite, INFO, UPDATE case*/
304 if (strcmp("INVITE",method)==0){
305 if (code >=200 && code<300) {
306 handle_sdp_from_response(op,response);
307 ack=belle_sip_dialog_create_ack(op->dialog,belle_sip_dialog_get_local_seq_number(op->dialog));
308 if (ack == NULL) {
309 ms_error("This call has been already terminated.");
310 return ;
311 }
312 if (op->sdp_answer){
313 set_sdp(BELLE_SIP_MESSAGE(ack),op->sdp_answer);
314 belle_sip_object_unref(op->sdp_answer);
315 op->sdp_answer=NULL;
316 }
317 belle_sip_message_add_header(BELLE_SIP_MESSAGE(ack),BELLE_SIP_HEADER(op->base.root->user_agent));
318 op->base.root->callbacks.call_accepted(op); /*INVITE*/
319 op->base.root->callbacks.call_ack_being_sent(op, (SalCustomHeader*)ack);
320 belle_sip_dialog_send_ack(op->dialog,ack);
321 op->state=SalOpStateActive;
322 }else if (code >= 300){
323 call_set_error(op,response, FALSE);
324 }
325 }else if (strcmp("INFO",method)==0){
326 if (code == 491
327 && (header_content_type = belle_sip_message_get_header_by_type(req,belle_sip_header_content_type_t))
328 && strcmp("application",belle_sip_header_content_type_get_type(header_content_type))==0
329 && strcmp("media_control+xml",belle_sip_header_content_type_get_subtype(header_content_type))==0) {
330 unsigned int retry_in = (unsigned int)(1000*((float)rand()/RAND_MAX));
331 belle_sip_source_t *s=sal_create_timer(op->base.root,vfu_retry,sal_op_ref(op), retry_in, "vfu request retry");
332 ms_message("Rejected vfu request on op [%p], just retry in [%ui] ms",op,retry_in);
333 belle_sip_object_unref(s);
334 }else {
335 /*ignoring*/
336 }
337 }else if (strcmp("UPDATE",method)==0){
338 op->base.root->callbacks.call_accepted(op); /*INVITE*/
339 }else if (strcmp("CANCEL",method)==0){
340 op->base.root->callbacks.call_cancel_done(op);
341 }
342 break;
343 case SalOpStateTerminating:
344 sal_op_send_request(op,belle_sip_dialog_create_request(op->dialog,"BYE"));
345 break;
346 case SalOpStateTerminated:
347 default:
348 ms_error("Call op [%p] receives unexpected answer [%i] while in state [%s].",op,code, sal_op_state_to_string(op->state));
349 }
350 }
351 break;
352 case BELLE_SIP_DIALOG_TERMINATED: {
353 if (strcmp("INVITE",method)==0 && code >= 300){
354 call_set_error(op,response, TRUE);
355 }
356 }
357 break;
358 default: {
359 ms_error("call op [%p] receive answer [%i] not implemented",op,code);
360 }
361 break;
362 }
363 sal_op_unref(op);
364 }
365
call_process_timeout(void * user_ctx,const belle_sip_timeout_event_t * event)366 static void call_process_timeout(void *user_ctx, const belle_sip_timeout_event_t *event) {
367 SalOp* op=(SalOp*)user_ctx;
368
369 if (op->state==SalOpStateTerminated) return;
370
371 if (!op->dialog) {
372 /*call terminated very early*/
373 sal_error_info_set(&op->error_info, SalReasonRequestTimeout, "SIP", 408, "Request timeout", NULL);
374 op->base.root->callbacks.call_failure(op);
375 op->state = SalOpStateTerminating;
376 call_set_released(op);
377 } else {
378 /*dialog will terminated shortly, nothing to do*/
379 }
380 }
381
call_process_transaction_terminated(void * user_ctx,const belle_sip_transaction_terminated_event_t * event)382 static void call_process_transaction_terminated(void *user_ctx, const belle_sip_transaction_terminated_event_t *event) {
383 SalOp* op = (SalOp*)user_ctx;
384 belle_sip_client_transaction_t *client_transaction=belle_sip_transaction_terminated_event_get_client_transaction(event);
385 belle_sip_server_transaction_t *server_transaction=belle_sip_transaction_terminated_event_get_server_transaction(event);
386 belle_sip_request_t* req;
387 belle_sip_response_t* resp;
388 int code = 0;
389 bool_t release_call=FALSE;
390
391 if (client_transaction) {
392 req=belle_sip_transaction_get_request(BELLE_SIP_TRANSACTION(client_transaction));
393 resp=belle_sip_transaction_get_response(BELLE_SIP_TRANSACTION(client_transaction));
394 } else {
395 req=belle_sip_transaction_get_request(BELLE_SIP_TRANSACTION(server_transaction));
396 resp=belle_sip_transaction_get_response(BELLE_SIP_TRANSACTION(server_transaction));
397 }
398 if (resp) code = belle_sip_response_get_status_code(resp);
399
400 if (op->state == SalOpStateTerminating
401 && strcmp("BYE",belle_sip_request_get_method(req))==0
402 && (!resp || (belle_sip_response_get_status_code(resp) != 401
403 && belle_sip_response_get_status_code(resp) != 407))
404 && op->dialog==NULL) {
405 release_call=TRUE;
406 }else if (op->state == SalOpStateEarly && code < 200){
407 /*call terminated early*/
408 sal_error_info_set(&op->error_info, SalReasonIOError, "SIP", 503, "I/O error", NULL);
409 op->state = SalOpStateTerminating;
410 op->base.root->callbacks.call_failure(op);
411 release_call=TRUE;
412 }
413 if (server_transaction){
414 if (op->pending_server_trans==server_transaction){
415 belle_sip_object_unref(op->pending_server_trans);
416 op->pending_server_trans=NULL;
417 }
418 if (op->pending_update_server_trans==server_transaction){
419 belle_sip_object_unref(op->pending_update_server_trans);
420 op->pending_update_server_trans=NULL;
421 }
422 }
423 if (release_call) call_set_released(op);
424 }
425
call_terminated(SalOp * op,belle_sip_server_transaction_t * server_transaction,int status_code,belle_sip_request_t * cancel_request)426 static void call_terminated(SalOp* op,belle_sip_server_transaction_t* server_transaction, int status_code, belle_sip_request_t* cancel_request) {
427 belle_sip_response_t* resp;
428 belle_sip_request_t* server_req = belle_sip_transaction_get_request(BELLE_SIP_TRANSACTION(server_transaction));
429 op->state = SalOpStateTerminating;
430 sal_op_set_reason_error_info(op, BELLE_SIP_MESSAGE(cancel_request ? cancel_request : server_req));
431 resp=sal_op_create_response_from_request(op,server_req,status_code);
432 belle_sip_server_transaction_send_response(server_transaction,resp);
433 op->base.root->callbacks.call_terminated(op,op->dir==SalOpDirIncoming?sal_op_get_from(op):sal_op_get_to(op));
434 }
435
unsupported_method(belle_sip_server_transaction_t * server_transaction,belle_sip_request_t * request)436 static void unsupported_method(belle_sip_server_transaction_t* server_transaction,belle_sip_request_t* request) {
437 belle_sip_response_t* resp;
438 resp=belle_sip_response_create_from_request(request,501);
439 belle_sip_server_transaction_send_response(server_transaction,resp);
440 return;
441 }
442
443 /*
444 * Extract the sdp from a sip message.
445 * If there is no body in the message, the session_desc is set to null, 0 is returned.
446 * If body was present is not a SDP or parsing of SDP failed, -1 is returned and SalReason is set appropriately.
447 *
448 **/
extract_sdp(SalOp * op,belle_sip_message_t * message,belle_sdp_session_description_t ** session_desc,SalReason * error)449 static int extract_sdp(SalOp *op, belle_sip_message_t* message,belle_sdp_session_description_t** session_desc, SalReason *error) {
450 const char *body;
451 belle_sip_header_content_type_t* content_type;
452
453 if (op&&op->sdp_handling == SalOpSDPSimulateError){
454 ms_error("Simulating SDP parsing error for op %p", op);
455 *session_desc=NULL;
456 *error=SalReasonNotAcceptable;
457 return -1;
458 } else if( op && op->sdp_handling == SalOpSDPSimulateRemove){
459 ms_error("Simulating no SDP for op %p", op);
460 *session_desc = NULL;
461 return 0;
462 }
463
464 body = belle_sip_message_get_body(message);
465 if(body == NULL) {
466 *session_desc = NULL;
467 return 0;
468 }
469
470 content_type = belle_sip_message_get_header_by_type(message,belle_sip_header_content_type_t);
471 if (content_type){
472 if (strcmp("application",belle_sip_header_content_type_get_type(content_type))==0
473 && strcmp("sdp",belle_sip_header_content_type_get_subtype(content_type))==0) {
474 *session_desc=belle_sdp_session_description_parse(body);
475 if (*session_desc==NULL) {
476 ms_error("Failed to parse SDP message.");
477 *error=SalReasonNotAcceptable;
478 return -1;
479 }
480 }else{
481 *error=SalReasonUnsupportedContent;
482 return -1;
483 }
484 }else *session_desc=NULL;
485 return 0;
486 }
487
is_media_description_acceptable(SalMediaDescription * md)488 static int is_media_description_acceptable(SalMediaDescription *md){
489 if (md->nb_streams==0){
490 ms_warning("Media description does not define any stream.");
491 return FALSE;
492 }
493 return TRUE;
494 }
495
process_sdp_for_invite(SalOp * op,belle_sip_request_t * invite)496 static SalReason process_sdp_for_invite(SalOp* op,belle_sip_request_t* invite) {
497 belle_sdp_session_description_t* sdp;
498 SalReason reason = SalReasonNone;
499 SalErrorInfo sei = {0};
500
501 if (extract_sdp(op,BELLE_SIP_MESSAGE(invite),&sdp,&reason)==0) {
502 if (sdp){
503 op->sdp_offering=FALSE;
504 op->base.remote_media=sal_media_description_new();
505 sdp_to_media_description(sdp,op->base.remote_media);
506 /*make some sanity check about the SDP received*/
507 if (!is_media_description_acceptable(op->base.remote_media)){
508 reason=SalReasonNotAcceptable;
509 }
510 belle_sip_object_unref(sdp);
511 }else op->sdp_offering=TRUE; /*INVITE without SDP*/
512 }
513
514 if (reason != SalReasonNone){
515 sal_error_info_set(&sei, reason,"SIP", 0, NULL, NULL);
516 sal_call_decline_with_error_info(op, &sei,NULL);
517 sal_error_info_reset(&sei);
518 }
519 return reason;
520 }
521
sal_op_reset_descriptions(SalOp * op)522 static void sal_op_reset_descriptions(SalOp *op) {
523 if (op->base.remote_media){
524 sal_media_description_unref(op->base.remote_media);
525 op->base.remote_media=NULL;
526 }
527 if (op->result){
528 sal_media_description_unref(op->result);
529 op->result=NULL;
530 }
531 }
532
is_a_pending_invite_incoming_transaction(belle_sip_transaction_t * tr)533 static bool_t is_a_pending_invite_incoming_transaction(belle_sip_transaction_t *tr){
534 return BELLE_SIP_OBJECT_IS_INSTANCE_OF(tr, belle_sip_ist_t) && belle_sip_transaction_state_is_transient(
535 belle_sip_transaction_get_state(tr));
536 }
537
process_request_event(void * op_base,const belle_sip_request_event_t * event)538 static void process_request_event(void *op_base, const belle_sip_request_event_t *event) {
539 SalOp* op = (SalOp*)op_base;
540 SalReason reason;
541 belle_sip_server_transaction_t* server_transaction=NULL;
542 belle_sdp_session_description_t* sdp;
543 belle_sip_request_t* req = belle_sip_request_event_get_request(event);
544 belle_sip_dialog_state_t dialog_state;
545 belle_sip_response_t* resp;
546 belle_sip_header_t* call_info;
547 const char *method=belle_sip_request_get_method(req);
548 bool_t is_update=FALSE;
549 bool_t drop_op = FALSE;
550
551 if (strcmp("ACK",method)!=0){ /*ACK doesn't create a server transaction*/
552 server_transaction = belle_sip_provider_create_server_transaction(op->base.root->prov,belle_sip_request_event_get_request(event));
553 belle_sip_object_ref(server_transaction);
554 belle_sip_transaction_set_application_data(BELLE_SIP_TRANSACTION(server_transaction),sal_op_ref(op));
555 }
556
557 if (strcmp("INVITE",method)==0) {
558 if (op->pending_server_trans) belle_sip_object_unref(op->pending_server_trans);
559 /*updating pending invite transaction*/
560 op->pending_server_trans=server_transaction;
561 belle_sip_object_ref(op->pending_server_trans);
562 }
563
564 if (strcmp("UPDATE",method)==0) {
565 if (op->pending_update_server_trans) belle_sip_object_unref(op->pending_update_server_trans);
566 /*updating pending update transaction*/
567 op->pending_update_server_trans=server_transaction;
568 belle_sip_object_ref(op->pending_update_server_trans);
569 }
570
571 if (!op->dialog) {
572 set_or_update_dialog(op,belle_sip_provider_create_dialog(op->base.root->prov,BELLE_SIP_TRANSACTION(op->pending_server_trans)));
573 ms_message("new incoming call from [%s] to [%s]",sal_op_get_from(op),sal_op_get_to(op));
574 }
575 dialog_state=belle_sip_dialog_get_state(op->dialog);
576 switch(dialog_state) {
577 case BELLE_SIP_DIALOG_NULL: {
578 if (strcmp("INVITE",method)==0) {
579 if (!op->replaces && (op->replaces=belle_sip_message_get_header_by_type(BELLE_SIP_MESSAGE(req),belle_sip_header_replaces_t))) {
580 belle_sip_object_ref(op->replaces);
581 } else if(op->replaces) {
582 ms_warning("replace header already set");
583 }
584
585 if ( (reason = process_sdp_for_invite(op,req)) == SalReasonNone) {
586 if ((call_info=belle_sip_message_get_header(BELLE_SIP_MESSAGE(req),"Call-Info"))) {
587 if( strstr(belle_sip_header_get_unparsed_value(call_info),"answer-after=") != NULL) {
588 op->auto_answer_asked=TRUE;
589 ms_message("The caller asked to automatically answer the call(Emergency?)\n");
590 }
591 }
592 op->base.root->callbacks.call_received(op);
593 }else{
594 sal_error_info_set(&op->error_info, reason, "SIP", 0, NULL, NULL);
595 op->base.root->callbacks.call_rejected(op);
596 /*the INVITE was declined by process_sdp_for_invite(). As we are not inside an established dialog, we can drop the op immediately*/
597 drop_op = TRUE;
598 }
599 break;
600 }BCTBX_NO_BREAK; /* else same behavior as for EARLY state, thus NO BREAK*/
601 }
602 case BELLE_SIP_DIALOG_EARLY: {
603 if (strcmp("CANCEL",method)==0) {
604 if(belle_sip_request_event_get_server_transaction(event)) {
605 /*first answer 200 ok to cancel*/
606 belle_sip_server_transaction_send_response(server_transaction
607 ,sal_op_create_response_from_request(op,req,200));
608 /*terminate invite transaction*/
609 call_terminated(op,op->pending_server_trans,487,req);
610 } else {
611 /*call leg does not exist*/
612 belle_sip_server_transaction_send_response(server_transaction
613 ,sal_op_create_response_from_request(op,req,481));
614 }
615 } else if (strcmp("PRACK",method)==0) {
616 resp=sal_op_create_response_from_request(op,req,200);
617 belle_sip_server_transaction_send_response(server_transaction,resp);
618 } else if (strcmp("UPDATE",method)==0) {
619 sal_op_reset_descriptions(op);
620 if (process_sdp_for_invite(op,req)==SalReasonNone)
621 op->base.root->callbacks.call_updating(op,TRUE);
622 } else {
623 belle_sip_error("Unexpected method [%s] for dialog state BELLE_SIP_DIALOG_EARLY",belle_sip_request_get_method(req));
624 unsupported_method(server_transaction,req);
625 }
626 break;
627 }
628 case BELLE_SIP_DIALOG_CONFIRMED:
629 /*great ACK received*/
630 if (strcmp("ACK",method)==0) {
631 if (!op->pending_client_trans ||
632 !belle_sip_transaction_state_is_transient(belle_sip_transaction_get_state((belle_sip_transaction_t*)op->pending_client_trans))){
633 if (op->sdp_offering){
634 SalReason reason;
635 if (extract_sdp(op,BELLE_SIP_MESSAGE(req),&sdp,&reason)==0){
636 if (sdp){
637 if (op->base.remote_media)
638 sal_media_description_unref(op->base.remote_media);
639 op->base.remote_media=sal_media_description_new();
640 sdp_to_media_description(sdp,op->base.remote_media);
641 sdp_process(op);
642 belle_sip_object_unref(sdp);
643 }else{
644 ms_warning("SDP expected in ACK but not found.");
645 }
646 }
647 }
648 op->base.root->callbacks.call_ack_received(op, (SalCustomHeader*)req);
649 }else{
650 ms_message("Ignored received ack since a new client transaction has been started since.");
651 }
652 } else if(strcmp("BYE",method)==0) {
653 call_terminated(op,server_transaction,200,req);
654 /*call end not notified by dialog deletion because transaction can end before dialog*/
655 } else if(strcmp("INVITE",method)==0 || (is_update=(strcmp("UPDATE",method)==0)) ) {
656 if (is_update && !belle_sip_message_get_body(BELLE_SIP_MESSAGE(req))) {
657 /*session timer case*/
658 /*session expire should be handled. to be done when real session timer (rfc4028) will be implemented*/
659 resp=sal_op_create_response_from_request(op,req,200);
660 belle_sip_server_transaction_send_response(server_transaction,resp);
661 belle_sip_object_unref(op->pending_update_server_trans);
662 op->pending_update_server_trans=NULL;
663 } else {
664 /*re-invite*/
665 sal_op_reset_descriptions(op);
666 if (process_sdp_for_invite(op,req)==SalReasonNone)
667 op->base.root->callbacks.call_updating(op,is_update);
668 }
669 } else if (strcmp("INFO",method)==0){
670 if (belle_sip_message_get_body(BELLE_SIP_MESSAGE(req))
671 && strstr(belle_sip_message_get_body(BELLE_SIP_MESSAGE(req)),"picture_fast_update")) {
672 /*vfu request*/
673 ms_message("Receiving VFU request on op [%p]",op);
674 if (op->base.root->callbacks.vfu_request){
675 op->base.root->callbacks.vfu_request(op);
676
677 }
678 }else{
679 belle_sip_message_t *msg = BELLE_SIP_MESSAGE(req);
680 belle_sip_body_handler_t *body_handler = BELLE_SIP_BODY_HANDLER(sal_op_get_body_handler(op, msg));
681 if (body_handler) {
682 belle_sip_header_content_type_t *content_type = belle_sip_message_get_header_by_type(msg, belle_sip_header_content_type_t);
683 if (content_type
684 && (strcmp(belle_sip_header_content_type_get_type(content_type), "application") == 0)
685 && (strcmp(belle_sip_header_content_type_get_subtype(content_type), "dtmf-relay") == 0)) {
686 char tmp[10];
687 if (sal_lines_get_value(belle_sip_message_get_body(msg), "Signal",tmp, sizeof(tmp))){
688 op->base.root->callbacks.dtmf_received(op,tmp[0]);
689 }
690 }else
691 op->base.root->callbacks.info_received(op, (SalBodyHandler *)body_handler);
692 } else {
693 op->base.root->callbacks.info_received(op,NULL);
694 }
695 }
696 resp=sal_op_create_response_from_request(op,req,200);
697 belle_sip_server_transaction_send_response(server_transaction,resp);
698 }else if (strcmp("REFER",method)==0) {
699 sal_op_process_refer(op,event,server_transaction);
700 } else if (strcmp("NOTIFY",method)==0) {
701 sal_op_call_process_notify(op,event,server_transaction);
702 } else if (strcmp("OPTIONS",method)==0) {
703 resp=sal_op_create_response_from_request(op,req,200);
704 belle_sip_server_transaction_send_response(server_transaction,resp);
705 } else if (strcmp("CANCEL",method)==0) {
706 belle_sip_transaction_t *last_transaction = belle_sip_dialog_get_last_transaction(op->dialog);
707 if (last_transaction == NULL || !is_a_pending_invite_incoming_transaction(last_transaction) ) {
708 /*call leg does not exist because 200ok already sent*/
709 belle_sip_server_transaction_send_response(server_transaction,sal_op_create_response_from_request(op,req,481));
710 } else {
711 /* CANCEL on re-INVITE for which a 200ok has not been sent yet */
712 belle_sip_server_transaction_send_response(server_transaction, sal_op_create_response_from_request(op, req, 200));
713 belle_sip_server_transaction_send_response(BELLE_SIP_SERVER_TRANSACTION(last_transaction),
714 sal_op_create_response_from_request(op, belle_sip_transaction_get_request(BELLE_SIP_TRANSACTION(last_transaction)), 487));
715 }
716 } else if (strcmp("MESSAGE",method)==0){
717 sal_process_incoming_message(op,event);
718 }else{
719 ms_error("unexpected method [%s] for dialog [%p]",belle_sip_request_get_method(req),op->dialog);
720 unsupported_method(server_transaction,req);
721 }
722 break;
723 default:
724 ms_error("unexpected dialog state [%s]",belle_sip_dialog_state_to_string(dialog_state));
725 break;
726 }
727
728 if (server_transaction) belle_sip_object_unref(server_transaction);
729 if (drop_op) sal_op_release(op);
730 }
731
732
733 /*Call API*/
sal_call_set_local_media_description(SalOp * op,SalMediaDescription * desc)734 int sal_call_set_local_media_description(SalOp *op, SalMediaDescription *desc){
735 if (desc)
736 sal_media_description_ref(desc);
737 if (op->base.local_media)
738 sal_media_description_unref(op->base.local_media);
739 op->base.local_media=desc;
740
741 if (op->base.remote_media){
742 /*case of an incoming call where we modify the local capabilities between the time
743 * the call is ringing and it is accepted (for example if you want to accept without video*/
744 /*reset the sdp answer so that it is computed again*/
745 if (op->sdp_answer){
746 belle_sip_object_unref(op->sdp_answer);
747 op->sdp_answer=NULL;
748 }
749 }
750 return 0;
751 }
752
create_allow(bool_t enable_update)753 static belle_sip_header_allow_t *create_allow(bool_t enable_update){
754 belle_sip_header_allow_t* header_allow;
755 char allow [256];
756 snprintf(allow,sizeof(allow),"INVITE, ACK, CANCEL, OPTIONS, BYE, REFER, NOTIFY, MESSAGE, SUBSCRIBE, INFO%s",(enable_update?", UPDATE":""));
757 header_allow = belle_sip_header_allow_create(allow);
758 return header_allow;
759 }
760
sal_op_fill_invite(SalOp * op,belle_sip_request_t * invite)761 static void sal_op_fill_invite(SalOp *op, belle_sip_request_t* invite) {
762 belle_sip_message_add_header(BELLE_SIP_MESSAGE(invite),BELLE_SIP_HEADER(create_allow(op->base.root->enable_sip_update)));
763
764 if (op->base.root->session_expires!=0){
765 belle_sip_message_add_header(BELLE_SIP_MESSAGE(invite),belle_sip_header_create( "Session-expires", "600;refresher=uas"));
766 belle_sip_message_add_header(BELLE_SIP_MESSAGE(invite),belle_sip_header_create( "Supported", "timer"));
767 }
768 if (op->base.local_media){
769 op->sdp_offering=TRUE;
770 set_sdp_from_desc(BELLE_SIP_MESSAGE(invite),op->base.local_media);
771 }else op->sdp_offering=FALSE;
772 return;
773 }
774
sal_call(SalOp * op,const char * from,const char * to)775 int sal_call(SalOp *op, const char *from, const char *to){
776 belle_sip_request_t* invite;
777 op->dir=SalOpDirOutgoing;
778
779 sal_op_set_from(op,from);
780 sal_op_set_to(op,to);
781
782 ms_message("[%s] calling [%s] on op [%p]", from, to, op);
783 invite=sal_op_build_request(op,"INVITE");
784
785 if( invite == NULL ){
786 /* can happen if the op has an invalid address */
787 return -1;
788 }
789
790 sal_op_fill_invite(op,invite);
791
792 sal_op_call_fill_cbs(op);
793 if (op->replaces){
794 belle_sip_message_add_header(BELLE_SIP_MESSAGE(invite),BELLE_SIP_HEADER(op->replaces));
795 }
796 if (op->referred_by)
797 belle_sip_message_add_header(BELLE_SIP_MESSAGE(invite),BELLE_SIP_HEADER(op->referred_by));
798
799 return sal_op_send_request(op,invite);
800 }
801
802 static belle_sip_listener_callbacks_t call_op_callbacks={0};
803
sal_op_call_fill_cbs(SalOp * op)804 void sal_op_call_fill_cbs(SalOp*op) {
805 if (call_op_callbacks.process_response_event==NULL){
806 call_op_callbacks.process_io_error=call_process_io_error;
807 call_op_callbacks.process_response_event=call_process_response;
808 call_op_callbacks.process_timeout=call_process_timeout;
809 call_op_callbacks.process_transaction_terminated=call_process_transaction_terminated;
810 call_op_callbacks.process_request_event=process_request_event;
811 call_op_callbacks.process_dialog_terminated=process_dialog_terminated;
812 }
813 op->callbacks=&call_op_callbacks;
814 op->type=SalOpCall;
815 }
816
handle_offer_answer_response(SalOp * op,belle_sip_response_t * response)817 static void handle_offer_answer_response(SalOp* op, belle_sip_response_t* response) {
818 if (op->base.local_media){
819 /*this is the case where we received an invite without SDP*/
820 if (op->sdp_offering) {
821 set_sdp_from_desc(BELLE_SIP_MESSAGE(response),op->base.local_media);
822 }else{
823
824 if ( op->sdp_answer==NULL )
825 {
826 if( op->sdp_handling == SalOpSDPSimulateRemove ){
827 ms_warning("Simulating SDP removal in answer for op %p", op);
828 } else {
829 sdp_process(op);
830 }
831 }
832
833 if (op->sdp_answer){
834 set_sdp(BELLE_SIP_MESSAGE(response),op->sdp_answer);
835 belle_sip_object_unref(op->sdp_answer);
836 op->sdp_answer=NULL;
837 }
838 }
839 }else{
840 ms_error("You are accepting a call but not defined any media capabilities !");
841 }
842 }
843
sal_call_notify_ringing(SalOp * op,bool_t early_media)844 int sal_call_notify_ringing(SalOp *op, bool_t early_media){
845 int status_code =early_media?183:180;
846 belle_sip_request_t* req=belle_sip_transaction_get_request(BELLE_SIP_TRANSACTION(op->pending_server_trans));
847 belle_sip_response_t* ringing_response = sal_op_create_response_from_request(op,req,status_code);
848 belle_sip_header_t *require;
849 const char *tags=NULL;
850
851 if (early_media){
852 handle_offer_answer_response(op,ringing_response);
853 }
854 require=belle_sip_message_get_header((belle_sip_message_t*)req,"Require");
855 if (require) tags=belle_sip_header_get_unparsed_value(require);
856 /* if client requires 100rel, then add necessary stuff*/
857 if (tags && strstr(tags,"100rel")!=0) {
858 belle_sip_message_add_header((belle_sip_message_t*)ringing_response,belle_sip_header_create("Require","100rel"));
859 belle_sip_message_add_header((belle_sip_message_t*)ringing_response,belle_sip_header_create("RSeq","1"));
860 }
861
862 #ifndef SAL_OP_CALL_FORCE_CONTACT_IN_RINGING
863 if (tags && strstr(tags,"100rel")!=0)
864 #endif
865 {
866 belle_sip_header_address_t* contact= (belle_sip_header_address_t*)sal_op_get_contact_address(op);
867 belle_sip_header_contact_t* contact_header;
868 if (contact && (contact_header=belle_sip_header_contact_create(contact))) {
869 belle_sip_message_add_header(BELLE_SIP_MESSAGE(ringing_response),BELLE_SIP_HEADER(contact_header));
870 }
871 }
872 belle_sip_server_transaction_send_response(op->pending_server_trans,ringing_response);
873 return 0;
874 }
875
876
877 /*accept an incoming call or, during a call accept a reINVITE*/
sal_call_accept(SalOp * h)878 int sal_call_accept(SalOp*h){
879 belle_sip_response_t *response;
880 belle_sip_header_contact_t* contact_header;
881 belle_sip_server_transaction_t* transaction;
882
883 /*first check if an UPDATE transaction need to be accepted*/
884 if (h->pending_update_server_trans) {
885 transaction=h->pending_update_server_trans;
886 } else if (h->pending_server_trans) {
887 /*so it must be an invite/re-invite*/
888 transaction=h->pending_server_trans;
889 } else {
890 ms_error("No transaction to accept for op [%p]",h);
891 return -1;
892 }
893 ms_message("Accepting server transaction [%p] on op [%p]", transaction, h);
894
895 /* sends a 200 OK */
896 response = sal_op_create_response_from_request(h,belle_sip_transaction_get_request(BELLE_SIP_TRANSACTION(transaction)),200);
897 if (response==NULL){
898 ms_error("Fail to build answer for call");
899 return -1;
900 }
901 belle_sip_message_add_header(BELLE_SIP_MESSAGE(response),BELLE_SIP_HEADER(create_allow(h->base.root->enable_sip_update)));
902 if (h->base.root->session_expires!=0){
903 /* if (h->supports_session_timers) {*/
904 belle_sip_message_add_header(BELLE_SIP_MESSAGE(response),belle_sip_header_create("Supported", "timer"));
905 belle_sip_message_add_header(BELLE_SIP_MESSAGE(response),belle_sip_header_create( "Session-expires", "600;refresher=uac"));
906 /*}*/
907 }
908
909 if ((contact_header=sal_op_create_contact(h))) {
910 belle_sip_message_add_header(BELLE_SIP_MESSAGE(response),BELLE_SIP_HEADER(contact_header));
911 }
912
913 _sal_op_add_custom_headers(h, BELLE_SIP_MESSAGE(response));
914
915 handle_offer_answer_response(h,response);
916
917 belle_sip_server_transaction_send_response(transaction,response);
918 if (h->pending_update_server_trans) {
919 belle_sip_object_unref(h->pending_update_server_trans);
920 h->pending_update_server_trans=NULL;
921 }
922 if (h->state == SalOpStateEarly){
923 h->state = SalOpStateActive;
924 }
925 return 0;
926 }
927
sal_call_make_reason_header(const SalErrorInfo * info)928 static belle_sip_header_reason_t *sal_call_make_reason_header( const SalErrorInfo *info){
929 if (info != NULL){
930 belle_sip_header_reason_t* reason = BELLE_SIP_HEADER_REASON(belle_sip_header_reason_new());
931 belle_sip_header_reason_set_text(reason, info->status_string);
932 belle_sip_header_reason_set_protocol(reason,info->protocol);
933 belle_sip_header_reason_set_cause(reason,info->protocol_code);
934 return reason;
935 }
936 return NULL;
937 }
938
sal_call_cancel_invite_with_info(SalOp * op,const SalErrorInfo * info)939 void sal_call_cancel_invite_with_info(SalOp* op, const SalErrorInfo *info) {
940 belle_sip_request_t* cancel;
941 ms_message("Cancelling INVITE request from [%s] to [%s] ",sal_op_get_from(op), sal_op_get_to(op));
942 cancel = belle_sip_client_transaction_create_cancel(op->pending_client_trans);
943 if (cancel){
944 if (info != NULL){
945 belle_sip_header_reason_t* reason = sal_call_make_reason_header(info);
946 belle_sip_message_add_header(BELLE_SIP_MESSAGE(cancel),BELLE_SIP_HEADER(reason));
947 }
948 sal_op_send_request(op,cancel);
949 }else if (op->dialog){
950 belle_sip_dialog_state_t state = belle_sip_dialog_get_state(op->dialog);;
951 /*case where the response received is invalid (could not establish a dialog), but the transaction is not cancellable
952 * because already terminated*/
953 switch(state){
954 case BELLE_SIP_DIALOG_EARLY:
955 case BELLE_SIP_DIALOG_NULL:
956 /*force kill the dialog*/
957 ms_warning("op [%p]: force kill of dialog [%p]", op, op->dialog);
958 belle_sip_dialog_delete(op->dialog);
959 break;
960 default:
961 break;
962 }
963 }
964 }
965
sal_call_decline(SalOp * op,SalReason reason,const char * redirection)966 int sal_call_decline(SalOp *op, SalReason reason, const char *redirection /*optional*/){
967 belle_sip_response_t* response;
968 belle_sip_header_contact_t* contact=NULL;
969 int status=sal_reason_to_sip_code(reason);
970 belle_sip_transaction_t *trans;
971
972 if (reason==SalReasonRedirect){
973 if (redirection!=NULL) {
974 if (strstr(redirection,"sip:")!=0) status=302;
975 else status=380;
976 contact= belle_sip_header_contact_new();
977 belle_sip_header_address_set_uri(BELLE_SIP_HEADER_ADDRESS(contact),belle_sip_uri_parse(redirection));
978 } else {
979 ms_error("Cannot redirect to null");
980 }
981 }
982 trans=(belle_sip_transaction_t*)op->pending_server_trans;
983 if (!trans) trans=(belle_sip_transaction_t*)op->pending_update_server_trans;
984 if (!trans){
985 ms_error("sal_call_decline(): no pending transaction to decline.");
986 return -1;
987 }
988 response = sal_op_create_response_from_request(op,belle_sip_transaction_get_request(trans),status);
989 if (contact) belle_sip_message_add_header(BELLE_SIP_MESSAGE(response),BELLE_SIP_HEADER(contact));
990 belle_sip_server_transaction_send_response(BELLE_SIP_SERVER_TRANSACTION(trans),response);
991 return 0;
992 }
993
sal_call_decline_with_error_info(SalOp * op,const SalErrorInfo * info,const char * redirection)994 int sal_call_decline_with_error_info(SalOp *op, const SalErrorInfo *info, const char *redirection /*optional*/){
995 belle_sip_response_t* response;
996 belle_sip_header_contact_t* contact=NULL;
997 int status = info->protocol_code;
998 belle_sip_transaction_t *trans;
999
1000 if (info->reason==SalReasonRedirect){
1001 if (redirection!=NULL) {
1002 if (strstr(redirection,"sip:")!=0) status=302;
1003 else status=380;
1004 contact= belle_sip_header_contact_new();
1005 belle_sip_header_address_set_uri(BELLE_SIP_HEADER_ADDRESS(contact),belle_sip_uri_parse(redirection));
1006 } else {
1007 ms_error("Cannot redirect to null");
1008 }
1009 }
1010 trans=(belle_sip_transaction_t*)op->pending_server_trans;
1011 if (!trans) trans=(belle_sip_transaction_t*)op->pending_update_server_trans;
1012 if (!trans){
1013 ms_error("sal_call_decline_with_error_info(): no pending transaction to decline.");
1014 return -1;
1015 }
1016 response = sal_op_create_response_from_request(op,belle_sip_transaction_get_request(trans),status);
1017 belle_sip_header_reason_t* reason_header = sal_call_make_reason_header(info->sub_sei);
1018 if (reason_header) {
1019 belle_sip_message_add_header(BELLE_SIP_MESSAGE(response),BELLE_SIP_HEADER(reason_header));
1020 }
1021
1022 if (contact) {
1023 belle_sip_message_add_header(BELLE_SIP_MESSAGE(response),BELLE_SIP_HEADER(contact));
1024 }
1025 belle_sip_server_transaction_send_response(BELLE_SIP_SERVER_TRANSACTION(trans),response);
1026 return 0;
1027 }
1028
sal_call_update(SalOp * op,const char * subject,bool_t no_user_consent)1029 int sal_call_update(SalOp *op, const char *subject, bool_t no_user_consent){
1030 belle_sip_request_t *update;
1031 belle_sip_dialog_state_t state;
1032
1033 if (op->dialog == NULL) {
1034 /* If the dialog does not exist, this is that we are trying to recover from a connection loss
1035 during a very early state of outgoing call initiation (the dialog has not been created yet). */
1036 const char *from = sal_op_get_from(op);
1037 const char *to = sal_op_get_to(op);
1038 return sal_call(op, from, to);
1039 }
1040
1041 state = belle_sip_dialog_get_state(op->dialog);
1042 belle_sip_dialog_enable_pending_trans_checking(op->dialog,op->base.root->pending_trans_checking);
1043
1044 /*check for dialog state*/
1045 if ( state == BELLE_SIP_DIALOG_CONFIRMED) {
1046 if (no_user_consent)
1047 update=belle_sip_dialog_create_request(op->dialog,"UPDATE");
1048 else
1049 update=belle_sip_dialog_create_request(op->dialog,"INVITE");
1050 } else if (state == BELLE_SIP_DIALOG_EARLY) {
1051 update=belle_sip_dialog_create_request(op->dialog,"UPDATE");
1052 } else {
1053 ms_error("Cannot update op [%p] with dialog [%p] in state [%s]",op, op->dialog,belle_sip_dialog_state_to_string(state));
1054 return -1;
1055 }
1056 if (update){
1057 belle_sip_message_add_header(BELLE_SIP_MESSAGE(update),belle_sip_header_create( "Subject", subject));
1058 sal_op_fill_invite(op, update);
1059 return sal_op_send_request(op,update);
1060 }
1061 /*it failed why ?*/
1062 if (belle_sip_dialog_request_pending(op->dialog))
1063 sal_error_info_set(&op->error_info,SalReasonRequestPending, "SIP", 491,NULL,NULL);
1064 else
1065 sal_error_info_set(&op->error_info,SalReasonUnknown, "SIP", 500,NULL,NULL);
1066 return -1;
1067 }
1068
sal_call_get_remote_media_description(SalOp * h)1069 SalMediaDescription * sal_call_get_remote_media_description(SalOp *h){
1070 return h->base.remote_media;
1071 }
1072
sal_call_get_final_media_description(SalOp * h)1073 SalMediaDescription * sal_call_get_final_media_description(SalOp *h){
1074 if (h->base.local_media && h->base.remote_media && !h->result){
1075 sdp_process(h);
1076 }
1077 return h->result;
1078 }
1079
sal_call_send_dtmf(SalOp * h,char dtmf)1080 int sal_call_send_dtmf(SalOp *h, char dtmf){
1081 if (h->dialog && (belle_sip_dialog_get_state(h->dialog) == BELLE_SIP_DIALOG_CONFIRMED || belle_sip_dialog_get_state(h->dialog) == BELLE_SIP_DIALOG_EARLY)){
1082 belle_sip_request_t *req=belle_sip_dialog_create_queued_request(h->dialog,"INFO");
1083 if (req){
1084 size_t bodylen;
1085 char dtmf_body[128]={0};
1086
1087 snprintf(dtmf_body, sizeof(dtmf_body)-1, "Signal=%c\r\nDuration=250\r\n", dtmf);
1088 bodylen=strlen(dtmf_body);
1089 belle_sip_message_set_body((belle_sip_message_t*)req,dtmf_body,bodylen);
1090 belle_sip_message_add_header((belle_sip_message_t*)req,(belle_sip_header_t*)belle_sip_header_content_length_create(bodylen));
1091 belle_sip_message_add_header((belle_sip_message_t*)req,(belle_sip_header_t*)belle_sip_header_content_type_create("application", "dtmf-relay"));
1092 sal_op_send_request(h,req);
1093 }else ms_error("sal_call_send_dtmf(): could not build request");
1094 }else ms_error("sal_call_send_dtmf(): no dialog");
1095 return 0;
1096 }
1097
1098
sal_call_terminate_with_error(SalOp * op,const SalErrorInfo * info)1099 int sal_call_terminate_with_error(SalOp *op, const SalErrorInfo *info){
1100 SalErrorInfo sei = { 0 };
1101 const SalErrorInfo *p_sei;
1102 belle_sip_dialog_state_t dialog_state = op->dialog ? belle_sip_dialog_get_state(op->dialog) : BELLE_SIP_DIALOG_NULL;
1103 int ret = 0;
1104
1105 if (info == NULL && dialog_state != BELLE_SIP_DIALOG_CONFIRMED && op->dir == SalOpDirIncoming){
1106 /*the purpose of this line is to set a default SalErrorInfo for declining an incoming call (not yet established of course) */
1107 sal_error_info_set(&sei,SalReasonDeclined, "SIP", 0, NULL, NULL);
1108 p_sei = &sei;
1109 } else{
1110 p_sei = info;
1111 }
1112 if (op->state==SalOpStateTerminating || op->state==SalOpStateTerminated) {
1113 ms_error("Cannot terminate op [%p] in state [%s]",op,sal_op_state_to_string(op->state));
1114 ret = -1;
1115 goto end;
1116 }
1117 switch(dialog_state) {
1118 case BELLE_SIP_DIALOG_CONFIRMED: {
1119 belle_sip_request_t * req = belle_sip_dialog_create_request(op->dialog,"BYE");
1120 if (info != NULL){
1121 belle_sip_header_reason_t* reason = sal_call_make_reason_header(info);
1122 belle_sip_message_add_header(BELLE_SIP_MESSAGE(req),BELLE_SIP_HEADER(reason));
1123 }
1124 sal_op_send_request(op,req);
1125 op->state=SalOpStateTerminating;
1126 break;
1127 }
1128
1129 case BELLE_SIP_DIALOG_NULL: {
1130 if (op->dir == SalOpDirIncoming) {
1131 sal_call_decline_with_error_info(op, p_sei, NULL);
1132 op->state=SalOpStateTerminated;
1133 } else if (op->pending_client_trans){
1134 if (belle_sip_transaction_get_state(BELLE_SIP_TRANSACTION(op->pending_client_trans)) == BELLE_SIP_TRANSACTION_PROCEEDING){
1135 cancelling_invite(op, p_sei);
1136 }else{
1137 /* Case where the CANCEL cannot be sent because no provisional response was received so far.
1138 * The Op must be kept for the time of the transaction in case a response is received later.
1139 * The state is passed to Terminating to remember to terminate later.
1140 */
1141 op->state=SalOpStateTerminating;
1142 }
1143 }
1144 break;
1145 }
1146 case BELLE_SIP_DIALOG_EARLY: {
1147 if (op->dir == SalOpDirIncoming) {
1148 sal_call_decline_with_error_info(op, p_sei,NULL);
1149 op->state=SalOpStateTerminated;
1150 } else {
1151 cancelling_invite(op, p_sei);
1152 }
1153 break;
1154 }
1155 default: {
1156 ms_error("sal_call_terminate not implemented yet for dialog state [%s]",belle_sip_dialog_state_to_string(dialog_state));
1157 ret = -1;
1158 goto end;
1159 }
1160 }
1161 end:
1162 sal_error_info_reset(&sei);
1163 return ret;
1164 }
1165
1166
sal_call_terminate(SalOp * op)1167 int sal_call_terminate(SalOp *op){
1168 return sal_call_terminate_with_error(op, NULL);
1169 }
1170
1171
sal_call_autoanswer_asked(SalOp * op)1172 bool_t sal_call_autoanswer_asked(SalOp *op){
1173 return op->auto_answer_asked;
1174 }
1175
sal_call_send_vfu_request(SalOp * op)1176 void sal_call_send_vfu_request(SalOp *op){
1177 char info_body[] =
1178 "<?xml version=\"1.0\" encoding=\"utf-8\" ?>"
1179 "<media_control>"
1180 " <vc_primitive>"
1181 " <to_encoder>"
1182 " <picture_fast_update></picture_fast_update>"
1183 " </to_encoder>"
1184 " </vc_primitive>"
1185 "</media_control>";
1186 size_t content_lenth = sizeof(info_body) - 1;
1187 belle_sip_dialog_state_t dialog_state=op->dialog?belle_sip_dialog_get_state(op->dialog):BELLE_SIP_DIALOG_NULL; /*no dialog = dialog in NULL state*/
1188 if (dialog_state == BELLE_SIP_DIALOG_CONFIRMED) {
1189 belle_sip_request_t* info = belle_sip_dialog_create_queued_request(op->dialog,"INFO");
1190 int error=TRUE;
1191 if (info) {
1192 belle_sip_message_add_header(BELLE_SIP_MESSAGE(info),BELLE_SIP_HEADER(belle_sip_header_content_type_create("application","media_control+xml")));
1193 belle_sip_message_add_header(BELLE_SIP_MESSAGE(info),BELLE_SIP_HEADER(belle_sip_header_content_length_create(content_lenth)));
1194 belle_sip_message_set_body(BELLE_SIP_MESSAGE(info),info_body,content_lenth);
1195 error=sal_op_send_request(op,info);
1196 }
1197 if (error)
1198 ms_warning("Cannot send vfu request to [%s] ", sal_op_get_to(op));
1199
1200 } else {
1201 ms_warning("Cannot send vfu request to [%s] because dialog [%p] in wrong state [%s]",sal_op_get_to(op)
1202 ,op->dialog
1203 ,belle_sip_dialog_state_to_string(dialog_state));
1204 }
1205
1206 return ;
1207 }
1208
sal_call_is_offerer(const SalOp * h)1209 int sal_call_is_offerer(const SalOp *h){
1210 return h->sdp_offering;
1211 }
1212
sal_call_compare_op(const SalOp * op1,const SalOp * op2)1213 bool_t sal_call_compare_op(const SalOp *op1, const SalOp *op2) {
1214 if (strcmp(op1->base.call_id, op2->base.call_id) == 0) return TRUE;
1215 return FALSE;
1216 }
1217
sal_call_dialog_request_pending(const SalOp * op)1218 bool_t sal_call_dialog_request_pending(const SalOp *op) {
1219 return belle_sip_dialog_request_pending(op->dialog) ? TRUE : FALSE;
1220 }
1221
sal_call_get_local_tag(SalOp * op)1222 const char * sal_call_get_local_tag(SalOp *op) {
1223 return belle_sip_dialog_get_local_tag(op->dialog);
1224 }
1225
sal_call_get_remote_tag(SalOp * op)1226 const char * sal_call_get_remote_tag(SalOp *op) {
1227 return belle_sip_dialog_get_remote_tag(op->dialog);
1228 }
1229
sal_call_set_replaces(SalOp * op,const char * call_id,const char * from_tag,const char * to_tag)1230 void sal_call_set_replaces(SalOp *op, const char *call_id, const char *from_tag, const char *to_tag) {
1231 belle_sip_header_replaces_t *replaces = belle_sip_header_replaces_create(call_id, from_tag, to_tag);
1232 sal_op_set_replaces(op, replaces);
1233 }
1234