/*
 *  Copyright (C) 2002 - 2003 Ardis Technologies <roman@ardistech.com>
 *  Copyright (C) 2007 - 2018 Vladislav Bolkhovitin
 *  Copyright (C) 2007 - 2018 Western Digital Corporation
 *
 *  This program is free software; you can redistribute it and/or
 *  modify it under the terms of the GNU General Public License
 *  as published by the Free Software Foundation, version 2
 *  of the License.
 *
 *  This program is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
 *  GNU General Public License for more details.
 */

#include <ctype.h>
#include <dirent.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <errno.h>
#include <sys/stat.h>

#include "iscsid.h"

#define ISCSI_CONN_NEW		1
#define ISCSI_CONN_EXIT		5

struct connection *conn_alloc(void)
{
	struct connection *conn;
	unsigned int session_params[session_key_last];
	int i;

	conn = malloc(sizeof(*conn));
	if (conn == NULL)
		goto out;

	memset(conn, 0, sizeof(*conn));
	conn->state = STATE_FREE;
	INIT_LIST_HEAD(&conn->rsp_buf_list);

	params_set_defaults(session_params, session_keys);

	for (i = 0; i < session_key_last; i++)
		conn->session_params[i].val = session_params[i];

out:
	return conn;
}

void conn_free(struct connection *conn)
{
	list_del(&conn->clist);
	free(conn->initiator);
	free(conn->target_portal);
	free(conn->user);
	if (conn->auth_method == AUTH_CHAP)
		free(conn->auth.chap.challenge);
	free(conn->initiator_ip_address);
	free(conn);
	return;
}

void conn_pass_to_kern(struct connection *conn, int fd)
{
	int err;

	log_debug(1, "fd %d, cid %u, stat_sn %u, exp_stat_sn %u sid %" PRIx64,
		fd, conn->cid, conn->stat_sn, conn->exp_stat_sn, conn->sid.id64);

	err = kernel_conn_create(conn->tid, conn->sess->sid.id64, conn->cid,
			      conn->stat_sn, conn->exp_stat_sn, fd);

	if (err == 0)
		conn->passed_to_kern = 1;

	/* We don't need to return err, because we are going to close conn anyway */
	return;
}

void conn_read_pdu(struct connection *conn)
{
	conn->iostate = IOSTATE_READ_BHS;
	conn->buffer = (void *)&conn->req.bhs;
	conn->rwsize = BHS_SIZE;
	return;
}

void conn_write_pdu(struct connection *conn)
{
	conn->iostate = IOSTATE_WRITE_BHS;
	memset(&conn->rsp, 0, sizeof(conn->rsp));
	conn->buffer = (void *)&conn->rsp.bhs;
	conn->rwsize = BHS_SIZE;
	return;
}

void conn_free_rsp_buf_list(struct connection *conn)
{
	struct buf_segment *seg, *tmp;

	list_for_each_entry_safe(seg, tmp, &conn->rsp_buf_list, entry) {
		list_del(&seg->entry);
		free(seg);
	}

	conn->rsp.datasize = 0;
	conn->rsp.data = NULL;
	return;
}

void conn_free_pdu(struct connection *conn)
{
	conn->iostate = IOSTATE_FREE;
	if (conn->req.ahs) {
		free(conn->req.ahs);
		conn->req.ahs = NULL;
	}
	if (conn->rsp.ahs) {
		free(conn->rsp.ahs);
		conn->rsp.ahs = NULL;
	}
	conn_free_rsp_buf_list(conn);
	return;
}
