kernels/linux-2.4.0/net/irda/irnet/irnet_irda.c
/*------------------------------------------------------------------*/
/*
 * Function irnet_discover_daddr_and_lsap_sel (self)
 *
 *    This try to find a device with the requested service.
 *
 * 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).
 * The, we set both the destination address and the lsap selector to point
 * on the service on the unique device we have found.
 *
 * Note : this function fails if there is more than one device in range,
 * because IrLMP doesn't disconnect the LAP when the last LSAP is closed.
 * Moreover, we would need to wait the LAP disconnection...
 */
Function irnet_discover_daddr_and_lsap_sel (self)
This try to find a device with the requested service.

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).
The, we set both the destination address and the lsap selector to point
on the service on the unique device we have found.

Note : this function fails if there is more than one device in range,
because IrLMP doesn't disconnect the LAP when the last LSAP is closed.
Moreover, we would need to wait the LAP disconnection
Function irnet_discover_daddr_and_lsap_sel ( self ) This try to find a device with the requested service . 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 ) . The we set both the destination address and the lsap selector to point on the service on the unique device we have found . Note : this function fails if there is more than one device in range 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)
{
  struct irda_device_info *discoveries;	
  int	number;			
  int	i;
  int	err = -ENETUNREACH;
  __u32	daddr = DEV_ADDR_ANY;	
  __u8	dtsap_sel = 0x0;	
  DENTER(IRDA_SR_TRACE, "(self=0x%X)\n", (unsigned int) self);
  discoveries = irlmp_get_discoveries(&number, self->mask);
  if (discoveries == NULL)
    DRETURN(-ENETUNREACH, IRDA_SR_INFO, "Cachelog empty...\n");
  for(i = 0; i < number; i++)
    {
      self->daddr = discoveries[i].daddr;
      self->saddr = 0x0;
      DEBUG(IRDA_SR_INFO, "trying daddr = %08x\n", self->daddr);
      err = irnet_find_lsap_sel(self);
      switch(err)
	{
	case 0:
	  if(daddr != DEV_ADDR_ANY)
	    {
	      DEBUG(IRDA_SR_INFO, "More than one device in range supports IrNET...\n");
	    }
	  else
	    {
	      daddr = self->daddr;
	      dtsap_sel = self->dtsap_sel;
	    }
	  break;
	case -EADDRNOTAVAIL:
	  break;
	default:
	  DERROR(IRDA_SR_ERROR, "unexpected IAS query failure\n");
	  self->daddr = DEV_ADDR_ANY;
	  kfree(discoveries);
	  return(-EHOSTUNREACH);
	  break;
	}
    }
  kfree(discoveries);
  if(daddr == DEV_ADDR_ANY)
    {
      self->daddr = DEV_ADDR_ANY;
      DEXIT(IRDA_SR_INFO, "cannot discover IrNET in any device !!!\n");
      return(-EADDRNOTAVAIL);
    }
  self->daddr = daddr;
  self->saddr = 0x0;
  self->dtsap_sel = dtsap_sel;
  DEBUG(IRDA_SR_INFO, "discovered IrNET at address %08x\n", self->daddr);
  DEXIT(IRDA_SR_TRACE, "\n");
  return 0;
}
static inline int irnet_discover_daddr_and_lsap_sel ( irnet_socket * self ) { struct irda_device_info * discoveries ; int number ; int i ; int err = - ENETUNREACH ; __u32 daddr = DEV_ADDR_ANY ; __u8 dtsap_sel = 0x0 ; DENTER ( IRDA_SR_TRACE , " \n " , ( unsigned int ) self ) ; discoveries = irlmp_get_discoveries ( & number , self -> mask ) ; if ( discoveries == NULL ) DRETURN ( - ENETUNREACH , IRDA_SR_INFO , " \n " ) ; for ( i = 0 ; i < number ; i ++ ) { self -> daddr = discoveries [ i ] . daddr ; self -> saddr = 0x0 ; DEBUG ( IRDA_SR_INFO , " \n " , self -> daddr ) ; err = irnet_find_lsap_sel ( self ) ; switch ( err ) { case 0 : if ( daddr != DEV_ADDR_ANY ) { DEBUG ( IRDA_SR_INFO , " \n " ) ; } else { daddr = self -> daddr ; dtsap_sel = self -> dtsap_sel ; } break ; case - EADDRNOTAVAIL : break ; default : DERROR ( IRDA_SR_ERROR , " \n " ) ; self -> daddr = DEV_ADDR_ANY ; kfree ( discoveries ) ; return ( - EHOSTUNREACH ) ; break ; } } kfree ( discoveries ) ; if ( daddr == DEV_ADDR_ANY ) { self -> daddr = DEV_ADDR_ANY ; DEXIT ( IRDA_SR_INFO , " \n " ) ; return ( - EADDRNOTAVAIL ) ; } self -> daddr = daddr ; self -> saddr = 0x0 ; self -> dtsap_sel = dtsap_sel ; DEBUG ( IRDA_SR_INFO , " \n " , self -> daddr ) ; DEXIT ( IRDA_SR_TRACE , " \n " ) ; return 0 ; }
Function irnet_discover_daddr_and_lsap_sel (self)
    This try to find a device with the requested service.
Function irnet_discover_daddr_and_lsap_sel ( self ) This try to find a device with the requested service .
/* Copy of the discovery log */ /* Number of nodes in the log */ /* Address we found the service on */ /* TSAP associated with it */ /* Ask lmp for the current discovery log
   * Note : we have to use irlmp_get_discoveries(), as opposed
   * to play with the cachelog directly, because while we are
   * making our ias query, le log might change... */ /* Check if the we got some results */ /* 
   * Now, check all discovered devices (if any), and connect
   * client only about the services that the client is
   * interested in...
   */ /* Try the address in the log */ /* Query remote LM-IAS for this service */ /* We found the requested service */ /* First time we found that one, save it ! */ /* Requested service simply doesn't exist on this node */ /* Something bad did happen :-( */ /* Cleanup our copy of the discovery log */ /* Check out what we found */ /* Revert back to discovered device & service */