/*********************************************************************
 *
 * Filename:      ircomm_tty_attach.c
 * Version:
 * Description:   Code for attaching the serial driver to IrCOMM
 * Status:        Experimental.
 * Author:        Dag Brattli <dagb@cs.uit.no>
 * Created at:    Sat Jun  5 17:42:00 1999
 * Modified at:   Tue Jan  4 14:20:49 2000
 * Modified by:   Dag Brattli <dagb@cs.uit.no>
 *
 *     Copyright (c) 1999-2000 Dag Brattli, All Rights Reserved.
 *     Copyright (c) 2000-2003 Jean Tourrilhes <jt@hpl.hp.com>
 *
 *     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; either version 2 of
 *     the License, or (at your option) any later version.
 *
 *     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.
 *
 *     You should have received a copy of the GNU General Public License
 *     along with this program; if not, see <http://www.gnu.org/licenses/>.
 *
 ********************************************************************/

#include <linux/init.h>
#include <linux/sched.h>

#include <net/irda/irda.h>
#include <net/irda/irlmp.h>
#include <net/irda/iriap.h>
#include <net/irda/irttp.h>
#include <net/irda/irias_object.h>
#include <net/irda/parameters.h>

#include <net/irda/ircomm_core.h>
#include <net/irda/ircomm_param.h>
#include <net/irda/ircomm_event.h>

#include <net/irda/ircomm_tty.h>
#include <net/irda/ircomm_tty_attach.h>

static void ircomm_tty_ias_register(struct ircomm_tty_cb *self);
static void ircomm_tty_discovery_indication(discinfo_t *discovery,
					    DISCOVERY_MODE mode,
					    void *priv);
static void ircomm_tty_getvalue_confirm(int result, __u16 obj_id,
					struct ias_value *value, void *priv);
static void ircomm_tty_start_watchdog_timer(struct ircomm_tty_cb *self,
					    int timeout);
static void ircomm_tty_watchdog_timer_expired(void *data);

static int ircomm_tty_state_idle(struct ircomm_tty_cb *self,
				 IRCOMM_TTY_EVENT event,
				 struct sk_buff *skb,
				 struct ircomm_tty_info *info);
static int ircomm_tty_state_search(struct ircomm_tty_cb *self,
				   IRCOMM_TTY_EVENT event,
				   struct sk_buff *skb,
				   struct ircomm_tty_info *info);
static int ircomm_tty_state_query_parameters(struct ircomm_tty_cb *self,
					     IRCOMM_TTY_EVENT event,
					     struct sk_buff *skb,
					     struct ircomm_tty_info *info);
static int ircomm_tty_state_query_lsap_sel(struct ircomm_tty_cb *self,
					   IRCOMM_TTY_EVENT event,
					   struct sk_buff *skb,
					   struct ircomm_tty_info *info);
static int ircomm_tty_state_setup(struct ircomm_tty_cb *self,
				  IRCOMM_TTY_EVENT event,
				  struct sk_buff *skb,
				  struct ircomm_tty_info *info);
static int ircomm_tty_state_ready(struct ircomm_tty_cb *self,
				  IRCOMM_TTY_EVENT event,
				  struct sk_buff *skb,
				  struct ircomm_tty_info *info);

const char *const ircomm_tty_state[] = {
	"IRCOMM_TTY_IDLE",
	"IRCOMM_TTY_SEARCH",
	"IRCOMM_TTY_QUERY_PARAMETERS",
	"IRCOMM_TTY_QUERY_LSAP_SEL",
	"IRCOMM_TTY_SETUP",
	"IRCOMM_TTY_READY",
	"*** ERROR *** ",
};

static const char *const ircomm_tty_event[] __maybe_unused = {
	"IRCOMM_TTY_ATTACH_CABLE",
	"IRCOMM_TTY_DETACH_CABLE",
	"IRCOMM_TTY_DATA_REQUEST",
	"IRCOMM_TTY_DATA_INDICATION",
	"IRCOMM_TTY_DISCOVERY_REQUEST",
	"IRCOMM_TTY_DISCOVERY_INDICATION",
	"IRCOMM_TTY_CONNECT_CONFIRM",
	"IRCOMM_TTY_CONNECT_INDICATION",
	"IRCOMM_TTY_DISCONNECT_REQUEST",
	"IRCOMM_TTY_DISCONNECT_INDICATION",
	"IRCOMM_TTY_WD_TIMER_EXPIRED",
	"IRCOMM_TTY_GOT_PARAMETERS",
	"IRCOMM_TTY_GOT_LSAPSEL",
	"*** ERROR ****",
};

static int (*state[])(struct ircomm_tty_cb *self, IRCOMM_TTY_EVENT event,
		      struct sk_buff *skb, struct ircomm_tty_info *info) =
{
	ircomm_tty_state_idle,
	ircomm_tty_state_search,
	ircomm_tty_state_query_parameters,
	ircomm_tty_state_query_lsap_sel,
	ircomm_tty_state_setup,
	ircomm_tty_state_ready,
};

/*
 * Function ircomm_tty_attach_cable (driver)
 *
 *    Try to attach cable (IrCOMM link). This function will only return
 *    when the link has been connected, or if an error condition occurs.
 *    If success, the return value is the resulting service type.
 */
int ircomm_tty_attach_cable(struct ircomm_tty_cb *self)
{
	struct tty_struct *tty;

	IRDA_ASSERT(self != NULL, return -1;);
	IRDA_ASSERT(self->magic == IRCOMM_TTY_MAGIC, return -1;);

	/* Check if somebody has already connected to us */
	if (ircomm_is_connected(self->ircomm)) {
		pr_debug("%s(), already connected!\n", __func__);
		return 0;
	}

	/* Make sure nobody tries to write before the link is up */
	tty = tty_port_tty_get(&self->port);
	if (tty) {
		tty->hw_stopped = 1;
		tty_kref_put(tty);
	}

	ircomm_tty_ias_register(self);

	ircomm_tty_do_event(self, IRCOMM_TTY_ATTACH_CABLE, NULL, NULL);

	return 0;
}

/*
 * Function ircomm_detach_cable (driver)
 *
 *    Detach cable, or cable has been detached by peer
 *
 */
void ircomm_tty_detach_cable(struct ircomm_tty_cb *self)
{
	IRDA_ASSERT(self != NULL, return;);
	IRDA_ASSERT(self->magic == IRCOMM_TTY_MAGIC, return;);

	del_timer(&self->watchdog_timer);

	/* Remove discovery handler */
	if (self->ckey) {
		irlmp_unregister_client(self->ckey);
		self->ckey = NULL;
	}
	/* Remove IrCOMM hint bits */
	if (self->skey) {
		irlmp_unregister_service(self->skey);
		self->skey = NULL;
	}

	if (self->iriap) {
		iriap_close(self->iriap);
		self->iriap = NULL;
	}

	/* Remove LM-IAS object */
	if (self->obj) {
		irias_delete_object(self->obj);
		self->obj = NULL;
	}

	ircomm_tty_do_event(self, IRCOMM_TTY_DETACH_CABLE, NULL, NULL);

	/* Reset some values */
	self->daddr = self->saddr = 0;
	self->dlsap_sel = self->slsap_sel = 0;

	memset(&self->settings, 0, sizeof(struct ircomm_params));
}

/*
 * Function ircomm_tty_ias_register (self)
 *
 *    Register with LM-IAS depending on which service type we are
 *
 */
static void ircomm_tty_ias_register(struct ircomm_tty_cb *self)
{
	__u8 oct_seq[6];
	__u16 hints;

	IRDA_ASSERT(self != NULL, return;);
	IRDA_ASSERT(self->magic == IRCOMM_TTY_MAGIC, return;);

	/* Compute hint bits based on service */
	hints = irlmp_service_to_hint(S_COMM);
	if (self->service_type & IRCOMM_3_WIRE_RAW)
		hints |= irlmp_service_to_hint(S_PRINTER);

	/* Advertise IrCOMM hint bit in discovery */
	if (!self->skey)
		self->skey = irlmp_register_service(hints);
	/* Set up a discovery handler */
	if (!self->ckey)
		self->ckey = irlmp_register_client(hints,
						   ircomm_tty_discovery_indication,
						   NULL, (void *) self);

	/* If already done, no need to do it again */
	if (self->obj)
		return;

	if (self->service_type & IRCOMM_3_WIRE_RAW) {
		/* Register IrLPT with LM-IAS */
		self->obj = irias_new_object("IrLPT", IAS_IRLPT_ID);
		irias_add_integer_attrib(self->obj, "IrDA:IrLMP:LsapSel",
					 self->slsap_sel, IAS_KERNEL_ATTR);
	} else {
		/* Register IrCOMM with LM-IAS */
		self->obj = irias_new_object("IrDA:IrCOMM", IAS_IRCOMM_ID);
		irias_add_integer_attrib(self->obj, "IrDA:TinyTP:LsapSel",
					 self->slsap_sel, IAS_KERNEL_ATTR);

		/* Code the parameters into the buffer */
		irda_param_pack(oct_seq, "bbbbbb",
				IRCOMM_SERVICE_TYPE, 1, self->service_type,
				IRCOMM_PORT_TYPE,    1, IRCOMM_SERIAL);

		/* Register parameters with LM-IAS */
		irias_add_octseq_attrib(self->obj, "Parameters", oct_seq, 6,
					IAS_KERNEL_ATTR);
	}
	irias_insert_object(self->obj);
}

/*
 * Function ircomm_tty_ias_unregister (self)
 *
 *    Remove our IAS object and client hook while connected.
 *
 */
static void ircomm_tty_ias_unregister(struct ircomm_tty_cb *self)
{
	/* Remove LM-IAS object now so it is not reused.
	 * IrCOMM deals very poorly with multiple incoming connections.
	 * It should looks a lot more like IrNET, and "dup" a server TSAP
	 * to the application TSAP (based on various rules).
	 * This is a cheap workaround allowing multiple clients to
	 * connect to us. It will not always work.
	 * Each IrCOMM socket has an IAS entry. Incoming connection will
	 * pick the first one found. So, when we are fully connected,
	 * we remove our IAS entries so that the next IAS entry is used.
	 * We do that for *both* client and server, because a server
	 * can also create client instances.
	 * Jean II */
	if (self->obj) {
		irias_delete_object(self->obj);
		self->obj = NULL;
	}

#if 0
	/* Remove discovery handler.
	 * While we are connected, we no longer need to receive
	 * discovery events. This would be the case if there is
	 * multiple IrLAP interfaces. Jean II */
	if (self->ckey) {
		irlmp_unregister_client(self->ckey);
		self->ckey = NULL;
	}
#endif
}

/*
 * Function ircomm_send_initial_parameters (self)
 *
 *    Send initial parameters to the remote IrCOMM device. These parameters
 *    must be sent before any data.
 */
int ircomm_tty_send_initial_parameters(struct ircomm_tty_cb *self)
{
	IRDA_ASSERT(self != NULL, return -1;);
	IRDA_ASSERT(self->magic == IRCOMM_TTY_MAGIC, return -1;);

	if (self->service_type & IRCOMM_3_WIRE_RAW)
		return 0;

	/*
	 * Set default values, but only if the application for some reason
	 * haven't set them already
	 */
	pr_debug("%s(), data-rate = %d\n", __func__ ,
		 self->settings.data_rate);
	if (!self->settings.data_rate)
		self->settings.data_rate = 9600;
	pr_debug("%s(), data-format = %d\n", __func__ ,
		 self->settings.data_format);
	if (!self->settings.data_format)
		self->settings.data_format = IRCOMM_WSIZE_8;  /* 8N1 */

	pr_debug("%s(), flow-control = %d\n", __func__ ,
		 self->settings.flow_control);
	/*self->settings.flow_control = IRCOMM_RTS_CTS_IN|IRCOMM_RTS_CTS_OUT;*/

	/* Do not set delta values for the initial parameters */
	self->settings.dte = IRCOMM_DTR | IRCOMM_RTS;

	/* Only send service type parameter when we are the client */
	if (self->client)
		ircomm_param_request(self, IRCOMM_SERVICE_TYPE, FALSE);
	ircomm_param_request(self, IRCOMM_DATA_RATE, FALSE);
	ircomm_param_request(self, IRCOMM_DATA_FORMAT, FALSE);

	/* For a 3 wire service, we just flush the last parameter and return */
	if (self->settings.service_type == IRCOMM_3_WIRE) {
		ircomm_param_request(self, IRCOMM_FLOW_CONTROL, TRUE);
		return 0;
	}

	/* Only 9-wire service types continue here */
	ircomm_param_request(self, IRCOMM_FLOW_CONTROL, FALSE);
#if 0
	ircomm_param_request(self, IRCOMM_XON_XOFF, FALSE);
	ircomm_param_request(self, IRCOMM_ENQ_ACK, FALSE);
#endif
	/* Notify peer that we are ready to receive data */
	ircomm_param_request(self, IRCOMM_DTE, TRUE);

	return 0;
}

/*
 * Function ircomm_tty_discovery_indication (discovery)
 *
 *    Remote device is discovered, try query the remote IAS to see which
 *    device it is, and which services it has.
 *
 */
static void ircomm_tty_discovery_indication(discinfo_t *discovery,
					    DISCOVERY_MODE mode,
					    void *priv)
{
	struct ircomm_tty_cb *self;
	struct ircomm_tty_info info;

	/* Important note :
	 * We need to drop all passive discoveries.
	 * The LSAP management of IrComm is deficient and doesn't deal
	 * with the case of two instance connecting to each other
	 * simultaneously (it will deadlock in LMP).
	 * The proper fix would be to use the same technique as in IrNET,
	 * to have one server socket and separate instances for the
	 * connecting/connected socket.
	 * The workaround is to drop passive discovery, which drastically
	 * reduce the probability of this happening.
	 * Jean II */
	if(mode == DISCOVERY_PASSIVE)
		return;

	info.daddr = discovery->daddr;
	info.saddr = discovery->saddr;

	self = priv;
	ircomm_tty_do_event(self, IRCOMM_TTY_DISCOVERY_INDICATION,
			    NULL, &info);
}

/*
 * Function ircomm_tty_disconnect_indication (instance, sap, reason, skb)
 *
 *    Link disconnected
 *
 */
void ircomm_tty_disconnect_indication(void *instance, void *sap,
				      LM_REASON reason,
				      struct sk_buff *skb)
{
	struct ircomm_tty_cb *self = (struct ircomm_tty_cb *) instance;
	struct tty_struct *tty;

	IRDA_ASSERT(self != NULL, return;);
	IRDA_ASSERT(self->magic == IRCOMM_TTY_MAGIC, return;);

	tty = tty_port_tty_get(&self->port);
	if (!tty)
		return;

	/* This will stop control data transfers */
	self->flow = FLOW_STOP;

	/* Stop data transfers */
	tty->hw_stopped = 1;

	ircomm_tty_do_event(self, IRCOMM_TTY_DISCONNECT_INDICATION, NULL,
			    NULL);
	tty_kref_put(tty);
}

/*
 * Function ircomm_tty_getvalue_confirm (result, obj_id, value, priv)
 *
 *    Got result from the IAS query we make
 *
 */
static void ircomm_tty_getvalue_confirm(int result, __u16 obj_id,
					struct ias_value *value,
					void *priv)
{
	struct ircomm_tty_cb *self = (struct ircomm_tty_cb *) priv;

	IRDA_ASSERT(self != NULL, return;);
	IRDA_ASSERT(self->magic == IRCOMM_TTY_MAGIC, return;);

	/* We probably don't need to make any more queries */
	iriap_close(self->iriap);
	self->iriap = NULL;

	/* Check if request succeeded */
	if (result != IAS_SUCCESS) {
		pr_debug("%s(), got NULL value!\n", __func__);
		return;
	}

	switch (value->type) {
	case IAS_OCT_SEQ:
		pr_debug("%s(), got octet sequence\n", __func__);

		irda_param_extract_all(self, value->t.oct_seq, value->len,
				       &ircomm_param_info);

		ircomm_tty_do_event(self, IRCOMM_TTY_GOT_PARAMETERS, NULL,
				    NULL);
		break;
	case IAS_INTEGER:
		/* Got LSAP selector */
		pr_debug("%s(), got lsapsel = %d\n", __func__ ,
			 value->t.integer);

		if (value->t.integer == -1) {
			pr_debug("%s(), invalid value!\n", __func__);
		} else
			self->dlsap_sel = value->t.integer;

		ircomm_tty_do_event(self, IRCOMM_TTY_GOT_LSAPSEL, NULL, NULL);
		break;
	case IAS_MISSING:
		pr_debug("%s(), got IAS_MISSING\n", __func__);
		break;
	default:
		pr_debug("%s(), got unknown type!\n", __func__);
		break;
	}
	irias_delete_value(value);
}

/*
 * Function ircomm_tty_connect_confirm (instance, sap, qos, max_sdu_size, skb)
 *
 *    Connection confirmed
 *
 */
void ircomm_tty_connect_confirm(void *instance, void *sap,
				struct qos_info *qos,
				__u32 max_data_size,
				__u8 max_header_size,
				struct sk_buff *skb)
{
	struct ircomm_tty_cb *self = (struct ircomm_tty_cb *) instance;

	IRDA_ASSERT(self != NULL, return;);
	IRDA_ASSERT(self->magic == IRCOMM_TTY_MAGIC, return;);

	self->client = TRUE;
	self->max_data_size = max_data_size;
	self->max_header_size = max_header_size;
	self->flow = FLOW_START;

	ircomm_tty_do_event(self, IRCOMM_TTY_CONNECT_CONFIRM, NULL, NULL);

	/* No need to kfree_skb - see ircomm_ttp_connect_confirm() */
}

/*
 * Function ircomm_tty_connect_indication (instance, sap, qos, max_sdu_size,
 *                                         skb)
 *
 *    we are discovered and being requested to connect by remote device !
 *
 */
void ircomm_tty_connect_indication(void *instance, void *sap,
				   struct qos_info *qos,
				   __u32 max_data_size,
				   __u8 max_header_size,
				   struct sk_buff *skb)
{
	struct ircomm_tty_cb *self = (struct ircomm_tty_cb *) instance;
	int clen;

	IRDA_ASSERT(self != NULL, return;);
	IRDA_ASSERT(self->magic == IRCOMM_TTY_MAGIC, return;);

	self->client = FALSE;
	self->max_data_size = max_data_size;
	self->max_header_size = max_header_size;
	self->flow = FLOW_START;

	clen = skb->data[0];
	if (clen)
		irda_param_extract_all(self, skb->data+1,
				       IRDA_MIN(skb->len, clen),
				       &ircomm_param_info);

	ircomm_tty_do_event(self, IRCOMM_TTY_CONNECT_INDICATION, NULL, NULL);

	/* No need to kfree_skb - see ircomm_ttp_connect_indication() */
}

/*
 * Function ircomm_tty_link_established (self)
 *
 *    Called when the IrCOMM link is established
 *
 */
void ircomm_tty_link_established(struct ircomm_tty_cb *self)
{
	struct tty_struct *tty;

	IRDA_ASSERT(self != NULL, return;);
	IRDA_ASSERT(self->magic == IRCOMM_TTY_MAGIC, return;);

	tty = tty_port_tty_get(&self->port);
	if (!tty)
		return;

	del_timer(&self->watchdog_timer);

	/*
	 * IrCOMM link is now up, and if we are not using hardware
	 * flow-control, then declare the hardware as running. Otherwise we
	 * will have to wait for the peer device (DCE) to raise the CTS
	 * line.
	 */
	if (tty_port_cts_enabled(&self->port) &&
			((self->settings.dce & IRCOMM_CTS) == 0)) {
		pr_debug("%s(), waiting for CTS ...\n", __func__);
		goto put;
	} else {
		pr_debug("%s(), starting hardware!\n", __func__);

		tty->hw_stopped = 0;

		/* Wake up processes blocked on open */
		wake_up_interruptible(&self->port.open_wait);
	}

	schedule_work(&self->tqueue);
put:
	tty_kref_put(tty);
}

/*
 * Function ircomm_tty_start_watchdog_timer (self, timeout)
 *
 *    Start the watchdog timer. This timer is used to make sure that any
 *    connection attempt is successful, and if not, we will retry after
 *    the timeout
 */
static void ircomm_tty_start_watchdog_timer(struct ircomm_tty_cb *self,
					    int timeout)
{
	IRDA_ASSERT(self != NULL, return;);
	IRDA_ASSERT(self->magic == IRCOMM_TTY_MAGIC, return;);

	irda_start_timer(&self->watchdog_timer, timeout, (void *) self,
			 ircomm_tty_watchdog_timer_expired);
}

/*
 * Function ircomm_tty_watchdog_timer_expired (data)
 *
 *    Called when the connect procedure have taken to much time.
 *
 */
static void ircomm_tty_watchdog_timer_expired(void *data)
{
	struct ircomm_tty_cb *self = (struct ircomm_tty_cb *) data;

	IRDA_ASSERT(self != NULL, return;);
	IRDA_ASSERT(self->magic == IRCOMM_TTY_MAGIC, return;);

	ircomm_tty_do_event(self, IRCOMM_TTY_WD_TIMER_EXPIRED, NULL, NULL);
}


/*
 * Function ircomm_tty_do_event (self, event, skb)
 *
 *    Process event
 *
 */
int ircomm_tty_do_event(struct ircomm_tty_cb *self, IRCOMM_TTY_EVENT event,
			struct sk_buff *skb, struct ircomm_tty_info *info)
{
	IRDA_ASSERT(self != NULL, return -1;);
	IRDA_ASSERT(self->magic == IRCOMM_TTY_MAGIC, return -1;);

	pr_debug("%s: state=%s, event=%s\n", __func__ ,
		 ircomm_tty_state[self->state], ircomm_tty_event[event]);

	return (*state[self->state])(self, event, skb, info);
}

/*
 * Function ircomm_tty_next_state (self, state)
 *
 *    Switch state
 *
 */
static inline void ircomm_tty_next_state(struct ircomm_tty_cb *self, IRCOMM_TTY_STATE state)
{
	/*
	IRDA_ASSERT(self != NULL, return;);
	IRDA_ASSERT(self->magic == IRCOMM_TTY_MAGIC, return;);

	pr_debug("%s: next state=%s, service type=%d\n", __func__ ,
	ircomm_tty_state[self->state], self->service_type);
	*/
	self->state = state;
}

/*
 * Function ircomm_tty_state_idle (self, event, skb, info)
 *
 *    Just hanging around
 *
 */
static int ircomm_tty_state_idle(struct ircomm_tty_cb *self,
				 IRCOMM_TTY_EVENT event,
				 struct sk_buff *skb,
				 struct ircomm_tty_info *info)
{
	int ret = 0;

	pr_debug("%s: state=%s, event=%s\n", __func__ ,
		 ircomm_tty_state[self->state], ircomm_tty_event[event]);
	switch (event) {
	case IRCOMM_TTY_ATTACH_CABLE:
		/* Try to discover any remote devices */
		ircomm_tty_start_watchdog_timer(self, 3*HZ);
		ircomm_tty_next_state(self, IRCOMM_TTY_SEARCH);

		irlmp_discovery_request(DISCOVERY_DEFAULT_SLOTS);
		break;
	case IRCOMM_TTY_DISCOVERY_INDICATION:
		self->daddr = info->daddr;
		self->saddr = info->saddr;

		if (self->iriap) {
			net_warn_ratelimited("%s(), busy with a previous query\n",
					     __func__);
			return -EBUSY;
		}

		self->iriap = iriap_open(LSAP_ANY, IAS_CLIENT, self,
					 ircomm_tty_getvalue_confirm);

		iriap_getvaluebyclass_request(self->iriap,
					      self->saddr, self->daddr,
					      "IrDA:IrCOMM", "Parameters");

		ircomm_tty_start_watchdog_timer(self, 3*HZ);
		ircomm_tty_next_state(self, IRCOMM_TTY_QUERY_PARAMETERS);
		break;
	case IRCOMM_TTY_CONNECT_INDICATION:
		del_timer(&self->watchdog_timer);

		/* Accept connection */
		ircomm_connect_response(self->ircomm, NULL);
		ircomm_tty_next_state(self, IRCOMM_TTY_READY);
		break;
	case IRCOMM_TTY_WD_TIMER_EXPIRED:
		/* Just stay idle */
		break;
	case IRCOMM_TTY_DETACH_CABLE:
		ircomm_tty_next_state(self, IRCOMM_TTY_IDLE);
		break;
	default:
		pr_debug("%s(), unknown event: %s\n", __func__ ,
			 ircomm_tty_event[event]);
		ret = -EINVAL;
	}
	return ret;
}

/*
 * Function ircomm_tty_state_search (self, event, skb, info)
 *
 *    Trying to discover an IrCOMM device
 *
 */
static int ircomm_tty_state_search(struct ircomm_tty_cb *self,
				   IRCOMM_TTY_EVENT event,
				   struct sk_buff *skb,
				   struct ircomm_tty_info *info)
{
	int ret = 0;

	pr_debug("%s: state=%s, event=%s\n", __func__ ,
		 ircomm_tty_state[self->state], ircomm_tty_event[event]);

	switch (event) {
	case IRCOMM_TTY_DISCOVERY_INDICATION:
		self->daddr = info->daddr;
		self->saddr = info->saddr;

		if (self->iriap) {
			net_warn_ratelimited("%s(), busy with a previous query\n",
					     __func__);
			return -EBUSY;
		}

		self->iriap = iriap_open(LSAP_ANY, IAS_CLIENT, self,
					 ircomm_tty_getvalue_confirm);

		if (self->service_type == IRCOMM_3_WIRE_RAW) {
			iriap_getvaluebyclass_request(self->iriap, self->saddr,
						      self->daddr, "IrLPT",
						      "IrDA:IrLMP:LsapSel");
			ircomm_tty_next_state(self, IRCOMM_TTY_QUERY_LSAP_SEL);
		} else {
			iriap_getvaluebyclass_request(self->iriap, self->saddr,
						      self->daddr,
						      "IrDA:IrCOMM",
						      "Parameters");

			ircomm_tty_next_state(self, IRCOMM_TTY_QUERY_PARAMETERS);
		}
		ircomm_tty_start_watchdog_timer(self, 3*HZ);
		break;
	case IRCOMM_TTY_CONNECT_INDICATION:
		del_timer(&self->watchdog_timer);
		ircomm_tty_ias_unregister(self);

		/* Accept connection */
		ircomm_connect_response(self->ircomm, NULL);
		ircomm_tty_next_state(self, IRCOMM_TTY_READY);
		break;
	case IRCOMM_TTY_WD_TIMER_EXPIRED:
#if 1
		/* Give up */
#else
		/* Try to discover any remote devices */
		ircomm_tty_start_watchdog_timer(self, 3*HZ);
		irlmp_discovery_request(DISCOVERY_DEFAULT_SLOTS);
#endif
		break;
	case IRCOMM_TTY_DETACH_CABLE:
		ircomm_tty_next_state(self, IRCOMM_TTY_IDLE);
		break;
	default:
		pr_debug("%s(), unknown event: %s\n", __func__ ,
			 ircomm_tty_event[event]);
		ret = -EINVAL;
	}
	return ret;
}

/*
 * Function ircomm_tty_state_query (self, event, skb, info)
 *
 *    Querying the remote LM-IAS for IrCOMM parameters
 *
 */
static int ircomm_tty_state_query_parameters(struct ircomm_tty_cb *self,
					     IRCOMM_TTY_EVENT event,
					     struct sk_buff *skb,
					     struct ircomm_tty_info *info)
{
	int ret = 0;

	pr_debug("%s: state=%s, event=%s\n", __func__ ,
		 ircomm_tty_state[self->state], ircomm_tty_event[event]);

	switch (event) {
	case IRCOMM_TTY_GOT_PARAMETERS:
		if (self->iriap) {
			net_warn_ratelimited("%s(), busy with a previous query\n",
					     __func__);
			return -EBUSY;
		}

		self->iriap = iriap_open(LSAP_ANY, IAS_CLIENT, self,
					 ircomm_tty_getvalue_confirm);

		iriap_getvaluebyclass_request(self->iriap, self->saddr,
					      self->daddr, "IrDA:IrCOMM",
					      "IrDA:TinyTP:LsapSel");

		ircomm_tty_start_watchdog_timer(self, 3*HZ);
		ircomm_tty_next_state(self, IRCOMM_TTY_QUERY_LSAP_SEL);
		break;
	case IRCOMM_TTY_WD_TIMER_EXPIRED:
		/* Go back to search mode */
		ircomm_tty_next_state(self, IRCOMM_TTY_SEARCH);
		ircomm_tty_start_watchdog_timer(self, 3*HZ);
		break;
	case IRCOMM_TTY_CONNECT_INDICATION:
		del_timer(&self->watchdog_timer);
		ircomm_tty_ias_unregister(self);

		/* Accept connection */
		ircomm_connect_response(self->ircomm, NULL);
		ircomm_tty_next_state(self, IRCOMM_TTY_READY);
		break;
	case IRCOMM_TTY_DETACH_CABLE:
		ircomm_tty_next_state(self, IRCOMM_TTY_IDLE);
		break;
	default:
		pr_debug("%s(), unknown event: %s\n", __func__ ,
			 ircomm_tty_event[event]);
		ret = -EINVAL;
	}
	return ret;
}

/*
 * Function ircomm_tty_state_query_lsap_sel (self, event, skb, info)
 *
 *    Query remote LM-IAS for the LSAP selector which we can connect to
 *
 */
static int ircomm_tty_state_query_lsap_sel(struct ircomm_tty_cb *self,
					   IRCOMM_TTY_EVENT event,
					   struct sk_buff *skb,
					   struct ircomm_tty_info *info)
{
	int ret = 0;

	pr_debug("%s: state=%s, event=%s\n", __func__ ,
		 ircomm_tty_state[self->state], ircomm_tty_event[event]);

	switch (event) {
	case IRCOMM_TTY_GOT_LSAPSEL:
		/* Connect to remote device */
		ret = ircomm_connect_request(self->ircomm, self->dlsap_sel,
					     self->saddr, self->daddr,
					     NULL, self->service_type);
		ircomm_tty_start_watchdog_timer(self, 3*HZ);
		ircomm_tty_next_state(self, IRCOMM_TTY_SETUP);
		break;
	case IRCOMM_TTY_WD_TIMER_EXPIRED:
		/* Go back to search mode */
		ircomm_tty_next_state(self, IRCOMM_TTY_SEARCH);
		ircomm_tty_start_watchdog_timer(self, 3*HZ);
		break;
	case IRCOMM_TTY_CONNECT_INDICATION:
		del_timer(&self->watchdog_timer);
		ircomm_tty_ias_unregister(self);

		/* Accept connection */
		ircomm_connect_response(self->ircomm, NULL);
		ircomm_tty_next_state(self, IRCOMM_TTY_READY);
		break;
	case IRCOMM_TTY_DETACH_CABLE:
		ircomm_tty_next_state(self, IRCOMM_TTY_IDLE);
		break;
	default:
		pr_debug("%s(), unknown event: %s\n", __func__ ,
			 ircomm_tty_event[event]);
		ret = -EINVAL;
	}
	return ret;
}

/*
 * Function ircomm_tty_state_setup (self, event, skb, info)
 *
 *    Trying to connect
 *
 */
static int ircomm_tty_state_setup(struct ircomm_tty_cb *self,
				  IRCOMM_TTY_EVENT event,
				  struct sk_buff *skb,
				  struct ircomm_tty_info *info)
{
	int ret = 0;

	pr_debug("%s: state=%s, event=%s\n", __func__ ,
		 ircomm_tty_state[self->state], ircomm_tty_event[event]);

	switch (event) {
	case IRCOMM_TTY_CONNECT_CONFIRM:
		del_timer(&self->watchdog_timer);
		ircomm_tty_ias_unregister(self);

		/*
		 * Send initial parameters. This will also send out queued
		 * parameters waiting for the connection to come up
		 */
		ircomm_tty_send_initial_parameters(self);
		ircomm_tty_link_established(self);
		ircomm_tty_next_state(self, IRCOMM_TTY_READY);
		break;
	case IRCOMM_TTY_CONNECT_INDICATION:
		del_timer(&self->watchdog_timer);
		ircomm_tty_ias_unregister(self);

		/* Accept connection */
		ircomm_connect_response(self->ircomm, NULL);
		ircomm_tty_next_state(self, IRCOMM_TTY_READY);
		break;
	case IRCOMM_TTY_WD_TIMER_EXPIRED:
		/* Go back to search mode */
		ircomm_tty_next_state(self, IRCOMM_TTY_SEARCH);
		ircomm_tty_start_watchdog_timer(self, 3*HZ);
		break;
	case IRCOMM_TTY_DETACH_CABLE:
		/* ircomm_disconnect_request(self->ircomm, NULL); */
		ircomm_tty_next_state(self, IRCOMM_TTY_IDLE);
		break;
	default:
		pr_debug("%s(), unknown event: %s\n", __func__ ,
			 ircomm_tty_event[event]);
		ret = -EINVAL;
	}
	return ret;
}

/*
 * Function ircomm_tty_state_ready (self, event, skb, info)
 *
 *    IrCOMM is now connected
 *
 */
static int ircomm_tty_state_ready(struct ircomm_tty_cb *self,
				  IRCOMM_TTY_EVENT event,
				  struct sk_buff *skb,
				  struct ircomm_tty_info *info)
{
	int ret = 0;

	switch (event) {
	case IRCOMM_TTY_DATA_REQUEST:
		ret = ircomm_data_request(self->ircomm, skb);
		break;
	case IRCOMM_TTY_DETACH_CABLE:
		ircomm_disconnect_request(self->ircomm, NULL);
		ircomm_tty_next_state(self, IRCOMM_TTY_IDLE);
		break;
	case IRCOMM_TTY_DISCONNECT_INDICATION:
		ircomm_tty_ias_register(self);
		ircomm_tty_next_state(self, IRCOMM_TTY_SEARCH);
		ircomm_tty_start_watchdog_timer(self, 3*HZ);

		if (self->port.flags & ASYNC_CHECK_CD) {
			/* Drop carrier */
			self->settings.dce = IRCOMM_DELTA_CD;
			ircomm_tty_check_modem_status(self);
		} else {
			pr_debug("%s(), hanging up!\n", __func__);
			tty_port_tty_hangup(&self->port, false);
		}
		break;
	default:
		pr_debug("%s(), unknown event: %s\n", __func__ ,
			 ircomm_tty_event[event]);
		ret = -EINVAL;
	}
	return ret;
}

