Пример #1
0
static void queue_message_delayed(belle_sip_channel_t *obj, belle_sip_message_t *msg){
	delay_send_t *ctx=belle_sip_malloc(sizeof(delay_send_t));
	ctx->chan=(belle_sip_channel_t*)belle_sip_object_ref(obj);
	ctx->msg=(belle_sip_message_t*)belle_sip_object_ref(msg);
	belle_sip_main_loop_add_timeout(obj->stack->ml,(belle_sip_source_func_t)on_delayed_send_do,ctx,obj->stack->tx_delay);
	belle_sip_message("channel %p: message sending delayed by %i ms",obj,obj->stack->tx_delay);
}
static void testMalformedMandatoryField(void){
	belle_sip_stack_t*        stack = belle_sip_stack_new(NULL);
	belle_sip_listening_point_t* lp = belle_sip_stack_create_listening_point(stack,
																			 "127.0.0.1",
																			 LISTENING_POINT_PORT,
																			 "tcp");
	belle_sip_provider_t* provider = belle_sip_provider_new(stack,lp);
	belle_sip_listener_callbacks_t listener_cbs = {0};

	/* the MESSAGE message has no definition on which fields are required, which means we'll go into
	 *
	 *
	 *
	 */

	const char* raw_message = "MESSAGE sip:[email protected]:5861;transport=tcp SIP/2.0\r\n"
			"Via: SIP/2.0/TCP " LISTENING_POINT_HOSTPORT ";branch=z9hG4bK5eca096a;rport\r\n"
			"Max-Forwards: 70\r\n"
			"From: \"MS TFT\" <sip:[email protected]>;tag=as2413a381\r\n"
			"To: <sip:[email protected]:5861;app-id=fr.lollol.phone.prod;pn-type=apple;pn-tok=azertyuiopqsdfghhjjkmlqoijfubieuzhqiluehcpoqidufqsdkjlcnuoishcvs;pn-msg-str=IM_MSG;pn-call-str=IC_MSG;pn-call-snd=ring.caf;pn-msg-snd=msg.caf;transport=tcp>;tag=\r\n"
			"Call-ID: [email protected]:5060\r\n"
			"CSeq: 103 MESSAGE\r\n"
			"User-Agent: Sip Server On Host (20130523_12h10)\r\n"
			"Content-Type: text/plain;charset=UTF-8\r\n"
			"Content-Length: 276\r\n"
			"\r\n"
			"<?xml version=\"1.0\" encoding=\"UTF-8\"?>\r\n"
			"<VDUCMediaConfig GId=\"1234567\" IdPosteType=\"123\"><Label>Salut Bilout TFT MS2</Label><MediaConfig GId=\"456\"><CommandCode Code=\"MediaCommand*\"><Label>Porte ouverte</Label></CommandCode><withVideo FPS=\"0.0\"/></MediaConfig></VDUCMediaConfig>\r\n"
			"\r\n";

	belle_sip_message_t* message = belle_sip_message_parse(raw_message);
	belle_sip_listener_t* listener = NULL;

	int called_times = 0;

	listener_cbs.process_response_event = testMalformedFrom_process_response_cb;
	listener = belle_sip_listener_create_from_callbacks(&listener_cbs, &called_times);

	belle_sip_provider_add_sip_listener(provider, listener);

	belle_sip_object_ref(message);
	belle_sip_object_ref(message); /* double ref: originally the message is created with 0 refcount, and dispatch_message will unref() it.*/

	belle_sip_provider_dispatch_message(provider, message);
	// we expect the stack to send a 400 error
	belle_sip_stack_sleep(stack,1000);

	CU_ASSERT_EQUAL(called_times,1);
	belle_sip_provider_remove_sip_listener(provider,listener);

	belle_sip_object_unref(listener);
	belle_sip_object_unref(provider);
	belle_sip_object_unref(stack);
	belle_sip_object_unref(message);

}
Пример #3
0
belle_sip_dialog_t *belle_sip_dialog_new(belle_sip_transaction_t *t){
	belle_sip_dialog_t *obj;
	belle_sip_header_from_t *from;
	const char *from_tag;
	belle_sip_header_to_t *to;
	const char *to_tag=NULL;

	from=belle_sip_message_get_header_by_type(t->request,belle_sip_header_from_t);
	if (from==NULL){
		belle_sip_error("belle_sip_dialog_new(): no from!");
		return NULL;
	}
	from_tag=belle_sip_header_from_get_tag(from);
	if (from_tag==NULL){
		belle_sip_error("belle_sip_dialog_new(): no from tag!");
		return NULL;
	}

	if (t->last_response) {
		to=belle_sip_message_get_header_by_type(t->last_response,belle_sip_header_to_t);
		if (to==NULL){
			belle_sip_error("belle_sip_dialog_new(): no to!");
			return NULL;
		}
		to_tag=belle_sip_header_to_get_tag(to);
	}
	obj=belle_sip_object_new(belle_sip_dialog_t);
	obj->terminate_on_bye=1;
	obj->provider=t->provider;
	
	if (BELLE_SIP_OBJECT_IS_INSTANCE_OF(t,belle_sip_server_transaction_t)){
		obj->remote_tag=belle_sip_strdup(from_tag);
		obj->local_tag=to_tag?belle_sip_strdup(to_tag):NULL; /*might be null at dialog creation*/
		obj->remote_party=(belle_sip_header_address_t*)belle_sip_object_ref(from);
		obj->is_server=TRUE;
	}else{
		const belle_sip_list_t *predefined_routes=NULL;
		obj->local_tag=belle_sip_strdup(from_tag);
		obj->remote_tag=to_tag?belle_sip_strdup(to_tag):NULL; /*might be null at dialog creation*/
		obj->local_party=(belle_sip_header_address_t*)belle_sip_object_ref(from);
		obj->is_server=FALSE;
		for(predefined_routes=belle_sip_message_get_headers((belle_sip_message_t*)t->request,BELLE_SIP_ROUTE);
			predefined_routes!=NULL;predefined_routes=predefined_routes->next){
			obj->route_set=belle_sip_list_append(obj->route_set,belle_sip_object_ref(predefined_routes->data));	
		}
	}
	belle_sip_message("New %s dialog [%p] , local tag [%s], remote tag [%s]"
			,obj->is_server?"server":"client"
			,obj
			,obj->local_tag?obj->local_tag:""
			,obj->remote_tag?obj->remote_tag:"");
	set_state(obj,BELLE_SIP_DIALOG_NULL);
	return obj;
}
Пример #4
0
static int belle_sip_dialog_init_as_uac(belle_sip_dialog_t *obj, belle_sip_request_t *req, belle_sip_response_t *resp){
	const belle_sip_list_t *elem;
	belle_sip_header_contact_t *ct=belle_sip_message_get_header_by_type(resp,belle_sip_header_contact_t);
	belle_sip_header_cseq_t *cseq=belle_sip_message_get_header_by_type(req,belle_sip_header_cseq_t);
	belle_sip_header_to_t *to=belle_sip_message_get_header_by_type(resp,belle_sip_header_to_t);
	belle_sip_header_via_t *via=belle_sip_message_get_header_by_type(req,belle_sip_header_via_t);
	belle_sip_uri_t *requri=belle_sip_request_get_uri(req);

	if (!to){
		belle_sip_error("No to in response.");
		return -1;
	}
	if (!cseq){
		belle_sip_error("No cseq in request.");
		return -1;
	}
	if (!via){
		belle_sip_error("No via in request.");
		return -1;
	}

	if (strcasecmp(belle_sip_header_via_get_protocol(via),"TLS")==0
	    && belle_sip_uri_is_secure(requri)){
		obj->is_secure=TRUE;
	}
	/**12.1.2
	 *  The route set MUST be set to the list of URIs in the Record-Route
   	 *header field from the response, taken in reverse order and preserving
   	 *all URI parameters.  If no Record-Route header field is present in
   	 *the response, the route set MUST be set to the empty set.
   	 **/
	obj->route_set=belle_sip_list_free_with_data(obj->route_set,belle_sip_object_unref);
	for(elem=belle_sip_message_get_headers((belle_sip_message_t*)resp,BELLE_SIP_RECORD_ROUTE);elem!=NULL;elem=elem->next){
		obj->route_set=belle_sip_list_prepend(obj->route_set,belle_sip_object_ref(belle_sip_header_route_create(
		                                     (belle_sip_header_address_t*)elem->data)));
	}

	check_route_set(obj->route_set);
	/*contact might be provided later*/
	if (ct)
		obj->remote_target=(belle_sip_header_address_t*)belle_sip_object_ref(ct);

	obj->local_cseq=belle_sip_header_cseq_get_seq_number(cseq);
	/*call id is already set */
	/*local_tag is already set*/
	obj->remote_party=(belle_sip_header_address_t*)belle_sip_object_ref(to);
	/*local party is already set*/
	if (strcmp(belle_sip_request_get_method(req),"INVITE")==0){
		set_last_out_invite(obj,req);
	}
	return 0;
}
Пример #5
0
belle_sip_uri_t* belle_sip_uri_new () {
	belle_sip_uri_t* l_object = belle_sip_object_new(belle_sip_uri_t);
	belle_sip_parameters_init((belle_sip_parameters_t*)l_object); /*super*/
	l_object->header_list = belle_sip_parameters_new();
	belle_sip_object_ref(l_object->header_list);
	return l_object;
}
Пример #6
0
belle_sip_refresher_t* belle_sip_refresher_new(belle_sip_client_transaction_t* transaction) {
	belle_sip_refresher_t* refresher;
	belle_sip_transaction_state_t state=belle_sip_transaction_get_state(BELLE_SIP_TRANSACTION(transaction));
	belle_sip_request_t* request = belle_sip_transaction_get_request(BELLE_SIP_TRANSACTION(transaction));
	int is_register=strcmp("REGISTER",belle_sip_request_get_method(request))==0;

	refresher = (belle_sip_refresher_t*)belle_sip_object_new(belle_sip_refresher_t);
	refresher->transaction=transaction;
	refresher->state=stopped;
	refresher->number_of_retry=0;
	belle_sip_object_ref(transaction);
	refresher->retry_after=DEFAULT_RETRY_AFTER;

	if (belle_sip_transaction_get_dialog(BELLE_SIP_TRANSACTION(transaction))) {
		set_or_update_dialog(refresher, belle_sip_transaction_get_dialog(BELLE_SIP_TRANSACTION(transaction)));
	}
	belle_sip_provider_add_internal_sip_listener(transaction->base.provider,BELLE_SIP_LISTENER(refresher), is_register);
	if (set_expires_from_trans(refresher)==-1){
		belle_sip_error("Unable to extract refresh value from transaction [%p]",transaction);
	}
	if (belle_sip_transaction_state_is_transient(state)) {
		belle_sip_message("Refresher [%p] takes ownership of transaction [%p]",refresher,transaction);
		transaction->base.is_internal=1;
		refresher->state=started;
	}else{
		belle_sip_refresher_start(refresher);
	}
	return refresher;
}
Пример #7
0
static LinphoneFriendList * linphone_friend_list_new(void) {
	LinphoneFriendList *list = belle_sip_object_new(LinphoneFriendList);
	list->cbs = linphone_friend_list_cbs_new();
	list->enable_subscriptions = TRUE;
	belle_sip_object_ref(list);
	return list;
}
Пример #8
0
int belle_sip_dialog_establish(belle_sip_dialog_t *obj, belle_sip_request_t *req, belle_sip_response_t *resp){
	belle_sip_header_to_t *to=belle_sip_message_get_header_by_type(resp,belle_sip_header_to_t);
	belle_sip_header_call_id_t *call_id=belle_sip_message_get_header_by_type(req,belle_sip_header_call_id_t);
	int err;

	if (obj->state != BELLE_SIP_DIALOG_NULL) {
		belle_sip_error("Dialog [%p] already established.",obj);
		return -1;
	}
	if (!call_id){
		belle_sip_error("No call-id in response.");
		return -1;
	}
	obj->call_id=(belle_sip_header_call_id_t*)belle_sip_object_ref(call_id);

	if (obj->is_server)
		err= belle_sip_dialog_init_as_uas(obj,req,resp);
	else
		err= belle_sip_dialog_init_as_uac(obj,req,resp);
	
	if (err) return err;

	set_to_tag(obj,to);

	return 0;
}
Пример #9
0
void linphone_xml_rpc_session_send_request(LinphoneXmlRpcSession *session, LinphoneXmlRpcRequest *request) {
	belle_http_request_listener_callbacks_t cbs = { 0 };
	belle_http_request_listener_t *l;
	belle_generic_uri_t *uri;
	belle_http_request_t *req;
	belle_sip_memory_body_handler_t *bh;
	const char *data;
	linphone_xml_rpc_request_ref(request);

	uri = belle_generic_uri_parse(session->url);
	if (!uri) {
		ms_error("Could not send request, URL %s is invalid", session->url);
		process_io_error_from_post_xml_rpc_request(request, NULL);
		return;
	}
	req = belle_http_request_create("POST", uri, belle_sip_header_content_type_create("text", "xml"), NULL);
	if (!req) {
		belle_sip_object_unref(uri);
		process_io_error_from_post_xml_rpc_request(request, NULL);
		return;
	}
	data = linphone_xml_rpc_request_get_content(request);
	bh = belle_sip_memory_body_handler_new_copy_from_buffer(data, strlen(data), NULL, NULL);
	belle_sip_message_set_body_handler(BELLE_SIP_MESSAGE(req), BELLE_SIP_BODY_HANDLER(bh));
	cbs.process_response = process_response_from_post_xml_rpc_request;
	cbs.process_io_error = process_io_error_from_post_xml_rpc_request;
	cbs.process_auth_requested = process_auth_requested_from_post_xml_rpc_request;
	l = belle_http_request_listener_create_from_callbacks(&cbs, request);
	belle_http_provider_send_request(session->core->http_provider, req, l);
	/*ensure that the listener object will be destroyed with the request*/
	belle_sip_object_data_set(BELLE_SIP_OBJECT(request), "listener", l, belle_sip_object_unref);
	/*prevent destruction of the session while there are still pending http requests*/
	belle_sip_object_data_set(BELLE_SIP_OBJECT(request), "session", belle_sip_object_ref(session), belle_sip_object_unref);
}
Пример #10
0
static void sdp_process(SalOp *h){
	ms_message("Doing SDP offer/answer process of type %s",h->sdp_offering ? "outgoing" : "incoming");
	if (h->result){
		sal_media_description_unref(h->result);
	}
	h->result=sal_media_description_new();
	if (h->sdp_offering){
		offer_answer_initiate_outgoing(h->base.local_media,h->base.remote_media,h->result);
	}else{
		int i;
		if (h->sdp_answer){
			belle_sip_object_unref(h->sdp_answer);
		}
		offer_answer_initiate_incoming(h->base.local_media,h->base.remote_media,h->result,h->base.root->one_matching_codec);
		h->sdp_answer=(belle_sdp_session_description_t *)belle_sip_object_ref(media_description_to_sdp(h->result));
		/*once we have generated the SDP answer, we modify the result description for processing by the upper layer.
		 It should contains media parameters constraint from the remote offer, not our response*/
		strcpy(h->result->addr,h->base.remote_media->addr);
		h->result->bandwidth=h->base.remote_media->bandwidth;

		for(i=0;i<h->result->n_active_streams;++i){
			strcpy(h->result->streams[i].rtp_addr,h->base.remote_media->streams[i].rtp_addr);
			h->result->streams[i].ptime=h->base.remote_media->streams[i].ptime;
			h->result->streams[i].bandwidth=h->base.remote_media->streams[i].bandwidth;
			h->result->streams[i].rtp_port=h->base.remote_media->streams[i].rtp_port;
			strcpy(h->result->streams[i].rtcp_addr,h->base.remote_media->streams[i].rtcp_addr);
			h->result->streams[i].rtcp_port=h->base.remote_media->streams[i].rtcp_port;

			if (h->result->streams[i].proto == SalProtoRtpSavp) {
				h->result->streams[i].crypto[0] = h->base.remote_media->streams[i].crypto[0];
			}
		}
	}

}
Пример #11
0
static LinphoneNatPolicy * _linphone_nat_policy_new_with_ref(LinphoneCore *lc, const char *ref) {
	LinphoneNatPolicy *policy = belle_sip_object_new(LinphoneNatPolicy);
	belle_sip_object_ref(policy);
	policy->lc = lc;
	policy->ref = belle_sip_strdup(ref);
	return policy;
}
Пример #12
0
/*call transfer*/
static void sal_op_set_referred_by(SalOp* op,belle_sip_header_referred_by_t* referred_by) {
	if (op->referred_by){
		belle_sip_object_unref(op->referred_by);
	}
	op->referred_by=referred_by;
	belle_sip_object_ref(op->referred_by);
}
Пример #13
0
int sal_subscribe(SalOp *op, const char *from, const char *to, const char *eventname, int expires, const SalBody *body){
	belle_sip_request_t *req=NULL;
	
	if (from)
		sal_op_set_from(op,from);
	if (to)
		sal_op_set_to(op,to);
	
	if (!op->dialog){
		sal_op_subscribe_fill_cbs(op);
		/*???sal_exosip_fix_route(op); make sure to ha ;lr*/
		req=sal_op_build_request(op,"SUBSCRIBE");
		if (eventname){
			if (op->event) belle_sip_object_unref(op->event);
			op->event=belle_sip_header_create("Event",eventname);
			belle_sip_object_ref(op->event);
		}
		belle_sip_message_add_header(BELLE_SIP_MESSAGE(req),op->event);
		belle_sip_message_add_header(BELLE_SIP_MESSAGE(req),BELLE_SIP_HEADER(belle_sip_header_expires_create(expires)));
		sal_op_add_body(op,(belle_sip_message_t*)req,body);
		return sal_op_send_and_create_refresher(op,req,expires,subscribe_refresher_listener);
	}else if (op->refresher){
		const belle_sip_transaction_t *tr=(const belle_sip_transaction_t*) belle_sip_refresher_get_transaction(op->refresher);
		belle_sip_request_t *last_req=belle_sip_transaction_get_request(tr);
		/* modify last request to update body*/
		sal_op_add_body(op,(belle_sip_message_t*)last_req,body);
		return belle_sip_refresher_refresh(op->refresher,expires);
	}
	ms_warning("sal_subscribe(): no dialog and no refresher ?");
	return -1;
}
Пример #14
0
void sal_op_set_replaces(SalOp* op,belle_sip_header_replaces_t* replaces) {
	if (op->replaces){
		belle_sip_object_unref(op->replaces);
	}
	op->replaces=replaces;
	belle_sip_object_ref(op->replaces);
}
Пример #15
0
Sal * sal_init(){
	belle_sip_listener_callbacks_t listener_callbacks;
	Sal * sal=ms_new0(Sal,1);
	sal->nat_helper_enabled=TRUE;
	sal->user_agent=belle_sip_header_user_agent_new();
#if defined(PACKAGE_NAME) && defined(LINPHONE_VERSION)
	belle_sip_header_user_agent_add_product(sal->user_agent, PACKAGE_NAME "/" LINPHONE_VERSION);
#endif
	sal_append_stack_string_to_user_agent(sal);
	belle_sip_object_ref(sal->user_agent);
	belle_sip_set_log_handler(_belle_sip_log);
	sal->stack = belle_sip_stack_new(NULL);
	sal->prov = belle_sip_stack_create_provider(sal->stack,NULL);
	memset(&listener_callbacks,0,sizeof(listener_callbacks));
	listener_callbacks.process_dialog_terminated=process_dialog_terminated;
	listener_callbacks.process_io_error=process_io_error;
	listener_callbacks.process_request_event=process_request_event;
	listener_callbacks.process_response_event=process_response_event;
	listener_callbacks.process_timeout=process_timeout;
	listener_callbacks.process_transaction_terminated=process_transaction_terminated;
	listener_callbacks.process_auth_requested=process_auth_requested;
	sal->listener=belle_sip_listener_create_from_callbacks(&listener_callbacks,sal);
	belle_sip_provider_add_sip_listener(sal->prov,sal->listener);
	sal->tls_verify=TRUE;
	sal->tls_verify_cn=TRUE;
	sal->refresher_retry_after=60000; /*default value in ms*/
	return sal;
}
Пример #16
0
void belle_sip_multipart_body_handler_add_part(belle_sip_multipart_body_handler_t *obj, belle_sip_body_handler_t *part){
	obj->base.expected_size+=part->expected_size+strlen(obj->boundary) + 4; /* add the separator length to the body length as each part start with a separator. 4 is for "--" and "\r\n" */
	if (part->headers != NULL) { /* there is a declared header for this part, add its length to the expected total length */
		size_t headerStringBufferSize = DEFAULT_HEADER_STRING_SIZE;
		size_t offset = 0;
		belle_sip_list_t *headerList = part->headers;
		part->headerStringBuffer = (char *)belle_sip_malloc(DEFAULT_HEADER_STRING_SIZE);

		while (headerList != NULL) {
			size_t offsetBackup=offset; /* we must backup the offset as it will be messed up by the marshal function in case of failure */
			belle_sip_error_code returnCode = belle_sip_object_marshal(headerList->data, part->headerStringBuffer, headerStringBufferSize-5, &offset); /* -5 to leave room for carriage returns */
			if (returnCode == BELLE_SIP_BUFFER_OVERFLOW) { /* increase buffer size */
				offset=offsetBackup; /* restore the offset, no data were written to the buffer */
				headerStringBufferSize+=DEFAULT_HEADER_STRING_SIZE;
				part->headerStringBuffer = (char *)belle_sip_realloc(part->headerStringBuffer, headerStringBufferSize);
			} else if (returnCode == BELLE_SIP_OK) { /* add the carriage return chars */
				part->headerStringBuffer[offset++]='\r';
				part->headerStringBuffer[offset++]='\n';
				headerList = belle_sip_list_next(headerList);
			}
		}
		part->headerStringBuffer[offset++]='\r';
		part->headerStringBuffer[offset++]='\n';
		obj->base.expected_size += offset;
		part->headerStringBuffer[offset++]='\0'; /* null terminate the buffer in order to be able to get it length later using strlen */
	}
	obj->parts=belle_sip_list_append(obj->parts,belle_sip_object_ref(part));
}
Пример #17
0
static belle_sip_request_t* send_message(belle_sip_request_t *initial_request, const char* realm){
	int i;
	int io_error_count=0;
	belle_sip_request_t *message_request=NULL;
	belle_sip_request_t *clone_request=NULL;
	// belle_sip_header_authorization_t * h=NULL;

	is_register_ok = 0;

	message_request=belle_sip_request_create(
								belle_sip_uri_parse("sip:sip.linphone.org;transport=tcp")
								,"MESSAGE"
								,belle_sip_provider_create_call_id(prov)
								,belle_sip_header_cseq_create(22,"MESSAGE")
								,belle_sip_message_get_header_by_type(BELLE_SIP_MESSAGE(initial_request), belle_sip_header_from_t)
								,belle_sip_header_to_parse("To: sip:[email protected]")
								,belle_sip_header_via_new()
								,70);
	belle_sip_message_add_header(BELLE_SIP_MESSAGE(message_request),BELLE_SIP_HEADER(belle_sip_header_expires_create(600)));
	belle_sip_message_add_header(BELLE_SIP_MESSAGE(message_request),BELLE_SIP_HEADER(belle_sip_header_contact_new()));
	belle_sip_provider_add_authorization(prov,message_request,NULL,NULL,NULL,realm);
	// h = belle_sip_message_get_header_by_type(BELLE_SIP_MESSAGE(message_request), belle_sip_header_authorization_t);
	/*if a matching authorization was found, use it as a proxy authorization*/
	// if (h != NULL){
	// 	belle_sip_header_set_name(BELLE_SIP_HEADER(h), BELLE_SIP_PROXY_AUTHORIZATION);
	// }
	clone_request = (belle_sip_request_t*)belle_sip_object_ref(belle_sip_object_clone((belle_sip_object_t*)message_request));
	belle_sip_client_transaction_send_request_to(belle_sip_provider_create_client_transaction(prov,message_request),NULL);
	for(i=0; i<2 && io_error_count==0 &&is_register_ok==0;i++)
		belle_sip_stack_sleep(stack,5000);

	return clone_request;
}
Пример #18
0
/*presence Subscribe/notify*/
int sal_subscribe_presence(SalOp *op, const char *from, const char *to, int expires){
	belle_sip_request_t *req=NULL;
	if (from)
		sal_op_set_from(op,from);
	if (to)
		sal_op_set_to(op,to);

	sal_op_presence_fill_cbs(op);

	if (expires==-1){
		if (op->refresher){
			expires=belle_sip_refresher_get_expires(op->refresher);
			belle_sip_object_unref(op->refresher);
			op->refresher=NULL;
		}else{
			ms_error("sal_subscribe_presence(): cannot guess expires from previous refresher.");
			return -1;
		}
	}
	if (!op->event){
		op->event=belle_sip_header_create("Event","presence");
		belle_sip_object_ref(op->event);
	}
	belle_sip_parameters_remove_parameter(BELLE_SIP_PARAMETERS(op->base.from_address),"tag");
	belle_sip_parameters_remove_parameter(BELLE_SIP_PARAMETERS(op->base.to_address),"tag");
	req=sal_op_build_request(op,"SUBSCRIBE");
	belle_sip_message_add_header(BELLE_SIP_MESSAGE(req),op->event);
	belle_sip_message_add_header(BELLE_SIP_MESSAGE(req),BELLE_SIP_HEADER(belle_sip_header_expires_create(expires)));

	return sal_op_send_request(op,req);
}
Пример #19
0
belle_sip_request_t* try_register_user_at_domain(belle_sip_stack_t * stack
	,belle_sip_provider_t *prov
	,const char *transport
	,int use_transaction
	,const char* username
	,const char* domain
	,const char* outbound_proxy
	,int success_expected) {
	belle_sip_request_t *req,*copy;
	char identity[256];
	char uri[256];
	int i;
	char *outbound=NULL;

	number_of_challenge=0;
	if (transport)
		snprintf(uri,sizeof(uri),"sip:%s;transport=%s",domain,transport);
	else snprintf(uri,sizeof(uri),"sip:%s",domain);

	if (transport && strcasecmp("tls",transport)==0 && belle_sip_provider_get_listening_point(prov,"tls")==NULL){
		belle_sip_error("No TLS support, test skipped.");
		return NULL;
	}

	if (outbound_proxy){
		if (strstr(outbound_proxy,"sip:")==NULL && strstr(outbound_proxy,"sips:")==NULL){
			outbound=belle_sip_strdup_printf("sip:%s",outbound_proxy);
		}else outbound=belle_sip_strdup(outbound_proxy);
	}

	snprintf(identity,sizeof(identity),"Tester <sip:%s@%s>",username,domain);
	req=belle_sip_request_create(
						belle_sip_uri_parse(uri),
						"REGISTER",
						belle_sip_provider_create_call_id(prov),
						belle_sip_header_cseq_create(20,"REGISTER"),
						belle_sip_header_from_create2(identity,BELLE_SIP_RANDOM_TAG),
						belle_sip_header_to_create2(identity,NULL),
						belle_sip_header_via_new(),
						70);
	is_register_ok=0;
	io_error_count=0;
	using_transaction=0;
	belle_sip_message_add_header(BELLE_SIP_MESSAGE(req),BELLE_SIP_HEADER(belle_sip_header_expires_create(600)));
	belle_sip_message_add_header(BELLE_SIP_MESSAGE(req),BELLE_SIP_HEADER(belle_sip_header_contact_new()));
	copy=(belle_sip_request_t*)belle_sip_object_ref(belle_sip_object_clone((belle_sip_object_t*)req));
	belle_sip_provider_add_sip_listener(prov,l=BELLE_SIP_LISTENER(listener));
	if (use_transaction){
		belle_sip_client_transaction_t *t=belle_sip_provider_create_client_transaction(prov,req);
		belle_sip_client_transaction_send_request_to(t,outbound?belle_sip_uri_parse(outbound):NULL);
	}else belle_sip_provider_send_request(prov,req);
	for(i=0;!is_register_ok && i<2 && io_error_count==0;i++)
		belle_sip_stack_sleep(stack,5000);
	CU_ASSERT_EQUAL(is_register_ok,success_expected);
	if (success_expected) CU_ASSERT_EQUAL(using_transaction,use_transaction);

	belle_sip_provider_remove_sip_listener(prov,l);
	if (outbound) belle_sip_free(outbound);
	return copy;
}
Пример #20
0
/*
 * Warning: this function takes owneship of the custom headers
 */
void sal_op_set_sent_custom_header(SalOp *op, SalCustomHeader* ch){
	SalOpBase *b=(SalOpBase *)op;
	if (b->sent_custom_headers){
		sal_custom_header_free(b->sent_custom_headers);
		b->sent_custom_headers=NULL;
	}
	if (ch) belle_sip_object_ref((belle_sip_message_t*)ch);
	b->sent_custom_headers=ch;
}
Пример #21
0
static void queue_message(belle_sip_channel_t *obj, belle_sip_message_t *msg){
	belle_sip_object_ref(msg);
	channel_push_outgoing(obj,msg);
	if (obj->state==BELLE_SIP_CHANNEL_INIT){
		belle_sip_channel_prepare(obj);
	}else if (obj->state==BELLE_SIP_CHANNEL_READY) {
		channel_process_queue(obj);
	}
}
Пример #22
0
void sal_op_set_event(SalOp *op, const char *eventname){
	belle_sip_header_event_t *header = NULL;
	if (op->event) belle_sip_object_unref(op->event);
	if (eventname){
		header = belle_sip_header_event_create(eventname);
		belle_sip_object_ref(header);
	}
	op->event = header;
}
Пример #23
0
void sal_op_assign_recv_headers(SalOp *op, belle_sip_message_t *incoming){
	if (incoming) belle_sip_object_ref(incoming);
	if (op->base.recv_custom_headers){
		belle_sip_object_unref(op->base.recv_custom_headers);
		op->base.recv_custom_headers=NULL;
	}
	if (incoming){
		op->base.recv_custom_headers=(SalCustomHeader*)incoming;
	}
}
Пример #24
0
static void presence_process_request_event(void *op_base, const belle_sip_request_event_t *event) {
	SalOp* op = (SalOp*)op_base;
	belle_sip_server_transaction_t* server_transaction = belle_sip_provider_create_server_transaction(op->base.root->prov,belle_sip_request_event_get_request(event));
	belle_sip_request_t* req = belle_sip_request_event_get_request(event);
	belle_sip_dialog_state_t dialog_state;
	belle_sip_header_expires_t* expires = belle_sip_message_get_header_by_type(req,belle_sip_header_expires_t);
	belle_sip_response_t* resp;
	const char *method=belle_sip_request_get_method(req);
	
	belle_sip_object_ref(server_transaction);
	if (op->pending_server_trans)  belle_sip_object_unref(op->pending_server_trans);
	op->pending_server_trans=server_transaction;


	if (!op->dialog) {
		if (strcmp(method,"SUBSCRIBE")==0){
			op->dialog=belle_sip_provider_create_dialog(op->base.root->prov,BELLE_SIP_TRANSACTION(server_transaction));
			belle_sip_dialog_set_application_data(op->dialog,op);
			sal_op_ref(op);
			ms_message("new incoming subscription from [%s] to [%s]",sal_op_get_from(op),sal_op_get_to(op));
		}else{ /* this is a NOTIFY */
			ms_message("Receiving out of dialog notify");
			handle_notify(op,req);
			return;
		}
	}
	dialog_state=belle_sip_dialog_get_state(op->dialog);
	switch(dialog_state) {
		case BELLE_SIP_DIALOG_NULL: {
			op->base.root->callbacks.subscribe_presence_received(op,sal_op_get_from(op));
			break;
		}
		case BELLE_SIP_DIALOG_EARLY:
			ms_error("unexpected method [%s] for dialog [%p] in state BELLE_SIP_DIALOG_EARLY ",method,op->dialog);
			break;

		case BELLE_SIP_DIALOG_CONFIRMED:
			if (strcmp("NOTIFY",method)==0) {
				handle_notify(op,req);
			} else if (strcmp("SUBSCRIBE",method)==0) {
				/*either a refresh or an unsubscribe*/
				if (expires && belle_sip_header_expires_get_expires(expires)>0) {
					op->base.root->callbacks.subscribe_presence_received(op,sal_op_get_from(op));
				} else if(expires) {
					ms_message("Unsubscribe received from [%s]",sal_op_get_from(op));
					resp=sal_op_create_response_from_request(op,req,200);
					belle_sip_server_transaction_send_response(server_transaction,resp);
				}
			}
			break;
		default: 
			ms_error("unexpected dialog state [%s]",belle_sip_dialog_state_to_string(dialog_state));
			break;
	}
}
Пример #25
0
void belle_sip_channel_resolve(belle_sip_channel_t *obj){
	channel_set_state(obj,BELLE_SIP_CHANNEL_RES_IN_PROGRESS);
	if (belle_sip_stack_dns_srv_enabled(obj->stack) && obj->lp!=NULL)
		obj->resolver_ctx=belle_sip_stack_resolve(obj->stack, belle_sip_channel_get_transport_name_lower_case(obj), obj->peer_name, obj->peer_port, obj->ai_family, channel_res_done, obj);
	else
		obj->resolver_ctx=belle_sip_stack_resolve_a(obj->stack, obj->peer_name, obj->peer_port, obj->ai_family, channel_res_done, obj);
	if (obj->resolver_ctx){
		belle_sip_object_ref(obj->resolver_ctx);
	}
	return ;
}
Пример #26
0
void belle_sip_server_transaction_send_response(belle_sip_server_transaction_t *t, belle_sip_response_t *resp){
	belle_sip_transaction_t *base=(belle_sip_transaction_t*)t;
	belle_sip_header_to_t *to=(belle_sip_header_to_t*)belle_sip_message_get_header((belle_sip_message_t*)resp,"to");
	belle_sip_dialog_t *dialog=base->dialog;
	int status_code;

	belle_sip_object_ref(resp);
	if (!base->last_response){
		belle_sip_hop_t* hop=belle_sip_response_get_return_hop(resp);
		base->channel=belle_sip_provider_get_channel(base->provider,hop);
		belle_sip_object_unref(hop);
		if (!base->channel){
			belle_sip_error("Transaction [%p]: No channel available for sending response.",t);
			return;
		}
		belle_sip_object_ref(base->channel);
		belle_sip_channel_add_listener(base->channel, BELLE_SIP_CHANNEL_LISTENER(t));
	}
	status_code=belle_sip_response_get_status_code(resp);
	if (status_code!=100){
		if (belle_sip_header_to_get_tag(to)==NULL){
			//add a random to tag
			belle_sip_header_to_set_tag(to,t->to_tag);
		}
		/*12.1 Creation of a Dialog
		   Dialogs are created through the generation of non-failure responses
		   to requests with specific methods.  Within this specification, only
		   2xx and 101-199 responses with a To tag, where the request was
		   INVITE, will establish a dialog.*/
		if (dialog && status_code>100 && status_code<300){
			belle_sip_response_fill_for_dialog(resp,base->request);
		}
	}
	if (BELLE_SIP_OBJECT_VPTR(t,belle_sip_server_transaction_t)->send_new_response(t,resp)==0){
		if (base->last_response)
			belle_sip_object_unref(base->last_response);
		base->last_response=resp;
	}
	if (dialog)
		belle_sip_dialog_update(dialog,BELLE_SIP_TRANSACTION(t),TRUE);
}
static void testRFC2543_base(char* branch) {
	belle_sip_server_transaction_t *tr;
	const char* raw_message_base = 	"INVITE sip:[email protected] SIP/2.0\r\n"
			"Via: SIP/2.0/UDP 192.168.1.12:15060;%srport=15060;received=81.56.113.2\r\n"
			"Record-Route: <sip:37.59.129.73;lr;transport=tcp>\r\n"
			"Record-Route: <sip:37.59.129.73;lr>\r\n"
			"Max-Forwards: 70\r\n"
			"From: <sip:[email protected]>;tag=711138653\r\n"
			"To: <sip:[email protected]>\r\n"
			"Call-ID: 977107319\r\n"
			"CSeq: 21 INVITE\r\n"
			"Contact: <sip:[email protected]:5062>\r\n"
			"Subject: Phone call\r\n"
			"User-Agent: Linphone/3.5.2 (eXosip2/3.6.0)\r\n"
			"Allow: INVITE, ACK, CANCEL, OPTIONS, BYE, REFER, NOTIFY, MESSAGE, SUBSCRIBE, INFO\r\n"
			"Content-Length: 0\r\n"
			"Extended: \r\n" /*fixme lexer*/
			"\r\n";

	char raw_message[2048];
	belle_sip_request_t* request;
	belle_sip_stack_t *stack=belle_sip_stack_new(NULL);
	belle_sip_provider_t *prov=belle_sip_provider_new(stack,NULL);
	belle_sip_message_t* message;

	snprintf(raw_message,sizeof(raw_message),raw_message_base,branch);

	message = belle_sip_message_parse(raw_message);
	belle_sip_object_ref(message);
	belle_sip_object_ref(message); /*yes double ref: originally the message is created with 0 refcount, and dispatch_message will unref() it.*/
	belle_sip_provider_dispatch_message(prov,message);
	request = BELLE_SIP_REQUEST(message);

	CU_ASSERT_PTR_NOT_NULL(request);
	tr=belle_sip_provider_create_server_transaction(prov,request);
	CU_ASSERT_PTR_NOT_NULL(belle_sip_provider_find_matching_server_transaction(prov,request)); /*make sure branch id is properly set*/
	CU_ASSERT_PTR_NOT_NULL(tr);
	belle_sip_object_unref(prov);
	belle_sip_object_unref(stack);
	belle_sip_object_unref(message);
}
Пример #28
0
void belle_sip_dialog_send_ack(belle_sip_dialog_t *obj, belle_sip_request_t *request){
	if (obj->needs_ack){
		obj->needs_ack=FALSE;
		if (obj->last_out_ack)
			belle_sip_object_unref(obj->last_out_ack);
		obj->last_out_ack=(belle_sip_request_t*)belle_sip_object_ref(request);
		belle_sip_provider_send_request(obj->provider,request);
		belle_sip_dialog_process_queue(obj);
	}else{
		belle_sip_error("Why do you want to send an ACK ?");
	}
}
Пример #29
0
static LinphoneContent * linphone_content_new_with_body_handler(SalBodyHandler *body_handler) {
	LinphoneContent *content = belle_sip_object_new(LinphoneContent);
	belle_sip_object_ref(content);
	content->owned_fields = TRUE;
	content->cryptoContext = NULL; /* this field is managed externally by encryption/decryption functions so be careful to initialise it to NULL */
	if (body_handler == NULL) {
		linphone_content_set_sal_body_handler(content, sal_body_handler_new());
	} else {
		linphone_content_set_sal_body_handler(content, body_handler);
	}
	return content;
}
Пример #30
0
static void belle_sip_uri_clone(belle_sip_uri_t* uri, const belle_sip_uri_t *orig){
	uri->secure=orig->secure;
	uri->user=orig->user?belle_sip_strdup(orig->user):NULL;
	uri->user_password=orig->user_password?belle_sip_strdup(orig->user_password):NULL;
	uri->host=orig->host?belle_sip_strdup(orig->host):NULL;
	uri->port=orig->port;
	if (orig->header_list){
		uri->header_list=(belle_sip_parameters_t*)belle_sip_object_clone(BELLE_SIP_OBJECT(orig->header_list));
		belle_sip_object_ref(uri->header_list);
	}

}