/*********************************************************************
 *
 * Filename:      irlan_provider_event.c
 * Version:       0.9
 * Description:   IrLAN provider state machine)
 * Status:        Experimental.
 * Author:        Dag Brattli <dagb@cs.uit.no>
 * Created at:    Sun Aug 31 20:14:37 1997
 * Modified at:   Sat Oct 30 12:52:41 1999
 * Modified by:   Dag Brattli <dagb@cs.uit.no>
 *
 *     Copyright (c) 1998-1999 Dag Brattli <dagb@cs.uit.no>, All Rights Reserved.
 *
 *     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.
 *
 *     Neither Dag Brattli nor University of Tromsø admit liability nor
 *     provide warranty for any of this software. This material is
 *     provided "AS-IS" and at no charge.
 *
 ********************************************************************/

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

#include <net/irda/irlan_provider.h>
#include <net/irda/irlan_event.h>

static int irlan_provider_state_idle(struct irlan_cb *self, IRLAN_EVENT event,
				     struct sk_buff *skb);
static int irlan_provider_state_info(struct irlan_cb *self, IRLAN_EVENT event,
				     struct sk_buff *skb);
static int irlan_provider_state_open(struct irlan_cb *self, IRLAN_EVENT event,
				     struct sk_buff *skb);
static int irlan_provider_state_data(struct irlan_cb *self, IRLAN_EVENT event,
				     struct sk_buff *skb);

static int (*state[])(struct irlan_cb *self, IRLAN_EVENT event,
		      struct sk_buff *skb) =
{
	irlan_provider_state_idle,
	NULL, /* Query */
	NULL, /* Info */
	irlan_provider_state_info,
	NULL, /* Media */
	irlan_provider_state_open,
	NULL, /* Wait */
	NULL, /* Arb */
	irlan_provider_state_data,
	NULL, /* Close */
	NULL, /* Sync */
};

void irlan_do_provider_event(struct irlan_cb *self, IRLAN_EVENT event,
			     struct sk_buff *skb)
{
	IRDA_ASSERT(*state[ self->provider.state] != NULL, return;);

	(*state[self->provider.state]) (self, event, skb);
}

/*
 * Function irlan_provider_state_idle (event, skb, info)
 *
 *    IDLE, We are waiting for an indication that there is a provider
 *    available.
 */
static int irlan_provider_state_idle(struct irlan_cb *self, IRLAN_EVENT event,
				     struct sk_buff *skb)
{
	IRDA_ASSERT(self != NULL, return -1;);

	switch(event) {
	case IRLAN_CONNECT_INDICATION:
	     irlan_provider_connect_response( self, self->provider.tsap_ctrl);
	     irlan_next_provider_state( self, IRLAN_INFO);
	     break;
	default:
		pr_debug("%s(), Unknown event %d\n", __func__ , event);
		break;
	}
	if (skb)
		dev_kfree_skb(skb);

	return 0;
}

/*
 * Function irlan_provider_state_info (self, event, skb, info)
 *
 *    INFO, We have issued a GetInfo command and is awaiting a reply.
 */
static int irlan_provider_state_info(struct irlan_cb *self, IRLAN_EVENT event,
				     struct sk_buff *skb)
{
	int ret;

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

	switch(event) {
	case IRLAN_GET_INFO_CMD:
		/* Be sure to use 802.3 in case of peer mode */
		if (self->provider.access_type == ACCESS_PEER) {
			self->media = MEDIA_802_3;

			/* Check if client has started yet */
			if (self->client.state == IRLAN_IDLE) {
				/* This should get the client going */
				irlmp_discovery_request(8);
			}
		}

		irlan_provider_send_reply(self, CMD_GET_PROVIDER_INFO,
					  RSP_SUCCESS);
		/* Keep state */
		break;
	case IRLAN_GET_MEDIA_CMD:
		irlan_provider_send_reply(self, CMD_GET_MEDIA_CHAR,
					  RSP_SUCCESS);
		/* Keep state */
		break;
	case IRLAN_OPEN_DATA_CMD:
		ret = irlan_parse_open_data_cmd(self, skb);
		if (self->provider.access_type == ACCESS_PEER) {
			/* FIXME: make use of random functions! */
			self->provider.send_arb_val = (jiffies & 0xffff);
		}
		irlan_provider_send_reply(self, CMD_OPEN_DATA_CHANNEL, ret);

		if (ret == RSP_SUCCESS) {
			irlan_next_provider_state(self, IRLAN_OPEN);

			/* Signal client that we are now open */
			irlan_do_client_event(self, IRLAN_PROVIDER_SIGNAL, NULL);
		}
		break;
	case IRLAN_LMP_DISCONNECT:  /* FALLTHROUGH */
	case IRLAN_LAP_DISCONNECT:
		irlan_next_provider_state(self, IRLAN_IDLE);
		break;
	default:
		pr_debug("%s(), Unknown event %d\n", __func__ , event);
		break;
	}
	if (skb)
		dev_kfree_skb(skb);

	return 0;
}

/*
 * Function irlan_provider_state_open (self, event, skb, info)
 *
 *    OPEN, The client has issued a OpenData command and is awaiting a
 *    reply
 *
 */
static int irlan_provider_state_open(struct irlan_cb *self, IRLAN_EVENT event,
				     struct sk_buff *skb)
{
	IRDA_ASSERT(self != NULL, return -1;);

	switch(event) {
	case IRLAN_FILTER_CONFIG_CMD:
		irlan_provider_parse_command(self, CMD_FILTER_OPERATION, skb);
		irlan_provider_send_reply(self, CMD_FILTER_OPERATION,
					  RSP_SUCCESS);
		/* Keep state */
		break;
	case IRLAN_DATA_CONNECT_INDICATION:
		irlan_next_provider_state(self, IRLAN_DATA);
		irlan_provider_connect_response(self, self->tsap_data);
		break;
	case IRLAN_LMP_DISCONNECT:  /* FALLTHROUGH */
	case IRLAN_LAP_DISCONNECT:
		irlan_next_provider_state(self, IRLAN_IDLE);
		break;
	default:
		pr_debug("%s(), Unknown event %d\n", __func__ , event);
		break;
	}
	if (skb)
		dev_kfree_skb(skb);

	return 0;
}

/*
 * Function irlan_provider_state_data (self, event, skb, info)
 *
 *    DATA, The data channel is connected, allowing data transfers between
 *    the local and remote machines.
 *
 */
static int irlan_provider_state_data(struct irlan_cb *self, IRLAN_EVENT event,
				     struct sk_buff *skb)
{
	IRDA_ASSERT(self != NULL, return -1;);
	IRDA_ASSERT(self->magic == IRLAN_MAGIC, return -1;);

	switch(event) {
	case IRLAN_FILTER_CONFIG_CMD:
		irlan_provider_parse_command(self, CMD_FILTER_OPERATION, skb);
		irlan_provider_send_reply(self, CMD_FILTER_OPERATION,
					  RSP_SUCCESS);
		break;
	case IRLAN_LMP_DISCONNECT: /* FALLTHROUGH */
	case IRLAN_LAP_DISCONNECT:
		irlan_next_provider_state(self, IRLAN_IDLE);
		break;
	default:
		pr_debug("%s(), Unknown event %d\n", __func__ , event);
		break;
	}
	if (skb)
		dev_kfree_skb(skb);

	return 0;
}










