Exemple #1
0
static void register_refresher_listener (belle_sip_refresher_t* refresher
		,void* user_pointer
		,unsigned int status_code
		,const char* reason_phrase) {
	SalOp* op = (SalOp*)user_pointer;
	belle_sip_response_t* response=belle_sip_transaction_get_response(BELLE_SIP_TRANSACTION(belle_sip_refresher_get_transaction(refresher)));
	ms_message("Register refresher [%i] reason [%s] for proxy [%s]",status_code,reason_phrase,sal_op_get_proxy(op));

	if (belle_sip_refresher_get_auth_events(refresher)) {
		if (op->auth_info) sal_auth_info_delete(op->auth_info);
		/*only take first one for now*/
		op->auth_info=sal_auth_info_create((belle_sip_auth_event_t*)(belle_sip_refresher_get_auth_events(refresher)->data));
	}
	sal_error_info_set(&op->error_info,SalReasonUnknown,status_code,reason_phrase,NULL);
	if (status_code>=200){
		sal_op_assign_recv_headers(op,(belle_sip_message_t*)response);
	}
	if(status_code == 200) {
		/*check service route rfc3608*/
		belle_sip_header_service_route_t* service_route;
		belle_sip_header_address_t* service_route_address=NULL;
		belle_sip_header_contact_t *contact = belle_sip_refresher_get_contact(refresher);
		if ((service_route=belle_sip_message_get_header_by_type(response,belle_sip_header_service_route_t))) {
			service_route_address=belle_sip_header_address_create(NULL,belle_sip_header_address_get_uri(BELLE_SIP_HEADER_ADDRESS(service_route)));
		}
		sal_op_set_service_route(op,(const SalAddress*)service_route_address);
		if (service_route_address) belle_sip_object_unref(service_route_address);

		sal_remove_pending_auth(op->base.root,op); /*just in case*/
		if (contact) {
			sal_op_set_contact_address(op,(SalAddress*)(BELLE_SIP_HEADER_ADDRESS(contact))); /*update contact with real value*/
		}
		op->base.root->callbacks.register_success(op,belle_sip_refresher_get_expires(op->refresher)>0);
	} else if (status_code>=400) {
		/* from rfc3608, 6.1.
				If the UA refreshes the registration, the stored value of the Service-
				   Route is updated according to the Service-Route header field of the
				   latest 200 class response.  If there is no Service-Route header field
				   in the response, the UA clears any service route for that address-
				   of-record previously stored by the UA.  If the re-registration
				   request is refused or if an existing registration expires and the UA
				   chooses not to re-register, the UA SHOULD discard any stored service
				   route for that address-of-record. */
		sal_op_set_service_route(op,NULL);
		sal_op_ref(op); /*take a ref while invoking the callback to make sure the operations done after are valid*/
		op->base.root->callbacks.register_failure(op);
		if (op->state!=SalOpStateTerminated && op->auth_info) {
			/*add pending auth*/
			sal_add_pending_auth(op->base.root,op);
			if (status_code==403 || status_code==401 || status_code==407 )
				op->base.root->callbacks.auth_failure(op,op->auth_info);
		}
		sal_op_unref(op);
	}
}
Exemple #2
0
void sal_op_set_error_info_from_response(SalOp *op, belle_sip_response_t *response){
	int code = belle_sip_response_get_status_code(response);
	const char *reason_phrase=belle_sip_response_get_reason_phrase(response);
	/*Remark: the reason header is to be used mainly in SIP requests, thus the use and prototype of this function should be changed.*/
	belle_sip_header_t* reason_header = belle_sip_message_get_header(BELLE_SIP_MESSAGE(response),"Reason");
	belle_sip_header_t *warning=belle_sip_message_get_header(BELLE_SIP_MESSAGE(response),"Warning");
	SalErrorInfo *ei=&op->error_info;
	const char *warnings;

	warnings=warning ? belle_sip_header_get_unparsed_value(warning) : NULL;
	if (warnings==NULL) warnings=reason_header ? belle_sip_header_get_unparsed_value(reason_header) : NULL;
	sal_error_info_set(ei,SalReasonUnknown,code,reason_phrase,warnings);
}
Exemple #3
0
static void call_process_timeout(void *user_ctx, const belle_sip_timeout_event_t *event) {
	SalOp* op=(SalOp*)user_ctx;

	if (op->state==SalOpStateTerminated) return;

	if (!op->dialog)  {
		/*call terminated very early*/
		sal_error_info_set(&op->error_info,SalReasonRequestTimeout,408,"Request timeout",NULL);
		op->base.root->callbacks.call_failure(op);
		call_set_released(op);
	} else {
		/*dialog will terminated shortly, nothing to do*/
	}
}
Exemple #4
0
static void subscribe_refresher_listener (belle_sip_refresher_t* refresher
		,void* user_pointer
		,unsigned int status_code
		,const char* reason_phrase) {
	SalOp* op = (SalOp*)user_pointer;
	belle_sip_transaction_t *tr=BELLE_SIP_TRANSACTION(belle_sip_refresher_get_transaction(refresher));
	/*belle_sip_response_t* response=belle_sip_transaction_get_response(tr);*/
	SalSubscribeStatus sss=SalSubscribeTerminated;
	
	ms_message("Subscribe refresher  [%i] reason [%s] ",status_code,reason_phrase?reason_phrase:"none");
	if (status_code>=200 && status_code<300){
		if (status_code==200) sss=SalSubscribeActive;
		else if (status_code==202) sss=SalSubscribePending;
		set_or_update_dialog(op,belle_sip_transaction_get_dialog(tr));
	}
	if (status_code>=200){
		sal_error_info_set(&op->error_info,SalReasonUnknown,status_code,reason_phrase,NULL);
		op->base.root->callbacks.subscribe_response(op,sss);
	}else if (status_code==0){
		op->base.root->callbacks.on_expire(op);
	}
	
}
static void process_timeout(void *user_ctx, const belle_sip_timeout_event_t *event) {
	SalOp* op=(SalOp*)user_ctx;
	sal_error_info_set(&op->error_info,SalReasonRequestTimeout,408,"Request timeout",NULL);
	process_error(op);

}
static void process_io_error(void *user_ctx, const belle_sip_io_error_event_t *event){
	SalOp* op = (SalOp*)user_ctx;
	sal_error_info_set(&op->error_info,SalReasonIOError,503,"IO Error",NULL);
	process_error(op);
}
int sal_message_send(SalOp *op, const char *from, const char *to, const char* content_type, const char *msg, const char *peer_uri){
	belle_sip_request_t* req;
	char content_type_raw[256];
	size_t content_length = msg?strlen(msg):0;
	time_t curtime = time(NULL);
	uint8_t *multipartEncryptedMessage = NULL;
	int retval;
	
	if (op->dialog){
		/*for SIP MESSAGE that are sent in call's dialog*/
		req = belle_sip_dialog_create_queued_request(op->dialog,"MESSAGE");
	}else{
		sal_op_message_fill_cbs(op);
		if (from)
			sal_op_set_from(op, from);
		if (to)
			sal_op_set_to(op, to);
		op->dir = SalOpDirOutgoing;

		req = sal_op_build_request(op,"MESSAGE");
		if (req == NULL ){
			return -1;
		}
		if (sal_op_get_contact_address(op)){
			belle_sip_message_add_header(BELLE_SIP_MESSAGE(req), BELLE_SIP_HEADER(sal_op_create_contact(op)));
		}
	}

	/* shall we try to encrypt the message?*/
	if ((strcmp(content_type, "xml/cipher") == 0) || ((strcmp(content_type, "application/cipher.vnd.gsma.rcs-ft-http+xml") == 0))) {
		/* access the zrtp cache to get keys needed to cipher the message */
		LinphoneCore *lc=(LinphoneCore *)sal_get_user_pointer(sal_op_get_sal(op));
		FILE *CACHEFD = fopen(lc->zrtp_secrets_cache, "rb+");
		if (CACHEFD == NULL) {
			ms_warning("Unable to access ZRTP ZID cache to encrypt message");
			/*probably not a good idea to do this:*/
			sal_error_info_set(&op->error_info, SalReasonNotAcceptable, 488, "Unable to encrypt IM", NULL);
			op->base.root->callbacks.text_delivery_update(op,SalTextDeliveryFailed);
			return -1;
		} else {
			size_t cacheSize;
			char *cacheString;
			xmlDocPtr cacheXml;
			int retval;

			cacheString=ms_load_file_content(CACHEFD, &cacheSize);
			if (!cacheString){
				ms_warning("Unable to load content of ZRTP ZID cache to encrypt message");
				return -1;
			}
			cacheString[cacheSize] = '\0';
			cacheSize += 1;
			fclose(CACHEFD);
			cacheXml = xmlParseDoc((xmlChar*)cacheString);
			ms_free(cacheString);
			retval = lime_createMultipartMessage(cacheXml, (uint8_t *)msg, (uint8_t *)peer_uri, &multipartEncryptedMessage);
			if (retval != 0) {
				ms_warning("Unable to encrypt message for %s : %s - op [%p]", peer_uri, lime_error_code_to_string(retval), op);
				xmlFreeDoc(cacheXml);
				free(multipartEncryptedMessage);
				/*probably not a good idea to do this:*/
				sal_error_info_set(&op->error_info, SalReasonNotAcceptable, 488, "Unable to encrypt IM", NULL);
				op->base.root->callbacks.text_delivery_update(op,SalTextDeliveryFailed);
				return -1;
			} else {
				/* dump updated cache to a string */
				xmlChar *xmlStringOutput;
				int xmlStringLength;
				xmlDocDumpFormatMemoryEnc(cacheXml, &xmlStringOutput, &xmlStringLength, "UTF-8", 0);
				/* write it to the cache file */
				CACHEFD = fopen(lc->zrtp_secrets_cache, "wb+");
				if (fwrite(xmlStringOutput, 1, xmlStringLength, CACHEFD)<=0){
					ms_warning("Unable to write zid cache");
				}
				xmlFree(xmlStringOutput);
				fclose(CACHEFD);
				content_length = strlen((const char *)multipartEncryptedMessage);
			}
			xmlFreeDoc(cacheXml);
		}
	}

	snprintf(content_type_raw,sizeof(content_type_raw),BELLE_SIP_CONTENT_TYPE ": %s",content_type);
	belle_sip_message_add_header(BELLE_SIP_MESSAGE(req),BELLE_SIP_HEADER(belle_sip_header_content_type_parse(content_type_raw)));
	belle_sip_message_add_header(BELLE_SIP_MESSAGE(req),BELLE_SIP_HEADER(belle_sip_header_content_length_create(content_length)));
	belle_sip_message_add_header(BELLE_SIP_MESSAGE(req),BELLE_SIP_HEADER(belle_sip_header_date_create_from_time(&curtime)));
	belle_sip_message_set_body(BELLE_SIP_MESSAGE(req),(multipartEncryptedMessage==NULL)?msg:(const char *)multipartEncryptedMessage,content_length);
	retval = sal_op_send_request(op,req);
	free(multipartEncryptedMessage);

	return retval;
}