static LinphoneXmlRpcRequest * _create_account_with_email(LinphoneAccountCreator *creator) {
	LinphoneXmlRpcRequest *request;
	if (!creator->username || !creator->email) {
		return NULL;
	}
	request = linphone_xml_rpc_request_new_with_args("create_email_account", LinphoneXmlRpcArgString,
		LinphoneXmlRpcArgString, creator->username,
		LinphoneXmlRpcArgString, creator->email,
		LinphoneXmlRpcArgString, ha1_for_passwd(creator->username ? creator->username : creator->phone_number, creator->password, creator->domain),
		LinphoneXmlRpcArgString, linphone_core_get_user_agent(creator->core),
		LinphoneXmlRpcArgNone);
	return request;
}
void linphone_reporting_update_media_info(LinphoneCall * call, int stats_type) {
	MediaStream * stream = NULL;
	const PayloadType * local_payload = NULL;
	const PayloadType * remote_payload = NULL;
	const LinphoneCallParams * current_params = linphone_call_get_current_params(call);
	reporting_session_report_t * report = call->log->reporting.reports[stats_type];
	char * dialog_id;

	// call->op might be already released if hanging up in state LinphoneCallOutgoingInit
	if (!media_report_enabled(call, stats_type) || call->op == NULL)
		return;

	dialog_id = sal_op_get_dialog_id(call->op);

	STR_REASSIGN(report->info.call_id, ms_strdup(call->log->call_id));

	STR_REASSIGN(report->local_metrics.user_agent, ms_strdup(linphone_core_get_user_agent(call->core)));
	STR_REASSIGN(report->remote_metrics.user_agent, ms_strdup(linphone_call_get_remote_user_agent(call)));

	// RFC states: "LocalGroupID provides the identification for the purposes
	// of aggregation for the local endpoint.".
	STR_REASSIGN(report->info.local_addr.group, ms_strdup_printf("%s-%s-%s"
		, dialog_id ? dialog_id : ""
		, "local"
		, report->local_metrics.user_agent ? report->local_metrics.user_agent : ""
		)
	);
	STR_REASSIGN(report->info.remote_addr.group, ms_strdup_printf("%s-%s-%s"
		, dialog_id ? dialog_id : ""
		, "remote"
		, report->remote_metrics.user_agent ? report->remote_metrics.user_agent : ""
		)
	);


	if (call->dir == LinphoneCallIncoming) {
		STR_REASSIGN(report->info.remote_addr.id, linphone_address_as_string(call->log->from));
		STR_REASSIGN(report->info.local_addr.id, linphone_address_as_string(call->log->to));
		STR_REASSIGN(report->info.orig_id, ms_strdup(report->info.remote_addr.id));
	} else {
		STR_REASSIGN(report->info.remote_addr.id, linphone_address_as_string(call->log->to));
		STR_REASSIGN(report->info.local_addr.id, linphone_address_as_string(call->log->from));
		STR_REASSIGN(report->info.orig_id, ms_strdup(report->info.local_addr.id));
	}


	report->local_metrics.timestamps.start = call->log->start_date_time;
	report->local_metrics.timestamps.stop = call->log->start_date_time + linphone_call_get_duration(call);

	/*we use same timestamps for remote too*/
	report->remote_metrics.timestamps.start = call->log->start_date_time;
	report->remote_metrics.timestamps.stop = call->log->start_date_time + linphone_call_get_duration(call);


	/*yet we use the same payload config for local and remote, since this is the largest use case*/
	if (stats_type == LINPHONE_CALL_STATS_AUDIO && call->audiostream != NULL) {
		stream = &call->audiostream->ms;
		local_payload = linphone_call_params_get_used_audio_codec(current_params);
		remote_payload = local_payload;
	} else if (stats_type == LINPHONE_CALL_STATS_VIDEO && call->videostream != NULL) {
		stream = &call->videostream->ms;
		local_payload = linphone_call_params_get_used_video_codec(current_params);
		remote_payload = local_payload;
	} else if (stats_type == LINPHONE_CALL_STATS_TEXT && call->textstream != NULL) {
		stream = &call->textstream->ms;
		local_payload = linphone_call_params_get_used_text_codec(current_params);
		remote_payload = local_payload;
	}

	if (stream != NULL) {
		RtpSession * session = stream->sessions.rtp_session;

		report->info.local_addr.ssrc = rtp_session_get_send_ssrc(session);
		report->info.remote_addr.ssrc = rtp_session_get_recv_ssrc(session);

		if (stream->qi != NULL){
			report->local_metrics.quality_estimates.moslq = ms_quality_indicator_get_average_lq_rating(stream->qi) >= 0 ?
				MAX(1, ms_quality_indicator_get_average_lq_rating(stream->qi)) : -1;
			report->local_metrics.quality_estimates.moscq = ms_quality_indicator_get_average_rating(stream->qi) >= 0 ?
				MAX(1, ms_quality_indicator_get_average_rating(stream->qi)) : -1;
		}
	}

	STR_REASSIGN(report->dialog_id, ms_strdup_printf("%s;%u", dialog_id ? dialog_id : "", report->info.local_addr.ssrc));

	if (local_payload != NULL) {
		report->local_metrics.session_description.payload_type = local_payload->type;
		if (local_payload->mime_type!=NULL) STR_REASSIGN(report->local_metrics.session_description.payload_desc, ms_strdup(local_payload->mime_type));
		report->local_metrics.session_description.sample_rate = local_payload->clock_rate;
		if (local_payload->recv_fmtp!=NULL) STR_REASSIGN(report->local_metrics.session_description.fmtp, ms_strdup(local_payload->recv_fmtp));
	}

	if (remote_payload != NULL) {
		report->remote_metrics.session_description.payload_type = remote_payload->type;
		STR_REASSIGN(report->remote_metrics.session_description.payload_desc, ms_strdup(remote_payload->mime_type));
		report->remote_metrics.session_description.sample_rate = remote_payload->clock_rate;
		STR_REASSIGN(report->remote_metrics.session_description.fmtp, ms_strdup(remote_payload->recv_fmtp));
	}

	ms_free(dialog_id);
}