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