/*
 *	IrNET protocol module : Synchronous PPP over an IrDA socket.
 *
 *		Jean II - HPL `00 - <jt@hpl.hp.com>
 *
 * This file implement the IRDA interface of IrNET.
 * Basically, we sit on top of IrTTP. We set up IrTTP, IrIAS properly,
 * and exchange frames with IrTTP.
 */

#include "irnet_irda.h"		/* Private header */
#include <linux/sched.h>
#include <linux/seq_file.h>
#include <asm/unaligned.h>

/*
 * PPP disconnect work: we need to make sure we're in
 * process context when calling ppp_unregister_channel().
 */
static void irnet_ppp_disconnect(struct work_struct *work)
{
	irnet_socket * self =
		container_of(work, irnet_socket, disconnect_work);

	if (self == NULL)
		return;
	/*
	 * If we were connected, cleanup & close the PPP
	 * channel, which will kill pppd (hangup) and the rest.
	 */
	if (self->ppp_open && !self->ttp_open && !self->ttp_connect) {
		ppp_unregister_channel(&self->chan);
		self->ppp_open = 0;
	}
}

/************************* CONTROL CHANNEL *************************/
/*
 * When ppp is not active, /dev/irnet act as a control channel.
 * Writing allow to set up the IrDA destination of the IrNET channel,
 * and any application may be read events happening on IrNET...
 */

/*------------------------------------------------------------------*/
/*
 * Post an event to the control channel...
 * Put the event in the log, and then wait all process blocked on read
 * so they can read the log...
 */
static void
irnet_post_event(irnet_socket *	ap,
		 irnet_event	event,
		 __u32		saddr,
		 __u32		daddr,
		 char *		name,
		 __u16		hints)
{
  int			index;		/* In the log */

  DENTER(CTRL_TRACE, "(ap=0x%p, event=%d, daddr=%08x, name=``%s'')\n",
	 ap, event, daddr, name);

  /* Protect this section via spinlock.
   * Note : as we are the only event producer, we only need to exclude
   * ourself when touching the log, which is nice and easy.
   */
  spin_lock_bh(&irnet_events.spinlock);

  /* Copy the event in the log */
  index = irnet_events.index;
  irnet_events.log[index].event = event;
  irnet_events.log[index].daddr = daddr;
  irnet_events.log[index].saddr = saddr;
  /* Try to copy IrDA nickname */
  if(name)
    strcpy(irnet_events.log[index].name, name);
  else
    irnet_events.log[index].name[0] = '\0';
  /* Copy hints */
  irnet_events.log[index].hints.word = hints;
  /* Try to get ppp unit number */
  if((ap != (irnet_socket *) NULL) && (ap->ppp_open))
    irnet_events.log[index].unit = ppp_unit_number(&ap->chan);
  else
    irnet_events.log[index].unit = -1;

  /* Increment the index
   * Note that we increment the index only after the event is written,
   * to make sure that the readers don't get garbage... */
  irnet_events.index = (index + 1) % IRNET_MAX_EVENTS;

  DEBUG(CTRL_INFO, "New event index is %d\n", irnet_events.index);

  /* Spin lock end */
  spin_unlock_bh(&irnet_events.spinlock);

  /* Now : wake up everybody waiting for events... */
  wake_up_interruptible_all(&irnet_events.rwait);

  DEXIT(CTRL_TRACE, "\n");
}

/************************* IRDA SUBROUTINES *************************/
/*
 * These are a bunch of subroutines called from other functions
 * down there, mostly common code or to improve readability...
 *
 * Note : we duplicate quite heavily some routines of af_irda.c,
 * because our input structure (self) is quite different
 * (struct irnet instead of struct irda_sock), which make sharing
 * the same code impossible (at least, without templates).
 */

/*------------------------------------------------------------------*/
/*
 * Function irda_open_tsap (self)
 *
 *    Open local Transport Service Access Point (TSAP)
 *
 * Create a IrTTP instance for us and set all the IrTTP callbacks.
 */
static inline int
irnet_open_tsap(irnet_socket *	self)
{
  notify_t	notify;		/* Callback structure */

  DENTER(IRDA_SR_TRACE, "(self=0x%p)\n", self);

  DABORT(self->tsap != NULL, -EBUSY, IRDA_SR_ERROR, "Already busy !\n");

  /* Initialize IrTTP callbacks to be used by the IrDA stack */
  irda_notify_init(&notify);
  notify.connect_confirm	= irnet_connect_confirm;
  notify.connect_indication	= irnet_connect_indication;
  notify.disconnect_indication	= irnet_disconnect_indication;
  notify.data_indication	= irnet_data_indication;
  /*notify.udata_indication	= NULL;*/
  notify.flow_indication	= irnet_flow_indication;
  notify.status_indication	= irnet_status_indication;
  notify.instance		= self;
  strlcpy(notify.name, IRNET_NOTIFY_NAME, sizeof(notify.name));

  /* Open an IrTTP instance */
  self->tsap = irttp_open_tsap(LSAP_ANY, DEFAULT_INITIAL_CREDIT,
			       &notify);
  DABORT(self->tsap == NULL, -ENOMEM,
	 IRDA_SR_ERROR, "Unable to allocate TSAP !\n");

  /* Remember which TSAP selector we actually got */
  self->stsap_sel = self->tsap->stsap_sel;

  DEXIT(IRDA_SR_TRACE, " - tsap=0x%p, sel=0x%X\n",
	self->tsap, self->stsap_sel);
  return 0;
}

/*------------------------------------------------------------------*/
/*
 * Function irnet_ias_to_tsap (self, result, value)
 *
 *    Examine an IAS object and extract TSAP
 *
 * We do an IAP query to find the TSAP associated with the IrNET service.
 * When IrIAP pass us the result of the query, this function look at
 * the return values to check for failures and extract the TSAP if
 * possible.
 * Also deallocate value
 * The failure is in self->errno
 * Return TSAP or -1
 */
static inline __u8
irnet_ias_to_tsap(irnet_socket *	self,
		  int			result,
		  struct ias_value *	value)
{
  __u8	dtsap_sel = 0;		/* TSAP we are looking for */

  DENTER(IRDA_SR_TRACE, "(self=0x%p)\n", self);

  /* By default, no error */
  self->errno = 0;

  /* Check if request succeeded */
  switch(result)
    {
      /* Standard errors : service not available */
    case IAS_CLASS_UNKNOWN:
    case IAS_ATTRIB_UNKNOWN:
      DEBUG(IRDA_SR_INFO, "IAS object doesn't exist ! (%d)\n", result);
      self->errno = -EADDRNOTAVAIL;
      break;

      /* Other errors, most likely IrDA stack failure */
    default :
      DEBUG(IRDA_SR_INFO, "IAS query failed ! (%d)\n", result);
      self->errno = -EHOSTUNREACH;
      break;

      /* Success : we got what we wanted */
    case IAS_SUCCESS:
      break;
    }

  /* Check what was returned to us */
  if(value != NULL)
    {
      /* What type of argument have we got ? */
      switch(value->type)
	{
	case IAS_INTEGER:
	  DEBUG(IRDA_SR_INFO, "result=%d\n", value->t.integer);
	  if(value->t.integer != -1)
	    /* Get the remote TSAP selector */
	    dtsap_sel = value->t.integer;
	  else
	    self->errno = -EADDRNOTAVAIL;
	  break;
	default:
	  self->errno = -EADDRNOTAVAIL;
	  DERROR(IRDA_SR_ERROR, "bad type ! (0x%X)\n", value->type);
	  break;
	}

      /* Cleanup */
      irias_delete_value(value);
    }
  else	/* value == NULL */
    {
      /* Nothing returned to us - usually result != SUCCESS */
      if(!(self->errno))
	{
	  DERROR(IRDA_SR_ERROR,
		 "IrDA bug : result == SUCCESS && value == NULL\n");
	  self->errno = -EHOSTUNREACH;
	}
    }
  DEXIT(IRDA_SR_TRACE, "\n");

  /* Return the TSAP */
  return(dtsap_sel);
}

/*------------------------------------------------------------------*/
/*
 * Function irnet_find_lsap_sel (self)
 *
 *    Try to lookup LSAP selector in remote LM-IAS
 *
 * Basically, we start a IAP query, and then go to sleep. When the query
 * return, irnet_getvalue_confirm will wake us up, and we can examine the
 * result of the query...
 * Note that in some case, the query fail even before we go to sleep,
 * creating some races...
 */
static inline int
irnet_find_lsap_sel(irnet_socket *	self)
{
  DENTER(IRDA_SR_TRACE, "(self=0x%p)\n", self);

  /* This should not happen */
  DABORT(self->iriap, -EBUSY, IRDA_SR_ERROR, "busy with a previous query.\n");

  /* Create an IAP instance, will be closed in irnet_getvalue_confirm() */
  self->iriap = iriap_open(LSAP_ANY, IAS_CLIENT, self,
			   irnet_getvalue_confirm);

  /* Treat unexpected signals as disconnect */
  self->errno = -EHOSTUNREACH;

  /* Query remote LM-IAS */
  iriap_getvaluebyclass_request(self->iriap, self->rsaddr, self->daddr,
				IRNET_SERVICE_NAME, IRNET_IAS_VALUE);

  /* The above request is non-blocking.
   * After a while, IrDA will call us back in irnet_getvalue_confirm()
   * We will then call irnet_ias_to_tsap() and finish the
   * connection procedure */

  DEXIT(IRDA_SR_TRACE, "\n");
  return 0;
}

/*------------------------------------------------------------------*/
/*
 * Function irnet_connect_tsap (self)
 *
 *    Initialise the TTP socket and initiate TTP connection
 *
 */
static inline int
irnet_connect_tsap(irnet_socket *	self)
{
  int		err;

  DENTER(IRDA_SR_TRACE, "(self=0x%p)\n", self);

  /* Open a local TSAP (an IrTTP instance) */
  err = irnet_open_tsap(self);
  if(err != 0)
    {
      clear_bit(0, &self->ttp_connect);
      DERROR(IRDA_SR_ERROR, "connect aborted!\n");
      return(err);
    }

  /* Connect to remote device */
  err = irttp_connect_request(self->tsap, self->dtsap_sel,
			      self->rsaddr, self->daddr, NULL,
			      self->max_sdu_size_rx, NULL);
  if(err != 0)
    {
      clear_bit(0, &self->ttp_connect);
      DERROR(IRDA_SR_ERROR, "connect aborted!\n");
      return(err);
    }

  /* The above call is non-blocking.
   * After a while, the IrDA stack will either call us back in
   * irnet_connect_confirm() or irnet_disconnect_indication()
   * See you there ;-) */

  DEXIT(IRDA_SR_TRACE, "\n");
  return(err);
}

/*------------------------------------------------------------------*/
/*
 * Function irnet_discover_next_daddr (self)
 *
 *    Query the IrNET TSAP of the next device in the log.
 *
 * Used in the TSAP discovery procedure.
 */
static inline int
irnet_discover_next_daddr(irnet_socket *	self)
{
  /* Close the last instance of IrIAP, and open a new one.
   * We can't reuse the IrIAP instance in the IrIAP callback */
  if(self->iriap)
    {
      iriap_close(self->iriap);
      self->iriap = NULL;
    }
  /* Create a new IAP instance */
  self->iriap = iriap_open(LSAP_ANY, IAS_CLIENT, self,
			   irnet_discovervalue_confirm);
  if(self->iriap == NULL)
    return -ENOMEM;

  /* Next discovery - before the call to avoid races */
  self->disco_index++;

  /* Check if we have one more address to try */
  if(self->disco_index < self->disco_number)
    {
      /* Query remote LM-IAS */
      iriap_getvaluebyclass_request(self->iriap,
				    self->discoveries[self->disco_index].saddr,
				    self->discoveries[self->disco_index].daddr,
				    IRNET_SERVICE_NAME, IRNET_IAS_VALUE);
      /* The above request is non-blocking.
       * After a while, IrDA will call us back in irnet_discovervalue_confirm()
       * We will then call irnet_ias_to_tsap() and come back here again... */
      return(0);
    }
  else
    return(1);
}

/*------------------------------------------------------------------*/
/*
 * Function irnet_discover_daddr_and_lsap_sel (self)
 *
 *    This try to find a device with the requested service.
 *
 * Initiate a TSAP discovery procedure.
 * It basically look into the discovery log. For each address in the list,
 * it queries the LM-IAS of the device to find if this device offer
 * the requested service.
 * If there is more than one node supporting the service, we complain
 * to the user (it should move devices around).
 * If we find one node which have the requested TSAP, we connect to it.
 *
 * This function just start the whole procedure. It request the discovery
 * log and submit the first IAS query.
 * The bulk of the job is handled in irnet_discovervalue_confirm()
 *
 * Note : this procedure fails if there is more than one device in range
 * on the same dongle, because IrLMP doesn't disconnect the LAP when the
 * last LSAP is closed. Moreover, we would need to wait the LAP
 * disconnection...
 */
static inline int
irnet_discover_daddr_and_lsap_sel(irnet_socket *	self)
{
  int	ret;

  DENTER(IRDA_SR_TRACE, "(self=0x%p)\n", self);

  /* Ask lmp for the current discovery log */
  self->discoveries = irlmp_get_discoveries(&self->disco_number, self->mask,
					    DISCOVERY_DEFAULT_SLOTS);

  /* Check if the we got some results */
  if(self->discoveries == NULL)
    {
      self->disco_number = -1;
      clear_bit(0, &self->ttp_connect);
      DRETURN(-ENETUNREACH, IRDA_SR_INFO, "No Cachelog...\n");
    }
  DEBUG(IRDA_SR_INFO, "Got the log (0x%p), size is %d\n",
	self->discoveries, self->disco_number);

  /* Start with the first discovery */
  self->disco_index = -1;
  self->daddr = DEV_ADDR_ANY;

  /* This will fail if the log is empty - this is non-blocking */
  ret = irnet_discover_next_daddr(self);
  if(ret)
    {
      /* Close IAP */
      if(self->iriap)
	iriap_close(self->iriap);
      self->iriap = NULL;

      /* Cleanup our copy of the discovery log */
      kfree(self->discoveries);
      self->discoveries = NULL;

      clear_bit(0, &self->ttp_connect);
      DRETURN(-ENETUNREACH, IRDA_SR_INFO, "Cachelog empty...\n");
    }

  /* Follow me in irnet_discovervalue_confirm() */

  DEXIT(IRDA_SR_TRACE, "\n");
  return(0);
}

/*------------------------------------------------------------------*/
/*
 * Function irnet_dname_to_daddr (self)
 *
 *    Convert an IrDA nickname to a valid IrDA address
 *
 * It basically look into the discovery log until there is a match.
 */
static inline int
irnet_dname_to_daddr(irnet_socket *	self)
{
  struct irda_device_info *discoveries;	/* Copy of the discovery log */
  int	number;			/* Number of nodes in the log */
  int	i;

  DENTER(IRDA_SR_TRACE, "(self=0x%p)\n", self);

  /* Ask lmp for the current discovery log */
  discoveries = irlmp_get_discoveries(&number, 0xffff,
				      DISCOVERY_DEFAULT_SLOTS);
  /* Check if the we got some results */
  if(discoveries == NULL)
    DRETURN(-ENETUNREACH, IRDA_SR_INFO, "Cachelog empty...\n");

  /*
   * Now, check all discovered devices (if any), and connect
   * client only about the services that the client is
   * interested in...
   */
  for(i = 0; i < number; i++)
    {
      /* Does the name match ? */
      if(!strncmp(discoveries[i].info, self->rname, NICKNAME_MAX_LEN))
	{
	  /* Yes !!! Get it.. */
	  self->daddr = discoveries[i].daddr;
	  DEBUG(IRDA_SR_INFO, "discovered device ``%s'' at address 0x%08x.\n",
		self->rname, self->daddr);
	  kfree(discoveries);
	  DEXIT(IRDA_SR_TRACE, "\n");
	  return 0;
	}
    }
  /* No luck ! */
  DEBUG(IRDA_SR_INFO, "cannot discover device ``%s'' !!!\n", self->rname);
  kfree(discoveries);
  return(-EADDRNOTAVAIL);
}


/************************* SOCKET ROUTINES *************************/
/*
 * This are the main operations on IrNET sockets, basically to create
 * and destroy IrNET sockets. These are called from the PPP part...
 */

/*------------------------------------------------------------------*/
/*
 * Create a IrNET instance : just initialise some parameters...
 */
int
irda_irnet_create(irnet_socket *	self)
{
  DENTER(IRDA_SOCK_TRACE, "(self=0x%p)\n", self);

  self->magic = IRNET_MAGIC;	/* Paranoia */

  self->ttp_open = 0;		/* Prevent higher layer from accessing IrTTP */
  self->ttp_connect = 0;	/* Not connecting yet */
  self->rname[0] = '\0';	/* May be set via control channel */
  self->rdaddr = DEV_ADDR_ANY;	/* May be set via control channel */
  self->rsaddr = DEV_ADDR_ANY;	/* May be set via control channel */
  self->daddr = DEV_ADDR_ANY;	/* Until we get connected */
  self->saddr = DEV_ADDR_ANY;	/* Until we get connected */
  self->max_sdu_size_rx = TTP_SAR_UNBOUND;

  /* Register as a client with IrLMP */
  self->ckey = irlmp_register_client(0, NULL, NULL, NULL);
#ifdef DISCOVERY_NOMASK
  self->mask = 0xffff;		/* For W2k compatibility */
#else /* DISCOVERY_NOMASK */
  self->mask = irlmp_service_to_hint(S_LAN);
#endif /* DISCOVERY_NOMASK */
  self->tx_flow = FLOW_START;	/* Flow control from IrTTP */

  INIT_WORK(&self->disconnect_work, irnet_ppp_disconnect);

  DEXIT(IRDA_SOCK_TRACE, "\n");
  return(0);
}

/*------------------------------------------------------------------*/
/*
 * Connect to the other side :
 *	o convert device name to an address
 *	o find the socket number (dlsap)
 *	o Establish the connection
 *
 * Note : We no longer mimic af_irda. The IAS query for finding the TSAP
 * is done asynchronously, like the TTP connection. This allow us to
 * call this function from any context (not only process).
 * The downside is that following what's happening in there is tricky
 * because it involve various functions all over the place...
 */
int
irda_irnet_connect(irnet_socket *	self)
{
  int		err;

  DENTER(IRDA_SOCK_TRACE, "(self=0x%p)\n", self);

  /* Check if we are already trying to connect.
   * Because irda_irnet_connect() can be called directly by pppd plus
   * packet retries in ppp_generic and connect may take time, plus we may
   * race with irnet_connect_indication(), we need to be careful there... */
  if(test_and_set_bit(0, &self->ttp_connect))
    DRETURN(-EBUSY, IRDA_SOCK_INFO, "Already connecting...\n");
  if((self->iriap != NULL) || (self->tsap != NULL))
    DERROR(IRDA_SOCK_ERROR, "Socket not cleaned up...\n");

  /* Insert ourselves in the hashbin so that the IrNET server can find us.
   * Notes : 4th arg is string of 32 char max and must be null terminated
   *	     When 4th arg is used (string), 3rd arg isn't (int)
   *	     Can't re-insert (MUST remove first) so check for that... */
  if((irnet_server.running) && (self->q.q_next == NULL))
    {
      spin_lock_bh(&irnet_server.spinlock);
      hashbin_insert(irnet_server.list, (irda_queue_t *) self, 0, self->rname);
      spin_unlock_bh(&irnet_server.spinlock);
      DEBUG(IRDA_SOCK_INFO, "Inserted ``%s'' in hashbin...\n", self->rname);
    }

  /* If we don't have anything (no address, no name) */
  if((self->rdaddr == DEV_ADDR_ANY) && (self->rname[0] == '\0'))
    {
      /* Try to find a suitable address */
      if((err = irnet_discover_daddr_and_lsap_sel(self)) != 0)
	DRETURN(err, IRDA_SOCK_INFO, "auto-connect failed!\n");
      /* In most cases, the call above is non-blocking */
    }
  else
    {
      /* If we have only the name (no address), try to get an address */
      if(self->rdaddr == DEV_ADDR_ANY)
	{
	  if((err = irnet_dname_to_daddr(self)) != 0)
	    DRETURN(err, IRDA_SOCK_INFO, "name connect failed!\n");
	}
      else
	/* Use the requested destination address */
	self->daddr = self->rdaddr;

      /* Query remote LM-IAS to find LSAP selector */
      irnet_find_lsap_sel(self);
      /* The above call is non blocking */
    }

  /* At this point, we are waiting for the IrDA stack to call us back,
   * or we have already failed.
   * We will finish the connection procedure in irnet_connect_tsap().
   */
  DEXIT(IRDA_SOCK_TRACE, "\n");
  return(0);
}

/*------------------------------------------------------------------*/
/*
 * Function irda_irnet_destroy(self)
 *
 *    Destroy irnet instance
 *
 * Note : this need to be called from a process context.
 */
void
irda_irnet_destroy(irnet_socket *	self)
{
  DENTER(IRDA_SOCK_TRACE, "(self=0x%p)\n", self);
  if(self == NULL)
    return;

  /* Remove ourselves from hashbin (if we are queued in hashbin)
   * Note : `irnet_server.running' protect us from calls in hashbin_delete() */
  if((irnet_server.running) && (self->q.q_next != NULL))
    {
      struct irnet_socket *	entry;
      DEBUG(IRDA_SOCK_INFO, "Removing from hash..\n");
      spin_lock_bh(&irnet_server.spinlock);
      entry = hashbin_remove_this(irnet_server.list, (irda_queue_t *) self);
      self->q.q_next = NULL;
      spin_unlock_bh(&irnet_server.spinlock);
      DASSERT(entry == self, , IRDA_SOCK_ERROR, "Can't remove from hash.\n");
    }

  /* If we were connected, post a message */
  if(test_bit(0, &self->ttp_open))
    {
      /* Note : as the disconnect comes from ppp_generic, the unit number
       * doesn't exist anymore when we post the event, so we need to pass
       * NULL as the first arg... */
      irnet_post_event(NULL, IRNET_DISCONNECT_TO,
		       self->saddr, self->daddr, self->rname, 0);
    }

  /* Prevent various IrDA callbacks from messing up things
   * Need to be first */
  clear_bit(0, &self->ttp_connect);

  /* Prevent higher layer from accessing IrTTP */
  clear_bit(0, &self->ttp_open);

  /* Unregister with IrLMP */
  irlmp_unregister_client(self->ckey);

  /* Unregister with LM-IAS */
  if(self->iriap)
    {
      iriap_close(self->iriap);
      self->iriap = NULL;
    }

  /* Cleanup eventual discoveries from connection attempt or control channel */
  if(self->discoveries != NULL)
    {
      /* Cleanup our copy of the discovery log */
      kfree(self->discoveries);
      self->discoveries = NULL;
    }

  /* Close our IrTTP connection */
  if(self->tsap)
    {
      DEBUG(IRDA_SOCK_INFO, "Closing our TTP connection.\n");
      irttp_disconnect_request(self->tsap, NULL, P_NORMAL);
      irttp_close_tsap(self->tsap);
      self->tsap = NULL;
    }
  self->stsap_sel = 0;

  DEXIT(IRDA_SOCK_TRACE, "\n");
  return;
}


/************************** SERVER SOCKET **************************/
/*
 * The IrNET service is composed of one server socket and a variable
 * number of regular IrNET sockets. The server socket is supposed to
 * handle incoming connections and redirect them to one IrNET sockets.
 * It's a superset of the regular IrNET socket, but has a very distinct
 * behaviour...
 */

/*------------------------------------------------------------------*/
/*
 * Function irnet_daddr_to_dname (self)
 *
 *    Convert an IrDA address to a IrDA nickname
 *
 * It basically look into the discovery log until there is a match.
 */
static inline int
irnet_daddr_to_dname(irnet_socket *	self)
{
  struct irda_device_info *discoveries;	/* Copy of the discovery log */
  int	number;			/* Number of nodes in the log */
  int	i;

  DENTER(IRDA_SERV_TRACE, "(self=0x%p)\n", self);

  /* Ask lmp for the current discovery log */
  discoveries = irlmp_get_discoveries(&number, 0xffff,
				      DISCOVERY_DEFAULT_SLOTS);
  /* Check if the we got some results */
  if (discoveries == NULL)
    DRETURN(-ENETUNREACH, IRDA_SERV_INFO, "Cachelog empty...\n");

  /* Now, check all discovered devices (if any) */
  for(i = 0; i < number; i++)
    {
      /* Does the name match ? */
      if(discoveries[i].daddr == self->daddr)
	{
	  /* Yes !!! Get it.. */
	  strlcpy(self->rname, discoveries[i].info, sizeof(self->rname));
	  self->rname[sizeof(self->rname) - 1] = '\0';
	  DEBUG(IRDA_SERV_INFO, "Device 0x%08x is in fact ``%s''.\n",
		self->daddr, self->rname);
	  kfree(discoveries);
	  DEXIT(IRDA_SERV_TRACE, "\n");
	  return 0;
	}
    }
  /* No luck ! */
  DEXIT(IRDA_SERV_INFO, ": cannot discover device 0x%08x !!!\n", self->daddr);
  kfree(discoveries);
  return(-EADDRNOTAVAIL);
}

/*------------------------------------------------------------------*/
/*
 * Function irda_find_socket (self)
 *
 *    Find the correct IrNET socket
 *
 * Look into the list of IrNET sockets and finds one with the right
 * properties...
 */
static inline irnet_socket *
irnet_find_socket(irnet_socket *	self)
{
  irnet_socket *	new = (irnet_socket *) NULL;
  int			err;

  DENTER(IRDA_SERV_TRACE, "(self=0x%p)\n", self);

  /* Get the addresses of the requester */
  self->daddr = irttp_get_daddr(self->tsap);
  self->saddr = irttp_get_saddr(self->tsap);

  /* Try to get the IrDA nickname of the requester */
  err = irnet_daddr_to_dname(self);

  /* Protect access to the instance list */
  spin_lock_bh(&irnet_server.spinlock);

  /* So now, try to get an socket having specifically
   * requested that nickname */
  if(err == 0)
    {
      new = (irnet_socket *) hashbin_find(irnet_server.list,
					  0, self->rname);
      if(new)
	DEBUG(IRDA_SERV_INFO, "Socket 0x%p matches rname ``%s''.\n",
	      new, new->rname);
    }

  /* If no name matches, try to find an socket by the destination address */
  /* It can be either the requested destination address (set via the
   * control channel), or the current destination address if the
   * socket is in the middle of a connection request */
  if(new == (irnet_socket *) NULL)
    {
      new = (irnet_socket *) hashbin_get_first(irnet_server.list);
      while(new !=(irnet_socket *) NULL)
	{
	  /* Does it have the same address ? */
	  if((new->rdaddr == self->daddr) || (new->daddr == self->daddr))
	    {
	      /* Yes !!! Get it.. */
	      DEBUG(IRDA_SERV_INFO, "Socket 0x%p matches daddr %#08x.\n",
		    new, self->daddr);
	      break;
	    }
	  new = (irnet_socket *) hashbin_get_next(irnet_server.list);
	}
    }

  /* If we don't have any socket, get the first unconnected socket */
  if(new == (irnet_socket *) NULL)
    {
      new = (irnet_socket *) hashbin_get_first(irnet_server.list);
      while(new !=(irnet_socket *) NULL)
	{
	  /* Is it available ? */
	  if(!(test_bit(0, &new->ttp_open)) && (new->rdaddr == DEV_ADDR_ANY) &&
	     (new->rname[0] == '\0') && (new->ppp_open))
	    {
	      /* Yes !!! Get it.. */
	      DEBUG(IRDA_SERV_INFO, "Socket 0x%p is free.\n",
		    new);
	      break;
	    }
	  new = (irnet_socket *) hashbin_get_next(irnet_server.list);
	}
    }

  /* Spin lock end */
  spin_unlock_bh(&irnet_server.spinlock);

  DEXIT(IRDA_SERV_TRACE, " - new = 0x%p\n", new);
  return new;
}

/*------------------------------------------------------------------*/
/*
 * Function irda_connect_socket (self)
 *
 *    Connect an incoming connection to the socket
 *
 */
static inline int
irnet_connect_socket(irnet_socket *	server,
		     irnet_socket *	new,
		     struct qos_info *	qos,
		     __u32		max_sdu_size,
		     __u8		max_header_size)
{
  DENTER(IRDA_SERV_TRACE, "(server=0x%p, new=0x%p)\n",
	 server, new);

  /* Now attach up the new socket */
  new->tsap = irttp_dup(server->tsap, new);
  DABORT(new->tsap == NULL, -1, IRDA_SERV_ERROR, "dup failed!\n");

  /* Set up all the relevant parameters on the new socket */
  new->stsap_sel = new->tsap->stsap_sel;
  new->dtsap_sel = new->tsap->dtsap_sel;
  new->saddr = irttp_get_saddr(new->tsap);
  new->daddr = irttp_get_daddr(new->tsap);

  new->max_header_size = max_header_size;
  new->max_sdu_size_tx = max_sdu_size;
  new->max_data_size   = max_sdu_size;
#ifdef STREAM_COMPAT
  /* If we want to receive "stream sockets" */
  if(max_sdu_size == 0)
    new->max_data_size = irttp_get_max_seg_size(new->tsap);
#endif /* STREAM_COMPAT */

  /* Clean up the original one to keep it in listen state */
  irttp_listen(server->tsap);

  /* Send a connection response on the new socket */
  irttp_connect_response(new->tsap, new->max_sdu_size_rx, NULL);

  /* Allow PPP to send its junk over the new socket... */
  set_bit(0, &new->ttp_open);

  /* Not connecting anymore, and clean up last possible remains
   * of connection attempts on the socket */
  clear_bit(0, &new->ttp_connect);
  if(new->iriap)
    {
      iriap_close(new->iriap);
      new->iriap = NULL;
    }
  if(new->discoveries != NULL)
    {
      kfree(new->discoveries);
      new->discoveries = NULL;
    }

#ifdef CONNECT_INDIC_KICK
  /* As currently we don't block packets in ppp_irnet_send() while passive,
   * this is not really needed...
   * Also, not doing it give IrDA a chance to finish the setup properly
   * before being swamped with packets... */
  ppp_output_wakeup(&new->chan);
#endif /* CONNECT_INDIC_KICK */

  /* Notify the control channel */
  irnet_post_event(new, IRNET_CONNECT_FROM,
		   new->saddr, new->daddr, server->rname, 0);

  DEXIT(IRDA_SERV_TRACE, "\n");
  return 0;
}

/*------------------------------------------------------------------*/
/*
 * Function irda_disconnect_server (self)
 *
 *    Cleanup the server socket when the incoming connection abort
 *
 */
static inline void
irnet_disconnect_server(irnet_socket *	self,
			struct sk_buff *skb)
{
  DENTER(IRDA_SERV_TRACE, "(self=0x%p)\n", self);

  /* Put the received packet in the black hole */
  kfree_skb(skb);

#ifdef FAIL_SEND_DISCONNECT
  /* Tell the other party we don't want to be connected */
  /* Hum... Is it the right thing to do ? And do we need to send
   * a connect response before ? It looks ok without this... */
  irttp_disconnect_request(self->tsap, NULL, P_NORMAL);
#endif /* FAIL_SEND_DISCONNECT */

  /* Notify the control channel (see irnet_find_socket()) */
  irnet_post_event(NULL, IRNET_REQUEST_FROM,
		   self->saddr, self->daddr, self->rname, 0);

  /* Clean up the server to keep it in listen state */
  irttp_listen(self->tsap);

  DEXIT(IRDA_SERV_TRACE, "\n");
  return;
}

/*------------------------------------------------------------------*/
/*
 * Function irda_setup_server (self)
 *
 *    Create a IrTTP server and set it up...
 *
 * Register the IrLAN hint bit, create a IrTTP instance for us,
 * set all the IrTTP callbacks and create an IrIAS entry...
 */
static inline int
irnet_setup_server(void)
{
  __u16		hints;

  DENTER(IRDA_SERV_TRACE, "()\n");

  /* Initialise the regular socket part of the server */
  irda_irnet_create(&irnet_server.s);

  /* Open a local TSAP (an IrTTP instance) for the server */
  irnet_open_tsap(&irnet_server.s);

  /* PPP part setup */
  irnet_server.s.ppp_open = 0;
  irnet_server.s.chan.private = NULL;
  irnet_server.s.file = NULL;

  /* Get the hint bit corresponding to IrLAN */
  /* Note : we overload the IrLAN hint bit. As it is only a "hint", and as
   * we provide roughly the same functionality as IrLAN, this is ok.
   * In fact, the situation is similar as JetSend overloading the Obex hint
   */
  hints = irlmp_service_to_hint(S_LAN);

#ifdef ADVERTISE_HINT
  /* Register with IrLMP as a service (advertise our hint bit) */
  irnet_server.skey = irlmp_register_service(hints);
#endif /* ADVERTISE_HINT */

  /* Register with LM-IAS (so that people can connect to us) */
  irnet_server.ias_obj = irias_new_object(IRNET_SERVICE_NAME, jiffies);
  irias_add_integer_attrib(irnet_server.ias_obj, IRNET_IAS_VALUE,
			   irnet_server.s.stsap_sel, IAS_KERNEL_ATTR);
  irias_insert_object(irnet_server.ias_obj);

#ifdef DISCOVERY_EVENTS
  /* Tell IrLMP we want to be notified of newly discovered nodes */
  irlmp_update_client(irnet_server.s.ckey, hints,
		      irnet_discovery_indication, irnet_expiry_indication,
		      (void *) &irnet_server.s);
#endif

  DEXIT(IRDA_SERV_TRACE, " - self=0x%p\n", &irnet_server.s);
  return 0;
}

/*------------------------------------------------------------------*/
/*
 * Function irda_destroy_server (self)
 *
 *    Destroy the IrTTP server...
 *
 * Reverse of the previous function...
 */
static inline void
irnet_destroy_server(void)
{
  DENTER(IRDA_SERV_TRACE, "()\n");

#ifdef ADVERTISE_HINT
  /* Unregister with IrLMP */
  irlmp_unregister_service(irnet_server.skey);
#endif /* ADVERTISE_HINT */

  /* Unregister with LM-IAS */
  if(irnet_server.ias_obj)
    irias_delete_object(irnet_server.ias_obj);

  /* Cleanup the socket part */
  irda_irnet_destroy(&irnet_server.s);

  DEXIT(IRDA_SERV_TRACE, "\n");
  return;
}


/************************ IRDA-TTP CALLBACKS ************************/
/*
 * When we create a IrTTP instance, we pass to it a set of callbacks
 * that IrTTP will call in case of various events.
 * We take care of those events here.
 */

/*------------------------------------------------------------------*/
/*
 * Function irnet_data_indication (instance, sap, skb)
 *
 *    Received some data from TinyTP. Just queue it on the receive queue
 *
 */
static int
irnet_data_indication(void *	instance,
		      void *	sap,
		      struct sk_buff *skb)
{
  irnet_socket *	ap = (irnet_socket *) instance;
  unsigned char *	p;
  int			code = 0;

  DENTER(IRDA_TCB_TRACE, "(self/ap=0x%p, skb=0x%p)\n",
	 ap, skb);
  DASSERT(skb != NULL, 0, IRDA_CB_ERROR, "skb is NULL !!!\n");

  /* Check is ppp is ready to receive our packet */
  if(!ap->ppp_open)
    {
      DERROR(IRDA_CB_ERROR, "PPP not ready, dropping packet...\n");
      /* When we return error, TTP will need to requeue the skb and
       * will stop the sender. IrTTP will stall until we send it a
       * flow control request... */
      return -ENOMEM;
    }

  /* strip address/control field if present */
  p = skb->data;
  if((p[0] == PPP_ALLSTATIONS) && (p[1] == PPP_UI))
    {
      /* chop off address/control */
      if(skb->len < 3)
	goto err_exit;
      p = skb_pull(skb, 2);
    }

  /* decompress protocol field if compressed */
  if(p[0] & 1)
    {
      /* protocol is compressed */
      skb_push(skb, 1)[0] = 0;
    }
  else
    if(skb->len < 2)
      goto err_exit;

  /* pass to generic ppp layer */
  /* Note : how do I know if ppp can accept or not the packet ? This is
   * essential if I want to manage flow control smoothly... */
  ppp_input(&ap->chan, skb);

  DEXIT(IRDA_TCB_TRACE, "\n");
  return 0;

 err_exit:
  DERROR(IRDA_CB_ERROR, "Packet too small, dropping...\n");
  kfree_skb(skb);
  ppp_input_error(&ap->chan, code);
  return 0;	/* Don't return an error code, only for flow control... */
}

/*------------------------------------------------------------------*/
/*
 * Function irnet_disconnect_indication (instance, sap, reason, skb)
 *
 *    Connection has been closed. Chech reason to find out why
 *
 * Note : there are many cases where we come here :
 *	o attempted to connect, timeout
 *	o connected, link is broken, LAP has timeout
 *	o connected, other side close the link
 *	o connection request on the server not handled
 */
static void
irnet_disconnect_indication(void *	instance,
			    void *	sap,
			    LM_REASON	reason,
			    struct sk_buff *skb)
{
  irnet_socket *	self = (irnet_socket *) instance;
  int			test_open;
  int			test_connect;

  DENTER(IRDA_TCB_TRACE, "(self=0x%p)\n", self);
  DASSERT(self != NULL, , IRDA_CB_ERROR, "Self is NULL !!!\n");

  /* Don't care about it, but let's not leak it */
  if(skb)
    dev_kfree_skb(skb);

  /* Prevent higher layer from accessing IrTTP */
  test_open = test_and_clear_bit(0, &self->ttp_open);
  /* Not connecting anymore...
   * (note : TSAP is open, so IAP callbacks are no longer pending...) */
  test_connect = test_and_clear_bit(0, &self->ttp_connect);

  /* If both self->ttp_open and self->ttp_connect are NULL, it mean that we
   * have a race condition with irda_irnet_destroy() or
   * irnet_connect_indication(), so don't mess up tsap...
   */
  if(!(test_open || test_connect))
    {
      DERROR(IRDA_CB_ERROR, "Race condition detected...\n");
      return;
    }

  /* If we were active, notify the control channel */
  if(test_open)
    irnet_post_event(self, IRNET_DISCONNECT_FROM,
		     self->saddr, self->daddr, self->rname, 0);
  else
    /* If we were trying to connect, notify the control channel */
    if((self->tsap) && (self != &irnet_server.s))
      irnet_post_event(self, IRNET_NOANSWER_FROM,
		       self->saddr, self->daddr, self->rname, 0);

  /* Close our IrTTP connection, cleanup tsap */
  if((self->tsap) && (self != &irnet_server.s))
    {
      DEBUG(IRDA_CB_INFO, "Closing our TTP connection.\n");
      irttp_close_tsap(self->tsap);
      self->tsap = NULL;
    }
  /* Cleanup the socket in case we want to reconnect in ppp_output_wakeup() */
  self->stsap_sel = 0;
  self->daddr = DEV_ADDR_ANY;
  self->tx_flow = FLOW_START;

  /* Deal with the ppp instance if it's still alive */
  if(self->ppp_open)
    {
      if(test_open)
	{
	  /* ppp_unregister_channel() wants a user context. */
	  schedule_work(&self->disconnect_work);
	}
      else
	{
	  /* If we were trying to connect, flush (drain) ppp_generic
	   * Tx queue (most often we have blocked it), which will
	   * trigger an other attempt to connect. If we are passive,
	   * this will empty the Tx queue after last try. */
	  ppp_output_wakeup(&self->chan);
	}
    }

  DEXIT(IRDA_TCB_TRACE, "\n");
}

/*------------------------------------------------------------------*/
/*
 * Function irnet_connect_confirm (instance, sap, qos, max_sdu_size, skb)
 *
 *    Connections has been confirmed by the remote device
 *
 */
static void
irnet_connect_confirm(void *	instance,
		      void *	sap,
		      struct qos_info *qos,
		      __u32	max_sdu_size,
		      __u8	max_header_size,
		      struct sk_buff *skb)
{
  irnet_socket *	self = (irnet_socket *) instance;

  DENTER(IRDA_TCB_TRACE, "(self=0x%p)\n", self);

  /* Check if socket is closing down (via irda_irnet_destroy()) */
  if(! test_bit(0, &self->ttp_connect))
    {
      DERROR(IRDA_CB_ERROR, "Socket no longer connecting. Ouch !\n");
      return;
    }

  /* How much header space do we need to reserve */
  self->max_header_size = max_header_size;

  /* IrTTP max SDU size in transmit direction */
  self->max_sdu_size_tx = max_sdu_size;
  self->max_data_size = max_sdu_size;
#ifdef STREAM_COMPAT
  if(max_sdu_size == 0)
    self->max_data_size = irttp_get_max_seg_size(self->tsap);
#endif /* STREAM_COMPAT */

  /* At this point, IrLMP has assigned our source address */
  self->saddr = irttp_get_saddr(self->tsap);

  /* Allow higher layer to access IrTTP */
  set_bit(0, &self->ttp_open);
  clear_bit(0, &self->ttp_connect);	/* Not racy, IrDA traffic is serial */
  /* Give a kick in the ass of ppp_generic so that he sends us some data */
  ppp_output_wakeup(&self->chan);

  /* Check size of received packet */
  if(skb->len > 0)
    {
#ifdef PASS_CONNECT_PACKETS
      DEBUG(IRDA_CB_INFO, "Passing connect packet to PPP.\n");
      /* Try to pass it to PPP */
      irnet_data_indication(instance, sap, skb);
#else /* PASS_CONNECT_PACKETS */
      DERROR(IRDA_CB_ERROR, "Dropping non empty packet.\n");
      kfree_skb(skb);	/* Note : will be optimised with other kfree... */
#endif /* PASS_CONNECT_PACKETS */
    }
  else
    kfree_skb(skb);

  /* Notify the control channel */
  irnet_post_event(self, IRNET_CONNECT_TO,
		   self->saddr, self->daddr, self->rname, 0);

  DEXIT(IRDA_TCB_TRACE, "\n");
}

/*------------------------------------------------------------------*/
/*
 * Function irnet_flow_indication (instance, sap, flow)
 *
 *    Used by TinyTP to tell us if it can accept more data or not
 *
 */
static void
irnet_flow_indication(void *	instance,
		      void *	sap,
		      LOCAL_FLOW flow)
{
  irnet_socket *	self = (irnet_socket *) instance;
  LOCAL_FLOW		oldflow = self->tx_flow;

  DENTER(IRDA_TCB_TRACE, "(self=0x%p, flow=%d)\n", self, flow);

  /* Update our state */
  self->tx_flow = flow;

  /* Check what IrTTP want us to do... */
  switch(flow)
    {
    case FLOW_START:
      DEBUG(IRDA_CB_INFO, "IrTTP wants us to start again\n");
      /* Check if we really need to wake up PPP */
      if(oldflow == FLOW_STOP)
	ppp_output_wakeup(&self->chan);
      else
	DEBUG(IRDA_CB_INFO, "But we were already transmitting !!!\n");
      break;
    case FLOW_STOP:
      DEBUG(IRDA_CB_INFO, "IrTTP wants us to slow down\n");
      break;
    default:
      DEBUG(IRDA_CB_INFO, "Unknown flow command!\n");
      break;
    }

  DEXIT(IRDA_TCB_TRACE, "\n");
}

/*------------------------------------------------------------------*/
/*
 * Function irnet_status_indication (instance, sap, reason, skb)
 *
 *    Link (IrLAP) status report.
 *
 */
static void
irnet_status_indication(void *	instance,
			LINK_STATUS link,
			LOCK_STATUS lock)
{
  irnet_socket *	self = (irnet_socket *) instance;

  DENTER(IRDA_TCB_TRACE, "(self=0x%p)\n", self);
  DASSERT(self != NULL, , IRDA_CB_ERROR, "Self is NULL !!!\n");

  /* We can only get this event if we are connected */
  switch(link)
    {
    case STATUS_NO_ACTIVITY:
      irnet_post_event(self, IRNET_BLOCKED_LINK,
		       self->saddr, self->daddr, self->rname, 0);
      break;
    default:
      DEBUG(IRDA_CB_INFO, "Unknown status...\n");
    }

  DEXIT(IRDA_TCB_TRACE, "\n");
}

/*------------------------------------------------------------------*/
/*
 * Function irnet_connect_indication(instance, sap, qos, max_sdu_size, userdata)
 *
 *    Incoming connection
 *
 * In theory, this function is called only on the server socket.
 * Some other node is attempting to connect to the IrNET service, and has
 * sent a connection request on our server socket.
 * We just redirect the connection to the relevant IrNET socket.
 *
 * Note : we also make sure that between 2 irnet nodes, there can
 * exist only one irnet connection.
 */
static void
irnet_connect_indication(void *		instance,
			 void *		sap,
			 struct qos_info *qos,
			 __u32		max_sdu_size,
			 __u8		max_header_size,
			 struct sk_buff *skb)
{
  irnet_socket *	server = &irnet_server.s;
  irnet_socket *	new = (irnet_socket *) NULL;

  DENTER(IRDA_TCB_TRACE, "(server=0x%p)\n", server);
  DASSERT(instance == &irnet_server, , IRDA_CB_ERROR,
	  "Invalid instance (0x%p) !!!\n", instance);
  DASSERT(sap == irnet_server.s.tsap, , IRDA_CB_ERROR, "Invalid sap !!!\n");

  /* Try to find the most appropriate IrNET socket */
  new = irnet_find_socket(server);

  /* After all this hard work, do we have an socket ? */
  if(new == (irnet_socket *) NULL)
    {
      DEXIT(IRDA_CB_INFO, ": No socket waiting for this connection.\n");
      irnet_disconnect_server(server, skb);
      return;
    }

  /* Is the socket already busy ? */
  if(test_bit(0, &new->ttp_open))
    {
      DEXIT(IRDA_CB_INFO, ": Socket already connected.\n");
      irnet_disconnect_server(server, skb);
      return;
    }

  /* The following code is a bit tricky, so need comments ;-)
   */
  /* If ttp_connect is set, the socket is trying to connect to the other
   * end and may have sent a IrTTP connection request and is waiting for
   * a connection response (that may never come).
   * Now, the pain is that the socket may have opened a tsap and is
   * waiting on it, while the other end is trying to connect to it on
   * another tsap.
   * Because IrNET can be peer to peer, we need to workaround this.
   * Furthermore, the way the irnetd script is implemented, the
   * target will create a second IrNET connection back to the
   * originator and expect the originator to bind this new connection
   * to the original PPPD instance.
   * And of course, if we don't use irnetd, we can have a race when
   * both side try to connect simultaneously, which could leave both
   * connections half closed (yuck).
   * Conclusions :
   *	1) The "originator" must accept the new connection and get rid
   *	   of the old one so that irnetd works
   *	2) One side must deny the new connection to avoid races,
   *	   but both side must agree on which side it is...
   * Most often, the originator is primary at the LAP layer.
   * Jean II
   */
  /* Now, let's look at the way I wrote the test...
   * We need to clear up the ttp_connect flag atomically to prevent
   * irnet_disconnect_indication() to mess up the tsap we are going to close.
   * We want to clear the ttp_connect flag only if we close the tsap,
   * otherwise we will never close it, so we need to check for primary
   * *before* doing the test on the flag.
   * And of course, ALLOW_SIMULT_CONNECT can disable this entirely...
   * Jean II
   */

  /* Socket already connecting ? On primary ? */
  if(0
#ifdef ALLOW_SIMULT_CONNECT
     || ((irttp_is_primary(server->tsap) == 1)	/* primary */
	 && (test_and_clear_bit(0, &new->ttp_connect)))
#endif /* ALLOW_SIMULT_CONNECT */
     )
    {
      DERROR(IRDA_CB_ERROR, "Socket already connecting, but going to reuse it !\n");

      /* Cleanup the old TSAP if necessary - IrIAP will be cleaned up later */
      if(new->tsap != NULL)
	{
	  /* Close the old connection the new socket was attempting,
	   * so that we can hook it up to the new connection.
	   * It's now safe to do it... */
	  irttp_close_tsap(new->tsap);
	  new->tsap = NULL;
	}
    }
  else
    {
      /* Three options :
       * 1) socket was not connecting or connected : ttp_connect should be 0.
       * 2) we don't want to connect the socket because we are secondary or
       * ALLOW_SIMULT_CONNECT is undefined. ttp_connect should be 1.
       * 3) we are half way in irnet_disconnect_indication(), and it's a
       * nice race condition... Fortunately, we can detect that by checking
       * if tsap is still alive. On the other hand, we can't be in
       * irda_irnet_destroy() otherwise we would not have found this
       * socket in the hashbin.
       * Jean II */
      if((test_bit(0, &new->ttp_connect)) || (new->tsap != NULL))
	{
	  /* Don't mess this socket, somebody else in in charge... */
	  DERROR(IRDA_CB_ERROR, "Race condition detected, socket in use, abort connect...\n");
	  irnet_disconnect_server(server, skb);
	  return;
	}
    }

  /* So : at this point, we have a socket, and it is idle. Good ! */
  irnet_connect_socket(server, new, qos, max_sdu_size, max_header_size);

  /* Check size of received packet */
  if(skb->len > 0)
    {
#ifdef PASS_CONNECT_PACKETS
      DEBUG(IRDA_CB_INFO, "Passing connect packet to PPP.\n");
      /* Try to pass it to PPP */
      irnet_data_indication(new, new->tsap, skb);
#else /* PASS_CONNECT_PACKETS */
      DERROR(IRDA_CB_ERROR, "Dropping non empty packet.\n");
      kfree_skb(skb);	/* Note : will be optimised with other kfree... */
#endif /* PASS_CONNECT_PACKETS */
    }
  else
    kfree_skb(skb);

  DEXIT(IRDA_TCB_TRACE, "\n");
}


/********************** IRDA-IAS/LMP CALLBACKS **********************/
/*
 * These are the callbacks called by other layers of the IrDA stack,
 * mainly LMP for discovery and IAS for name queries.
 */

/*------------------------------------------------------------------*/
/*
 * Function irnet_getvalue_confirm (result, obj_id, value, priv)
 *
 *    Got answer from remote LM-IAS, just connect
 *
 * This is the reply to a IAS query we were doing to find the TSAP of
 * the device we want to connect to.
 * If we have found a valid TSAP, just initiate the TTP connection
 * on this TSAP.
 */
static void
irnet_getvalue_confirm(int	result,
		       __u16	obj_id,
		       struct ias_value *value,
		       void *	priv)
{
  irnet_socket *	self = (irnet_socket *) priv;

  DENTER(IRDA_OCB_TRACE, "(self=0x%p)\n", self);
  DASSERT(self != NULL, , IRDA_OCB_ERROR, "Self is NULL !!!\n");

  /* Check if already connected (via irnet_connect_socket())
   * or socket is closing down (via irda_irnet_destroy()) */
  if(! test_bit(0, &self->ttp_connect))
    {
      DERROR(IRDA_OCB_ERROR, "Socket no longer connecting. Ouch !\n");
      return;
    }

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

  /* Post process the IAS reply */
  self->dtsap_sel = irnet_ias_to_tsap(self, result, value);

  /* If error, just go out */
  if(self->errno)
    {
      clear_bit(0, &self->ttp_connect);
      DERROR(IRDA_OCB_ERROR, "IAS connect failed ! (0x%X)\n", self->errno);
      return;
    }

  DEBUG(IRDA_OCB_INFO, "daddr = %08x, lsap = %d, starting IrTTP connection\n",
	self->daddr, self->dtsap_sel);

  /* Start up TTP - non blocking */
  irnet_connect_tsap(self);

  DEXIT(IRDA_OCB_TRACE, "\n");
}

/*------------------------------------------------------------------*/
/*
 * Function irnet_discovervalue_confirm (result, obj_id, value, priv)
 *
 *    Handle the TSAP discovery procedure state machine.
 *    Got answer from remote LM-IAS, try next device
 *
 * We are doing a  TSAP discovery procedure, and we got an answer to
 * a IAS query we were doing to find the TSAP on one of the address
 * in the discovery log.
 *
 * If we have found a valid TSAP for the first time, save it. If it's
 * not the first time we found one, complain.
 *
 * If we have more addresses in the log, just initiate a new query.
 * Note that those query may fail (see irnet_discover_daddr_and_lsap_sel())
 *
 * Otherwise, wrap up the procedure (cleanup), check if we have found
 * any device and connect to it.
 */
static void
irnet_discovervalue_confirm(int		result,
			    __u16	obj_id,
			    struct ias_value *value,
			    void *	priv)
{
  irnet_socket *	self = (irnet_socket *) priv;
  __u8			dtsap_sel;		/* TSAP we are looking for */

  DENTER(IRDA_OCB_TRACE, "(self=0x%p)\n", self);
  DASSERT(self != NULL, , IRDA_OCB_ERROR, "Self is NULL !!!\n");

  /* Check if already connected (via irnet_connect_socket())
   * or socket is closing down (via irda_irnet_destroy()) */
  if(! test_bit(0, &self->ttp_connect))
    {
      DERROR(IRDA_OCB_ERROR, "Socket no longer connecting. Ouch !\n");
      return;
    }

  /* Post process the IAS reply */
  dtsap_sel = irnet_ias_to_tsap(self, result, value);

  /* Have we got something ? */
  if(self->errno == 0)
    {
      /* We found the requested service */
      if(self->daddr != DEV_ADDR_ANY)
	{
	  DERROR(IRDA_OCB_ERROR, "More than one device in range supports IrNET...\n");
	}
      else
	{
	  /* First time we found that one, save it ! */
	  self->daddr = self->discoveries[self->disco_index].daddr;
	  self->dtsap_sel = dtsap_sel;
	}
    }

  /* If no failure */
  if((self->errno == -EADDRNOTAVAIL) || (self->errno == 0))
    {
      int	ret;

      /* Search the next node */
      ret = irnet_discover_next_daddr(self);
      if(!ret)
	{
	  /* In this case, the above request was non-blocking.
	   * We will return here after a while... */
	  return;
	}
      /* In this case, we have processed the last discovery item */
    }

  /* No more queries to be done (failure or last one) */

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

  /* No more items : remove the log and signal termination */
  DEBUG(IRDA_OCB_INFO, "Cleaning up log (0x%p)\n",
	self->discoveries);
  if(self->discoveries != NULL)
    {
      /* Cleanup our copy of the discovery log */
      kfree(self->discoveries);
      self->discoveries = NULL;
    }
  self->disco_number = -1;

  /* Check out what we found */
  if(self->daddr == DEV_ADDR_ANY)
    {
      self->daddr = DEV_ADDR_ANY;
      clear_bit(0, &self->ttp_connect);
      DEXIT(IRDA_OCB_TRACE, ": cannot discover IrNET in any device !!!\n");
      return;
    }

  /* We have a valid address - just connect */

  DEBUG(IRDA_OCB_INFO, "daddr = %08x, lsap = %d, starting IrTTP connection\n",
	self->daddr, self->dtsap_sel);

  /* Start up TTP - non blocking */
  irnet_connect_tsap(self);

  DEXIT(IRDA_OCB_TRACE, "\n");
}

#ifdef DISCOVERY_EVENTS
/*------------------------------------------------------------------*/
/*
 * Function irnet_discovery_indication (discovery)
 *
 *    Got a discovery indication from IrLMP, post an event
 *
 * Note : IrLMP take care of matching the hint mask for us, and also
 * check if it is a "new" node for us...
 *
 * As IrLMP filter on the IrLAN hint bit, we get both IrLAN and IrNET
 * nodes, so it's only at connection time that we will know if the
 * node support IrNET, IrLAN or both. The other solution is to check
 * in IAS the PNP ids and service name.
 * Note : even if a node support IrNET (or IrLAN), it's no guarantee
 * that we will be able to connect to it, the node might already be
 * busy...
 *
 * One last thing : in some case, this function will trigger duplicate
 * discovery events. On the other hand, we should catch all
 * discoveries properly (i.e. not miss one). Filtering duplicate here
 * is to messy, so we leave that to user space...
 */
static void
irnet_discovery_indication(discinfo_t *		discovery,
			   DISCOVERY_MODE	mode,
			   void *		priv)
{
  irnet_socket *	self = &irnet_server.s;

  DENTER(IRDA_OCB_TRACE, "(self=0x%p)\n", self);
  DASSERT(priv == &irnet_server, , IRDA_OCB_ERROR,
	  "Invalid instance (0x%p) !!!\n", priv);

  DEBUG(IRDA_OCB_INFO, "Discovered new IrNET/IrLAN node %s...\n",
	discovery->info);

  /* Notify the control channel */
  irnet_post_event(NULL, IRNET_DISCOVER,
		   discovery->saddr, discovery->daddr, discovery->info,
		   get_unaligned((__u16 *)discovery->hints));

  DEXIT(IRDA_OCB_TRACE, "\n");
}

/*------------------------------------------------------------------*/
/*
 * Function irnet_expiry_indication (expiry)
 *
 *    Got a expiry indication from IrLMP, post an event
 *
 * Note : IrLMP take care of matching the hint mask for us, we only
 * check if it is a "new" node...
 */
static void
irnet_expiry_indication(discinfo_t *	expiry,
			DISCOVERY_MODE	mode,
			void *		priv)
{
  irnet_socket *	self = &irnet_server.s;

  DENTER(IRDA_OCB_TRACE, "(self=0x%p)\n", self);
  DASSERT(priv == &irnet_server, , IRDA_OCB_ERROR,
	  "Invalid instance (0x%p) !!!\n", priv);

  DEBUG(IRDA_OCB_INFO, "IrNET/IrLAN node %s expired...\n",
	expiry->info);

  /* Notify the control channel */
  irnet_post_event(NULL, IRNET_EXPIRE,
		   expiry->saddr, expiry->daddr, expiry->info,
		   get_unaligned((__u16 *)expiry->hints));

  DEXIT(IRDA_OCB_TRACE, "\n");
}
#endif /* DISCOVERY_EVENTS */


/*********************** PROC ENTRY CALLBACKS ***********************/
/*
 * We create a instance in the /proc filesystem, and here we take care
 * of that...
 */

#ifdef CONFIG_PROC_FS
static int
irnet_proc_show(struct seq_file *m, void *v)
{
  irnet_socket *	self;
  char *		state;
  int			i = 0;

  /* Get the IrNET server information... */
  seq_printf(m, "IrNET server - ");
  seq_printf(m, "IrDA state: %s, ",
		 (irnet_server.running ? "running" : "dead"));
  seq_printf(m, "stsap_sel: %02x, ", irnet_server.s.stsap_sel);
  seq_printf(m, "dtsap_sel: %02x\n", irnet_server.s.dtsap_sel);

  /* Do we need to continue ? */
  if(!irnet_server.running)
    return 0;

  /* Protect access to the instance list */
  spin_lock_bh(&irnet_server.spinlock);

  /* Get the sockets one by one... */
  self = (irnet_socket *) hashbin_get_first(irnet_server.list);
  while(self != NULL)
    {
      /* Start printing info about the socket. */
      seq_printf(m, "\nIrNET socket %d - ", i++);

      /* First, get the requested configuration */
      seq_printf(m, "Requested IrDA name: \"%s\", ", self->rname);
      seq_printf(m, "daddr: %08x, ", self->rdaddr);
      seq_printf(m, "saddr: %08x\n", self->rsaddr);

      /* Second, get all the PPP info */
      seq_printf(m, "	PPP state: %s",
		 (self->ppp_open ? "registered" : "unregistered"));
      if(self->ppp_open)
	{
	  seq_printf(m, ", unit: ppp%d",
			 ppp_unit_number(&self->chan));
	  seq_printf(m, ", channel: %d",
			 ppp_channel_index(&self->chan));
	  seq_printf(m, ", mru: %d",
			 self->mru);
	  /* Maybe add self->flags ? Later... */
	}

      /* Then, get all the IrDA specific info... */
      if(self->ttp_open)
	state = "connected";
      else
	if(self->tsap != NULL)
	  state = "connecting";
	else
	  if(self->iriap != NULL)
	    state = "searching";
	  else
	    if(self->ttp_connect)
	      state = "weird";
	    else
	      state = "idle";
      seq_printf(m, "\n	IrDA state: %s, ", state);
      seq_printf(m, "daddr: %08x, ", self->daddr);
      seq_printf(m, "stsap_sel: %02x, ", self->stsap_sel);
      seq_printf(m, "dtsap_sel: %02x\n", self->dtsap_sel);

      /* Next socket, please... */
      self = (irnet_socket *) hashbin_get_next(irnet_server.list);
    }

  /* Spin lock end */
  spin_unlock_bh(&irnet_server.spinlock);

  return 0;
}

static int irnet_proc_open(struct inode *inode, struct file *file)
{
	return single_open(file, irnet_proc_show, NULL);
}

static const struct file_operations irnet_proc_fops = {
	.owner		= THIS_MODULE,
	.open		= irnet_proc_open,
	.read		= seq_read,
	.llseek		= seq_lseek,
	.release	= single_release,
};
#endif /* PROC_FS */


/********************** CONFIGURATION/CLEANUP **********************/
/*
 * Initialisation and teardown of the IrDA part, called at module
 * insertion and removal...
 */

/*------------------------------------------------------------------*/
/*
 * Prepare the IrNET layer for operation...
 */
int __init
irda_irnet_init(void)
{
  int		err = 0;

  DENTER(MODULE_TRACE, "()\n");

  /* Pure paranoia - should be redundant */
  memset(&irnet_server, 0, sizeof(struct irnet_root));

  /* Setup start of irnet instance list */
  irnet_server.list = hashbin_new(HB_NOLOCK);
  DABORT(irnet_server.list == NULL, -ENOMEM,
	 MODULE_ERROR, "Can't allocate hashbin!\n");
  /* Init spinlock for instance list */
  spin_lock_init(&irnet_server.spinlock);

  /* Initialise control channel */
  init_waitqueue_head(&irnet_events.rwait);
  irnet_events.index = 0;
  /* Init spinlock for event logging */
  spin_lock_init(&irnet_events.spinlock);

#ifdef CONFIG_PROC_FS
  /* Add a /proc file for irnet infos */
  proc_create("irnet", 0, proc_irda, &irnet_proc_fops);
#endif /* CONFIG_PROC_FS */

  /* Setup the IrNET server */
  err = irnet_setup_server();

  if(!err)
    /* We are no longer functional... */
    irnet_server.running = 1;

  DEXIT(MODULE_TRACE, "\n");
  return err;
}

/*------------------------------------------------------------------*/
/*
 * Cleanup at exit...
 */
void __exit
irda_irnet_cleanup(void)
{
  DENTER(MODULE_TRACE, "()\n");

  /* We are no longer there... */
  irnet_server.running = 0;

#ifdef CONFIG_PROC_FS
  /* Remove our /proc file */
  remove_proc_entry("irnet", proc_irda);
#endif /* CONFIG_PROC_FS */

  /* Remove our IrNET server from existence */
  irnet_destroy_server();

  /* Remove all instances of IrNET socket still present */
  hashbin_delete(irnet_server.list, (FREE_FUNC) irda_irnet_destroy);

  DEXIT(MODULE_TRACE, "\n");
}
