linux/net/irda/irnet/irnet_irda.c
<<
>>
Prefs
   1/*
   2 *      IrNET protocol module : Synchronous PPP over an IrDA socket.
   3 *
   4 *              Jean II - HPL `00 - <jt@hpl.hp.com>
   5 *
   6 * This file implement the IRDA interface of IrNET.
   7 * Basically, we sit on top of IrTTP. We set up IrTTP, IrIAS properly,
   8 * and exchange frames with IrTTP.
   9 */
  10
  11#include "irnet_irda.h"         /* Private header */
  12#include <linux/seq_file.h>
  13#include <asm/unaligned.h>
  14
  15/*
  16 * PPP disconnect work: we need to make sure we're in
  17 * process context when calling ppp_unregister_channel().
  18 */
  19static void irnet_ppp_disconnect(struct work_struct *work)
  20{
  21        irnet_socket * self =
  22                container_of(work, irnet_socket, disconnect_work);
  23
  24        if (self == NULL)
  25                return;
  26        /*
  27         * If we were connected, cleanup & close the PPP
  28         * channel, which will kill pppd (hangup) and the rest.
  29         */
  30        if (self->ppp_open && !self->ttp_open && !self->ttp_connect) {
  31                ppp_unregister_channel(&self->chan);
  32                self->ppp_open = 0;
  33        }
  34}
  35
  36/************************* CONTROL CHANNEL *************************/
  37/*
  38 * When ppp is not active, /dev/irnet act as a control channel.
  39 * Writing allow to set up the IrDA destination of the IrNET channel,
  40 * and any application may be read events happening on IrNET...
  41 */
  42
  43/*------------------------------------------------------------------*/
  44/*
  45 * Post an event to the control channel...
  46 * Put the event in the log, and then wait all process blocked on read
  47 * so they can read the log...
  48 */
  49static void
  50irnet_post_event(irnet_socket * ap,
  51                 irnet_event    event,
  52                 __u32          saddr,
  53                 __u32          daddr,
  54                 char *         name,
  55                 __u16          hints)
  56{
  57  int                   index;          /* In the log */
  58
  59  DENTER(CTRL_TRACE, "(ap=0x%p, event=%d, daddr=%08x, name=``%s'')\n",
  60         ap, event, daddr, name);
  61
  62  /* Protect this section via spinlock.
  63   * Note : as we are the only event producer, we only need to exclude
  64   * ourself when touching the log, which is nice and easy.
  65   */
  66  spin_lock_bh(&irnet_events.spinlock);
  67
  68  /* Copy the event in the log */
  69  index = irnet_events.index;
  70  irnet_events.log[index].event = event;
  71  irnet_events.log[index].daddr = daddr;
  72  irnet_events.log[index].saddr = saddr;
  73  /* Try to copy IrDA nickname */
  74  if(name)
  75    strcpy(irnet_events.log[index].name, name);
  76  else
  77    irnet_events.log[index].name[0] = '\0';
  78  /* Copy hints */
  79  irnet_events.log[index].hints.word = hints;
  80  /* Try to get ppp unit number */
  81  if((ap != (irnet_socket *) NULL) && (ap->ppp_open))
  82    irnet_events.log[index].unit = ppp_unit_number(&ap->chan);
  83  else
  84    irnet_events.log[index].unit = -1;
  85
  86  /* Increment the index
  87   * Note that we increment the index only after the event is written,
  88   * to make sure that the readers don't get garbage... */
  89  irnet_events.index = (index + 1) % IRNET_MAX_EVENTS;
  90
  91  DEBUG(CTRL_INFO, "New event index is %d\n", irnet_events.index);
  92
  93  /* Spin lock end */
  94  spin_unlock_bh(&irnet_events.spinlock);
  95
  96  /* Now : wake up everybody waiting for events... */
  97  wake_up_interruptible_all(&irnet_events.rwait);
  98
  99  DEXIT(CTRL_TRACE, "\n");
 100}
 101
 102/************************* IRDA SUBROUTINES *************************/
 103/*
 104 * These are a bunch of subroutines called from other functions
 105 * down there, mostly common code or to improve readability...
 106 *
 107 * Note : we duplicate quite heavily some routines of af_irda.c,
 108 * because our input structure (self) is quite different
 109 * (struct irnet instead of struct irda_sock), which make sharing
 110 * the same code impossible (at least, without templates).
 111 */
 112
 113/*------------------------------------------------------------------*/
 114/*
 115 * Function irda_open_tsap (self)
 116 *
 117 *    Open local Transport Service Access Point (TSAP)
 118 *
 119 * Create a IrTTP instance for us and set all the IrTTP callbacks.
 120 */
 121static inline int
 122irnet_open_tsap(irnet_socket *  self)
 123{
 124  notify_t      notify;         /* Callback structure */
 125
 126  DENTER(IRDA_SR_TRACE, "(self=0x%p)\n", self);
 127
 128  DABORT(self->tsap != NULL, -EBUSY, IRDA_SR_ERROR, "Already busy !\n");
 129
 130  /* Initialize IrTTP callbacks to be used by the IrDA stack */
 131  irda_notify_init(&notify);
 132  notify.connect_confirm        = irnet_connect_confirm;
 133  notify.connect_indication     = irnet_connect_indication;
 134  notify.disconnect_indication  = irnet_disconnect_indication;
 135  notify.data_indication        = irnet_data_indication;
 136  /*notify.udata_indication     = NULL;*/
 137  notify.flow_indication        = irnet_flow_indication;
 138  notify.status_indication      = irnet_status_indication;
 139  notify.instance               = self;
 140  strlcpy(notify.name, IRNET_NOTIFY_NAME, sizeof(notify.name));
 141
 142  /* Open an IrTTP instance */
 143  self->tsap = irttp_open_tsap(LSAP_ANY, DEFAULT_INITIAL_CREDIT,
 144                               &notify);
 145  DABORT(self->tsap == NULL, -ENOMEM,
 146         IRDA_SR_ERROR, "Unable to allocate TSAP !\n");
 147
 148  /* Remember which TSAP selector we actually got */
 149  self->stsap_sel = self->tsap->stsap_sel;
 150
 151  DEXIT(IRDA_SR_TRACE, " - tsap=0x%p, sel=0x%X\n",
 152        self->tsap, self->stsap_sel);
 153  return 0;
 154}
 155
 156/*------------------------------------------------------------------*/
 157/*
 158 * Function irnet_ias_to_tsap (self, result, value)
 159 *
 160 *    Examine an IAS object and extract TSAP
 161 *
 162 * We do an IAP query to find the TSAP associated with the IrNET service.
 163 * When IrIAP pass us the result of the query, this function look at
 164 * the return values to check for failures and extract the TSAP if
 165 * possible.
 166 * Also deallocate value
 167 * The failure is in self->errno
 168 * Return TSAP or -1
 169 */
 170static inline __u8
 171irnet_ias_to_tsap(irnet_socket *        self,
 172                  int                   result,
 173                  struct ias_value *    value)
 174{
 175  __u8  dtsap_sel = 0;          /* TSAP we are looking for */
 176
 177  DENTER(IRDA_SR_TRACE, "(self=0x%p)\n", self);
 178
 179  /* By default, no error */
 180  self->errno = 0;
 181
 182  /* Check if request succeeded */
 183  switch(result)
 184    {
 185      /* Standard errors : service not available */
 186    case IAS_CLASS_UNKNOWN:
 187    case IAS_ATTRIB_UNKNOWN:
 188      DEBUG(IRDA_SR_INFO, "IAS object doesn't exist ! (%d)\n", result);
 189      self->errno = -EADDRNOTAVAIL;
 190      break;
 191
 192      /* Other errors, most likely IrDA stack failure */
 193    default :
 194      DEBUG(IRDA_SR_INFO, "IAS query failed ! (%d)\n", result);
 195      self->errno = -EHOSTUNREACH;
 196      break;
 197
 198      /* Success : we got what we wanted */
 199    case IAS_SUCCESS:
 200      break;
 201    }
 202
 203  /* Check what was returned to us */
 204  if(value != NULL)
 205    {
 206      /* What type of argument have we got ? */
 207      switch(value->type)
 208        {
 209        case IAS_INTEGER:
 210          DEBUG(IRDA_SR_INFO, "result=%d\n", value->t.integer);
 211          if(value->t.integer != -1)
 212            /* Get the remote TSAP selector */
 213            dtsap_sel = value->t.integer;
 214          else
 215            self->errno = -EADDRNOTAVAIL;
 216          break;
 217        default:
 218          self->errno = -EADDRNOTAVAIL;
 219          DERROR(IRDA_SR_ERROR, "bad type ! (0x%X)\n", value->type);
 220          break;
 221        }
 222
 223      /* Cleanup */
 224      irias_delete_value(value);
 225    }
 226  else  /* value == NULL */
 227    {
 228      /* Nothing returned to us - usually result != SUCCESS */
 229      if(!(self->errno))
 230        {
 231          DERROR(IRDA_SR_ERROR,
 232                 "IrDA bug : result == SUCCESS && value == NULL\n");
 233          self->errno = -EHOSTUNREACH;
 234        }
 235    }
 236  DEXIT(IRDA_SR_TRACE, "\n");
 237
 238  /* Return the TSAP */
 239  return(dtsap_sel);
 240}
 241
 242/*------------------------------------------------------------------*/
 243/*
 244 * Function irnet_find_lsap_sel (self)
 245 *
 246 *    Try to lookup LSAP selector in remote LM-IAS
 247 *
 248 * Basically, we start a IAP query, and then go to sleep. When the query
 249 * return, irnet_getvalue_confirm will wake us up, and we can examine the
 250 * result of the query...
 251 * Note that in some case, the query fail even before we go to sleep,
 252 * creating some races...
 253 */
 254static inline int
 255irnet_find_lsap_sel(irnet_socket *      self)
 256{
 257  DENTER(IRDA_SR_TRACE, "(self=0x%p)\n", self);
 258
 259  /* This should not happen */
 260  DABORT(self->iriap, -EBUSY, IRDA_SR_ERROR, "busy with a previous query.\n");
 261
 262  /* Create an IAP instance, will be closed in irnet_getvalue_confirm() */
 263  self->iriap = iriap_open(LSAP_ANY, IAS_CLIENT, self,
 264                           irnet_getvalue_confirm);
 265
 266  /* Treat unexpected signals as disconnect */
 267  self->errno = -EHOSTUNREACH;
 268
 269  /* Query remote LM-IAS */
 270  iriap_getvaluebyclass_request(self->iriap, self->rsaddr, self->daddr,
 271                                IRNET_SERVICE_NAME, IRNET_IAS_VALUE);
 272
 273  /* The above request is non-blocking.
 274   * After a while, IrDA will call us back in irnet_getvalue_confirm()
 275   * We will then call irnet_ias_to_tsap() and finish the
 276   * connection procedure */
 277
 278  DEXIT(IRDA_SR_TRACE, "\n");
 279  return 0;
 280}
 281
 282/*------------------------------------------------------------------*/
 283/*
 284 * Function irnet_connect_tsap (self)
 285 *
 286 *    Initialise the TTP socket and initiate TTP connection
 287 *
 288 */
 289static inline int
 290irnet_connect_tsap(irnet_socket *       self)
 291{
 292  int           err;
 293
 294  DENTER(IRDA_SR_TRACE, "(self=0x%p)\n", self);
 295
 296  /* Open a local TSAP (an IrTTP instance) */
 297  err = irnet_open_tsap(self);
 298  if(err != 0)
 299    {
 300      clear_bit(0, &self->ttp_connect);
 301      DERROR(IRDA_SR_ERROR, "connect aborted!\n");
 302      return(err);
 303    }
 304
 305  /* Connect to remote device */
 306  err = irttp_connect_request(self->tsap, self->dtsap_sel,
 307                              self->rsaddr, self->daddr, NULL,
 308                              self->max_sdu_size_rx, NULL);
 309  if(err != 0)
 310    {
 311      clear_bit(0, &self->ttp_connect);
 312      DERROR(IRDA_SR_ERROR, "connect aborted!\n");
 313      return(err);
 314    }
 315
 316  /* The above call is non-blocking.
 317   * After a while, the IrDA stack will either call us back in
 318   * irnet_connect_confirm() or irnet_disconnect_indication()
 319   * See you there ;-) */
 320
 321  DEXIT(IRDA_SR_TRACE, "\n");
 322  return(err);
 323}
 324
 325/*------------------------------------------------------------------*/
 326/*
 327 * Function irnet_discover_next_daddr (self)
 328 *
 329 *    Query the IrNET TSAP of the next device in the log.
 330 *
 331 * Used in the TSAP discovery procedure.
 332 */
 333static inline int
 334irnet_discover_next_daddr(irnet_socket *        self)
 335{
 336  /* Close the last instance of IrIAP, and open a new one.
 337   * We can't reuse the IrIAP instance in the IrIAP callback */
 338  if(self->iriap)
 339    {
 340      iriap_close(self->iriap);
 341      self->iriap = NULL;
 342    }
 343  /* Create a new IAP instance */
 344  self->iriap = iriap_open(LSAP_ANY, IAS_CLIENT, self,
 345                           irnet_discovervalue_confirm);
 346  if(self->iriap == NULL)
 347    return -ENOMEM;
 348
 349  /* Next discovery - before the call to avoid races */
 350  self->disco_index++;
 351
 352  /* Check if we have one more address to try */
 353  if(self->disco_index < self->disco_number)
 354    {
 355      /* Query remote LM-IAS */
 356      iriap_getvaluebyclass_request(self->iriap,
 357                                    self->discoveries[self->disco_index].saddr,
 358                                    self->discoveries[self->disco_index].daddr,
 359                                    IRNET_SERVICE_NAME, IRNET_IAS_VALUE);
 360      /* The above request is non-blocking.
 361       * After a while, IrDA will call us back in irnet_discovervalue_confirm()
 362       * We will then call irnet_ias_to_tsap() and come back here again... */
 363      return(0);
 364    }
 365  else
 366    return(1);
 367}
 368
 369/*------------------------------------------------------------------*/
 370/*
 371 * Function irnet_discover_daddr_and_lsap_sel (self)
 372 *
 373 *    This try to find a device with the requested service.
 374 *
 375 * Initiate a TSAP discovery procedure.
 376 * It basically look into the discovery log. For each address in the list,
 377 * it queries the LM-IAS of the device to find if this device offer
 378 * the requested service.
 379 * If there is more than one node supporting the service, we complain
 380 * to the user (it should move devices around).
 381 * If we find one node which have the requested TSAP, we connect to it.
 382 *
 383 * This function just start the whole procedure. It request the discovery
 384 * log and submit the first IAS query.
 385 * The bulk of the job is handled in irnet_discovervalue_confirm()
 386 *
 387 * Note : this procedure fails if there is more than one device in range
 388 * on the same dongle, because IrLMP doesn't disconnect the LAP when the
 389 * last LSAP is closed. Moreover, we would need to wait the LAP
 390 * disconnection...
 391 */
 392static inline int
 393irnet_discover_daddr_and_lsap_sel(irnet_socket *        self)
 394{
 395  int   ret;
 396
 397  DENTER(IRDA_SR_TRACE, "(self=0x%p)\n", self);
 398
 399  /* Ask lmp for the current discovery log */
 400  self->discoveries = irlmp_get_discoveries(&self->disco_number, self->mask,
 401                                            DISCOVERY_DEFAULT_SLOTS);
 402
 403  /* Check if the we got some results */
 404  if(self->discoveries == NULL)
 405    {
 406      self->disco_number = -1;
 407      clear_bit(0, &self->ttp_connect);
 408      DRETURN(-ENETUNREACH, IRDA_SR_INFO, "No Cachelog...\n");
 409    }
 410  DEBUG(IRDA_SR_INFO, "Got the log (0x%p), size is %d\n",
 411        self->discoveries, self->disco_number);
 412
 413  /* Start with the first discovery */
 414  self->disco_index = -1;
 415  self->daddr = DEV_ADDR_ANY;
 416
 417  /* This will fail if the log is empty - this is non-blocking */
 418  ret = irnet_discover_next_daddr(self);
 419  if(ret)
 420    {
 421      /* Close IAP */
 422      if(self->iriap)
 423        iriap_close(self->iriap);
 424      self->iriap = NULL;
 425
 426      /* Cleanup our copy of the discovery log */
 427      kfree(self->discoveries);
 428      self->discoveries = NULL;
 429
 430      clear_bit(0, &self->ttp_connect);
 431      DRETURN(-ENETUNREACH, IRDA_SR_INFO, "Cachelog empty...\n");
 432    }
 433
 434  /* Follow me in irnet_discovervalue_confirm() */
 435
 436  DEXIT(IRDA_SR_TRACE, "\n");
 437  return(0);
 438}
 439
 440/*------------------------------------------------------------------*/
 441/*
 442 * Function irnet_dname_to_daddr (self)
 443 *
 444 *    Convert an IrDA nickname to a valid IrDA address
 445 *
 446 * It basically look into the discovery log until there is a match.
 447 */
 448static inline int
 449irnet_dname_to_daddr(irnet_socket *     self)
 450{
 451  struct irda_device_info *discoveries; /* Copy of the discovery log */
 452  int   number;                 /* Number of nodes in the log */
 453  int   i;
 454
 455  DENTER(IRDA_SR_TRACE, "(self=0x%p)\n", self);
 456
 457  /* Ask lmp for the current discovery log */
 458  discoveries = irlmp_get_discoveries(&number, 0xffff,
 459                                      DISCOVERY_DEFAULT_SLOTS);
 460  /* Check if the we got some results */
 461  if(discoveries == NULL)
 462    DRETURN(-ENETUNREACH, IRDA_SR_INFO, "Cachelog empty...\n");
 463
 464  /*
 465   * Now, check all discovered devices (if any), and connect
 466   * client only about the services that the client is
 467   * interested in...
 468   */
 469  for(i = 0; i < number; i++)
 470    {
 471      /* Does the name match ? */
 472      if(!strncmp(discoveries[i].info, self->rname, NICKNAME_MAX_LEN))
 473        {
 474          /* Yes !!! Get it.. */
 475          self->daddr = discoveries[i].daddr;
 476          DEBUG(IRDA_SR_INFO, "discovered device ``%s'' at address 0x%08x.\n",
 477                self->rname, self->daddr);
 478          kfree(discoveries);
 479          DEXIT(IRDA_SR_TRACE, "\n");
 480          return 0;
 481        }
 482    }
 483  /* No luck ! */
 484  DEBUG(IRDA_SR_INFO, "cannot discover device ``%s'' !!!\n", self->rname);
 485  kfree(discoveries);
 486  return(-EADDRNOTAVAIL);
 487}
 488
 489
 490/************************* SOCKET ROUTINES *************************/
 491/*
 492 * This are the main operations on IrNET sockets, basically to create
 493 * and destroy IrNET sockets. These are called from the PPP part...
 494 */
 495
 496/*------------------------------------------------------------------*/
 497/*
 498 * Create a IrNET instance : just initialise some parameters...
 499 */
 500int
 501irda_irnet_create(irnet_socket *        self)
 502{
 503  DENTER(IRDA_SOCK_TRACE, "(self=0x%p)\n", self);
 504
 505  self->magic = IRNET_MAGIC;    /* Paranoia */
 506
 507  self->ttp_open = 0;           /* Prevent higher layer from accessing IrTTP */
 508  self->ttp_connect = 0;        /* Not connecting yet */
 509  self->rname[0] = '\0';        /* May be set via control channel */
 510  self->rdaddr = DEV_ADDR_ANY;  /* May be set via control channel */
 511  self->rsaddr = DEV_ADDR_ANY;  /* May be set via control channel */
 512  self->daddr = DEV_ADDR_ANY;   /* Until we get connected */
 513  self->saddr = DEV_ADDR_ANY;   /* Until we get connected */
 514  self->max_sdu_size_rx = TTP_SAR_UNBOUND;
 515
 516  /* Register as a client with IrLMP */
 517  self->ckey = irlmp_register_client(0, NULL, NULL, NULL);
 518#ifdef DISCOVERY_NOMASK
 519  self->mask = 0xffff;          /* For W2k compatibility */
 520#else /* DISCOVERY_NOMASK */
 521  self->mask = irlmp_service_to_hint(S_LAN);
 522#endif /* DISCOVERY_NOMASK */
 523  self->tx_flow = FLOW_START;   /* Flow control from IrTTP */
 524
 525  INIT_WORK(&self->disconnect_work, irnet_ppp_disconnect);
 526
 527  DEXIT(IRDA_SOCK_TRACE, "\n");
 528  return(0);
 529}
 530
 531/*------------------------------------------------------------------*/
 532/*
 533 * Connect to the other side :
 534 *      o convert device name to an address
 535 *      o find the socket number (dlsap)
 536 *      o Establish the connection
 537 *
 538 * Note : We no longer mimic af_irda. The IAS query for finding the TSAP
 539 * is done asynchronously, like the TTP connection. This allow us to
 540 * call this function from any context (not only process).
 541 * The downside is that following what's happening in there is tricky
 542 * because it involve various functions all over the place...
 543 */
 544int
 545irda_irnet_connect(irnet_socket *       self)
 546{
 547  int           err;
 548
 549  DENTER(IRDA_SOCK_TRACE, "(self=0x%p)\n", self);
 550
 551  /* Check if we are already trying to connect.
 552   * Because irda_irnet_connect() can be called directly by pppd plus
 553   * packet retries in ppp_generic and connect may take time, plus we may
 554   * race with irnet_connect_indication(), we need to be careful there... */
 555  if(test_and_set_bit(0, &self->ttp_connect))
 556    DRETURN(-EBUSY, IRDA_SOCK_INFO, "Already connecting...\n");
 557  if((self->iriap != NULL) || (self->tsap != NULL))
 558    DERROR(IRDA_SOCK_ERROR, "Socket not cleaned up...\n");
 559
 560  /* Insert ourselves in the hashbin so that the IrNET server can find us.
 561   * Notes : 4th arg is string of 32 char max and must be null terminated
 562   *         When 4th arg is used (string), 3rd arg isn't (int)
 563   *         Can't re-insert (MUST remove first) so check for that... */
 564  if((irnet_server.running) && (self->q.q_next == NULL))
 565    {
 566      spin_lock_bh(&irnet_server.spinlock);
 567      hashbin_insert(irnet_server.list, (irda_queue_t *) self, 0, self->rname);
 568      spin_unlock_bh(&irnet_server.spinlock);
 569      DEBUG(IRDA_SOCK_INFO, "Inserted ``%s'' in hashbin...\n", self->rname);
 570    }
 571
 572  /* If we don't have anything (no address, no name) */
 573  if((self->rdaddr == DEV_ADDR_ANY) && (self->rname[0] == '\0'))
 574    {
 575      /* Try to find a suitable address */
 576      if((err = irnet_discover_daddr_and_lsap_sel(self)) != 0)
 577        DRETURN(err, IRDA_SOCK_INFO, "auto-connect failed!\n");
 578      /* In most cases, the call above is non-blocking */
 579    }
 580  else
 581    {
 582      /* If we have only the name (no address), try to get an address */
 583      if(self->rdaddr == DEV_ADDR_ANY)
 584        {
 585          if((err = irnet_dname_to_daddr(self)) != 0)
 586            DRETURN(err, IRDA_SOCK_INFO, "name connect failed!\n");
 587        }
 588      else
 589        /* Use the requested destination address */
 590        self->daddr = self->rdaddr;
 591
 592      /* Query remote LM-IAS to find LSAP selector */
 593      irnet_find_lsap_sel(self);
 594      /* The above call is non blocking */
 595    }
 596
 597  /* At this point, we are waiting for the IrDA stack to call us back,
 598   * or we have already failed.
 599   * We will finish the connection procedure in irnet_connect_tsap().
 600   */
 601  DEXIT(IRDA_SOCK_TRACE, "\n");
 602  return(0);
 603}
 604
 605/*------------------------------------------------------------------*/
 606/*
 607 * Function irda_irnet_destroy(self)
 608 *
 609 *    Destroy irnet instance
 610 *
 611 * Note : this need to be called from a process context.
 612 */
 613void
 614irda_irnet_destroy(irnet_socket *       self)
 615{
 616  DENTER(IRDA_SOCK_TRACE, "(self=0x%p)\n", self);
 617  if(self == NULL)
 618    return;
 619
 620  /* Remove ourselves from hashbin (if we are queued in hashbin)
 621   * Note : `irnet_server.running' protect us from calls in hashbin_delete() */
 622  if((irnet_server.running) && (self->q.q_next != NULL))
 623    {
 624      struct irnet_socket *     entry;
 625      DEBUG(IRDA_SOCK_INFO, "Removing from hash..\n");
 626      spin_lock_bh(&irnet_server.spinlock);
 627      entry = hashbin_remove_this(irnet_server.list, (irda_queue_t *) self);
 628      self->q.q_next = NULL;
 629      spin_unlock_bh(&irnet_server.spinlock);
 630      DASSERT(entry == self, , IRDA_SOCK_ERROR, "Can't remove from hash.\n");
 631    }
 632
 633  /* If we were connected, post a message */
 634  if(test_bit(0, &self->ttp_open))
 635    {
 636      /* Note : as the disconnect comes from ppp_generic, the unit number
 637       * doesn't exist anymore when we post the event, so we need to pass
 638       * NULL as the first arg... */
 639      irnet_post_event(NULL, IRNET_DISCONNECT_TO,
 640                       self->saddr, self->daddr, self->rname, 0);
 641    }
 642
 643  /* Prevent various IrDA callbacks from messing up things
 644   * Need to be first */
 645  clear_bit(0, &self->ttp_connect);
 646
 647  /* Prevent higher layer from accessing IrTTP */
 648  clear_bit(0, &self->ttp_open);
 649
 650  /* Unregister with IrLMP */
 651  irlmp_unregister_client(self->ckey);
 652
 653  /* Unregister with LM-IAS */
 654  if(self->iriap)
 655    {
 656      iriap_close(self->iriap);
 657      self->iriap = NULL;
 658    }
 659
 660  /* Cleanup eventual discoveries from connection attempt or control channel */
 661  if(self->discoveries != NULL)
 662    {
 663      /* Cleanup our copy of the discovery log */
 664      kfree(self->discoveries);
 665      self->discoveries = NULL;
 666    }
 667
 668  /* Close our IrTTP connection */
 669  if(self->tsap)
 670    {
 671      DEBUG(IRDA_SOCK_INFO, "Closing our TTP connection.\n");
 672      irttp_disconnect_request(self->tsap, NULL, P_NORMAL);
 673      irttp_close_tsap(self->tsap);
 674      self->tsap = NULL;
 675    }
 676  self->stsap_sel = 0;
 677
 678  DEXIT(IRDA_SOCK_TRACE, "\n");
 679  return;
 680}
 681
 682
 683/************************** SERVER SOCKET **************************/
 684/*
 685 * The IrNET service is composed of one server socket and a variable
 686 * number of regular IrNET sockets. The server socket is supposed to
 687 * handle incoming connections and redirect them to one IrNET sockets.
 688 * It's a superset of the regular IrNET socket, but has a very distinct
 689 * behaviour...
 690 */
 691
 692/*------------------------------------------------------------------*/
 693/*
 694 * Function irnet_daddr_to_dname (self)
 695 *
 696 *    Convert an IrDA address to a IrDA nickname
 697 *
 698 * It basically look into the discovery log until there is a match.
 699 */
 700static inline int
 701irnet_daddr_to_dname(irnet_socket *     self)
 702{
 703  struct irda_device_info *discoveries; /* Copy of the discovery log */
 704  int   number;                 /* Number of nodes in the log */
 705  int   i;
 706
 707  DENTER(IRDA_SERV_TRACE, "(self=0x%p)\n", self);
 708
 709  /* Ask lmp for the current discovery log */
 710  discoveries = irlmp_get_discoveries(&number, 0xffff,
 711                                      DISCOVERY_DEFAULT_SLOTS);
 712  /* Check if the we got some results */
 713  if (discoveries == NULL)
 714    DRETURN(-ENETUNREACH, IRDA_SERV_INFO, "Cachelog empty...\n");
 715
 716  /* Now, check all discovered devices (if any) */
 717  for(i = 0; i < number; i++)
 718    {
 719      /* Does the name match ? */
 720      if(discoveries[i].daddr == self->daddr)
 721        {
 722          /* Yes !!! Get it.. */
 723          strlcpy(self->rname, discoveries[i].info, sizeof(self->rname));
 724          self->rname[sizeof(self->rname) - 1] = '\0';
 725          DEBUG(IRDA_SERV_INFO, "Device 0x%08x is in fact ``%s''.\n",
 726                self->daddr, self->rname);
 727          kfree(discoveries);
 728          DEXIT(IRDA_SERV_TRACE, "\n");
 729          return 0;
 730        }
 731    }
 732  /* No luck ! */
 733  DEXIT(IRDA_SERV_INFO, ": cannot discover device 0x%08x !!!\n", self->daddr);
 734  kfree(discoveries);
 735  return(-EADDRNOTAVAIL);
 736}
 737
 738/*------------------------------------------------------------------*/
 739/*
 740 * Function irda_find_socket (self)
 741 *
 742 *    Find the correct IrNET socket
 743 *
 744 * Look into the list of IrNET sockets and finds one with the right
 745 * properties...
 746 */
 747static inline irnet_socket *
 748irnet_find_socket(irnet_socket *        self)
 749{
 750  irnet_socket *        new = (irnet_socket *) NULL;
 751  int                   err;
 752
 753  DENTER(IRDA_SERV_TRACE, "(self=0x%p)\n", self);
 754
 755  /* Get the addresses of the requester */
 756  self->daddr = irttp_get_daddr(self->tsap);
 757  self->saddr = irttp_get_saddr(self->tsap);
 758
 759  /* Try to get the IrDA nickname of the requester */
 760  err = irnet_daddr_to_dname(self);
 761
 762  /* Protect access to the instance list */
 763  spin_lock_bh(&irnet_server.spinlock);
 764
 765  /* So now, try to get an socket having specifically
 766   * requested that nickname */
 767  if(err == 0)
 768    {
 769      new = (irnet_socket *) hashbin_find(irnet_server.list,
 770                                          0, self->rname);
 771      if(new)
 772        DEBUG(IRDA_SERV_INFO, "Socket 0x%p matches rname ``%s''.\n",
 773              new, new->rname);
 774    }
 775
 776  /* If no name matches, try to find an socket by the destination address */
 777  /* It can be either the requested destination address (set via the
 778   * control channel), or the current destination address if the
 779   * socket is in the middle of a connection request */
 780  if(new == (irnet_socket *) NULL)
 781    {
 782      new = (irnet_socket *) hashbin_get_first(irnet_server.list);
 783      while(new !=(irnet_socket *) NULL)
 784        {
 785          /* Does it have the same address ? */
 786          if((new->rdaddr == self->daddr) || (new->daddr == self->daddr))
 787            {
 788              /* Yes !!! Get it.. */
 789              DEBUG(IRDA_SERV_INFO, "Socket 0x%p matches daddr %#08x.\n",
 790                    new, self->daddr);
 791              break;
 792            }
 793          new = (irnet_socket *) hashbin_get_next(irnet_server.list);
 794        }
 795    }
 796
 797  /* If we don't have any socket, get the first unconnected socket */
 798  if(new == (irnet_socket *) NULL)
 799    {
 800      new = (irnet_socket *) hashbin_get_first(irnet_server.list);
 801      while(new !=(irnet_socket *) NULL)
 802        {
 803          /* Is it available ? */
 804          if(!(test_bit(0, &new->ttp_open)) && (new->rdaddr == DEV_ADDR_ANY) &&
 805             (new->rname[0] == '\0') && (new->ppp_open))
 806            {
 807              /* Yes !!! Get it.. */
 808              DEBUG(IRDA_SERV_INFO, "Socket 0x%p is free.\n",
 809                    new);
 810              break;
 811            }
 812          new = (irnet_socket *) hashbin_get_next(irnet_server.list);
 813        }
 814    }
 815
 816  /* Spin lock end */
 817  spin_unlock_bh(&irnet_server.spinlock);
 818
 819  DEXIT(IRDA_SERV_TRACE, " - new = 0x%p\n", new);
 820  return new;
 821}
 822
 823/*------------------------------------------------------------------*/
 824/*
 825 * Function irda_connect_socket (self)
 826 *
 827 *    Connect an incoming connection to the socket
 828 *
 829 */
 830static inline int
 831irnet_connect_socket(irnet_socket *     server,
 832                     irnet_socket *     new,
 833                     struct qos_info *  qos,
 834                     __u32              max_sdu_size,
 835                     __u8               max_header_size)
 836{
 837  DENTER(IRDA_SERV_TRACE, "(server=0x%p, new=0x%p)\n",
 838         server, new);
 839
 840  /* Now attach up the new socket */
 841  new->tsap = irttp_dup(server->tsap, new);
 842  DABORT(new->tsap == NULL, -1, IRDA_SERV_ERROR, "dup failed!\n");
 843
 844  /* Set up all the relevant parameters on the new socket */
 845  new->stsap_sel = new->tsap->stsap_sel;
 846  new->dtsap_sel = new->tsap->dtsap_sel;
 847  new->saddr = irttp_get_saddr(new->tsap);
 848  new->daddr = irttp_get_daddr(new->tsap);
 849
 850  new->max_header_size = max_header_size;
 851  new->max_sdu_size_tx = max_sdu_size;
 852  new->max_data_size   = max_sdu_size;
 853#ifdef STREAM_COMPAT
 854  /* If we want to receive "stream sockets" */
 855  if(max_sdu_size == 0)
 856    new->max_data_size = irttp_get_max_seg_size(new->tsap);
 857#endif /* STREAM_COMPAT */
 858
 859  /* Clean up the original one to keep it in listen state */
 860  irttp_listen(server->tsap);
 861
 862  /* Send a connection response on the new socket */
 863  irttp_connect_response(new->tsap, new->max_sdu_size_rx, NULL);
 864
 865  /* Allow PPP to send its junk over the new socket... */
 866  set_bit(0, &new->ttp_open);
 867
 868  /* Not connecting anymore, and clean up last possible remains
 869   * of connection attempts on the socket */
 870  clear_bit(0, &new->ttp_connect);
 871  if(new->iriap)
 872    {
 873      iriap_close(new->iriap);
 874      new->iriap = NULL;
 875    }
 876  if(new->discoveries != NULL)
 877    {
 878      kfree(new->discoveries);
 879      new->discoveries = NULL;
 880    }
 881
 882#ifdef CONNECT_INDIC_KICK
 883  /* As currently we don't block packets in ppp_irnet_send() while passive,
 884   * this is not really needed...
 885   * Also, not doing it give IrDA a chance to finish the setup properly
 886   * before being swamped with packets... */
 887  ppp_output_wakeup(&new->chan);
 888#endif /* CONNECT_INDIC_KICK */
 889
 890  /* Notify the control channel */
 891  irnet_post_event(new, IRNET_CONNECT_FROM,
 892                   new->saddr, new->daddr, server->rname, 0);
 893
 894  DEXIT(IRDA_SERV_TRACE, "\n");
 895  return 0;
 896}
 897
 898/*------------------------------------------------------------------*/
 899/*
 900 * Function irda_disconnect_server (self)
 901 *
 902 *    Cleanup the server socket when the incoming connection abort
 903 *
 904 */
 905static inline void
 906irnet_disconnect_server(irnet_socket *  self,
 907                        struct sk_buff *skb)
 908{
 909  DENTER(IRDA_SERV_TRACE, "(self=0x%p)\n", self);
 910
 911  /* Put the received packet in the black hole */
 912  kfree_skb(skb);
 913
 914#ifdef FAIL_SEND_DISCONNECT
 915  /* Tell the other party we don't want to be connected */
 916  /* Hum... Is it the right thing to do ? And do we need to send
 917   * a connect response before ? It looks ok without this... */
 918  irttp_disconnect_request(self->tsap, NULL, P_NORMAL);
 919#endif /* FAIL_SEND_DISCONNECT */
 920
 921  /* Notify the control channel (see irnet_find_socket()) */
 922  irnet_post_event(NULL, IRNET_REQUEST_FROM,
 923                   self->saddr, self->daddr, self->rname, 0);
 924
 925  /* Clean up the server to keep it in listen state */
 926  irttp_listen(self->tsap);
 927
 928  DEXIT(IRDA_SERV_TRACE, "\n");
 929  return;
 930}
 931
 932/*------------------------------------------------------------------*/
 933/*
 934 * Function irda_setup_server (self)
 935 *
 936 *    Create a IrTTP server and set it up...
 937 *
 938 * Register the IrLAN hint bit, create a IrTTP instance for us,
 939 * set all the IrTTP callbacks and create an IrIAS entry...
 940 */
 941static inline int
 942irnet_setup_server(void)
 943{
 944  __u16         hints;
 945
 946  DENTER(IRDA_SERV_TRACE, "()\n");
 947
 948  /* Initialise the regular socket part of the server */
 949  irda_irnet_create(&irnet_server.s);
 950
 951  /* Open a local TSAP (an IrTTP instance) for the server */
 952  irnet_open_tsap(&irnet_server.s);
 953
 954  /* PPP part setup */
 955  irnet_server.s.ppp_open = 0;
 956  irnet_server.s.chan.private = NULL;
 957  irnet_server.s.file = NULL;
 958
 959  /* Get the hint bit corresponding to IrLAN */
 960  /* Note : we overload the IrLAN hint bit. As it is only a "hint", and as
 961   * we provide roughly the same functionality as IrLAN, this is ok.
 962   * In fact, the situation is similar as JetSend overloading the Obex hint
 963   */
 964  hints = irlmp_service_to_hint(S_LAN);
 965
 966#ifdef ADVERTISE_HINT
 967  /* Register with IrLMP as a service (advertise our hint bit) */
 968  irnet_server.skey = irlmp_register_service(hints);
 969#endif /* ADVERTISE_HINT */
 970
 971  /* Register with LM-IAS (so that people can connect to us) */
 972  irnet_server.ias_obj = irias_new_object(IRNET_SERVICE_NAME, jiffies);
 973  irias_add_integer_attrib(irnet_server.ias_obj, IRNET_IAS_VALUE,
 974                           irnet_server.s.stsap_sel, IAS_KERNEL_ATTR);
 975  irias_insert_object(irnet_server.ias_obj);
 976
 977#ifdef DISCOVERY_EVENTS
 978  /* Tell IrLMP we want to be notified of newly discovered nodes */
 979  irlmp_update_client(irnet_server.s.ckey, hints,
 980                      irnet_discovery_indication, irnet_expiry_indication,
 981                      (void *) &irnet_server.s);
 982#endif
 983
 984  DEXIT(IRDA_SERV_TRACE, " - self=0x%p\n", &irnet_server.s);
 985  return 0;
 986}
 987
 988/*------------------------------------------------------------------*/
 989/*
 990 * Function irda_destroy_server (self)
 991 *
 992 *    Destroy the IrTTP server...
 993 *
 994 * Reverse of the previous function...
 995 */
 996static inline void
 997irnet_destroy_server(void)
 998{
 999  DENTER(IRDA_SERV_TRACE, "()\n");
1000
1001#ifdef ADVERTISE_HINT
1002  /* Unregister with IrLMP */
1003  irlmp_unregister_service(irnet_server.skey);
1004#endif /* ADVERTISE_HINT */
1005
1006  /* Unregister with LM-IAS */
1007  if(irnet_server.ias_obj)
1008    irias_delete_object(irnet_server.ias_obj);
1009
1010  /* Cleanup the socket part */
1011  irda_irnet_destroy(&irnet_server.s);
1012
1013  DEXIT(IRDA_SERV_TRACE, "\n");
1014  return;
1015}
1016
1017
1018/************************ IRDA-TTP CALLBACKS ************************/
1019/*
1020 * When we create a IrTTP instance, we pass to it a set of callbacks
1021 * that IrTTP will call in case of various events.
1022 * We take care of those events here.
1023 */
1024
1025/*------------------------------------------------------------------*/
1026/*
1027 * Function irnet_data_indication (instance, sap, skb)
1028 *
1029 *    Received some data from TinyTP. Just queue it on the receive queue
1030 *
1031 */
1032static int
1033irnet_data_indication(void *    instance,
1034                      void *    sap,
1035                      struct sk_buff *skb)
1036{
1037  irnet_socket *        ap = (irnet_socket *) instance;
1038  unsigned char *       p;
1039  int                   code = 0;
1040
1041  DENTER(IRDA_TCB_TRACE, "(self/ap=0x%p, skb=0x%p)\n",
1042         ap, skb);
1043  DASSERT(skb != NULL, 0, IRDA_CB_ERROR, "skb is NULL !!!\n");
1044
1045  /* Check is ppp is ready to receive our packet */
1046  if(!ap->ppp_open)
1047    {
1048      DERROR(IRDA_CB_ERROR, "PPP not ready, dropping packet...\n");
1049      /* When we return error, TTP will need to requeue the skb and
1050       * will stop the sender. IrTTP will stall until we send it a
1051       * flow control request... */
1052      return -ENOMEM;
1053    }
1054
1055  /* strip address/control field if present */
1056  p = skb->data;
1057  if((p[0] == PPP_ALLSTATIONS) && (p[1] == PPP_UI))
1058    {
1059      /* chop off address/control */
1060      if(skb->len < 3)
1061        goto err_exit;
1062      p = skb_pull(skb, 2);
1063    }
1064
1065  /* decompress protocol field if compressed */
1066  if(p[0] & 1)
1067    {
1068      /* protocol is compressed */
1069      skb_push(skb, 1)[0] = 0;
1070    }
1071  else
1072    if(skb->len < 2)
1073      goto err_exit;
1074
1075  /* pass to generic ppp layer */
1076  /* Note : how do I know if ppp can accept or not the packet ? This is
1077   * essential if I want to manage flow control smoothly... */
1078  ppp_input(&ap->chan, skb);
1079
1080  DEXIT(IRDA_TCB_TRACE, "\n");
1081  return 0;
1082
1083 err_exit:
1084  DERROR(IRDA_CB_ERROR, "Packet too small, dropping...\n");
1085  kfree_skb(skb);
1086  ppp_input_error(&ap->chan, code);
1087  return 0;     /* Don't return an error code, only for flow control... */
1088}
1089
1090/*------------------------------------------------------------------*/
1091/*
1092 * Function irnet_disconnect_indication (instance, sap, reason, skb)
1093 *
1094 *    Connection has been closed. Chech reason to find out why
1095 *
1096 * Note : there are many cases where we come here :
1097 *      o attempted to connect, timeout
1098 *      o connected, link is broken, LAP has timeout
1099 *      o connected, other side close the link
1100 *      o connection request on the server not handled
1101 */
1102static void
1103irnet_disconnect_indication(void *      instance,
1104                            void *      sap,
1105                            LM_REASON   reason,
1106                            struct sk_buff *skb)
1107{
1108  irnet_socket *        self = (irnet_socket *) instance;
1109  int                   test_open;
1110  int                   test_connect;
1111
1112  DENTER(IRDA_TCB_TRACE, "(self=0x%p)\n", self);
1113  DASSERT(self != NULL, , IRDA_CB_ERROR, "Self is NULL !!!\n");
1114
1115  /* Don't care about it, but let's not leak it */
1116  if(skb)
1117    dev_kfree_skb(skb);
1118
1119  /* Prevent higher layer from accessing IrTTP */
1120  test_open = test_and_clear_bit(0, &self->ttp_open);
1121  /* Not connecting anymore...
1122   * (note : TSAP is open, so IAP callbacks are no longer pending...) */
1123  test_connect = test_and_clear_bit(0, &self->ttp_connect);
1124
1125  /* If both self->ttp_open and self->ttp_connect are NULL, it mean that we
1126   * have a race condition with irda_irnet_destroy() or
1127   * irnet_connect_indication(), so don't mess up tsap...
1128   */
1129  if(!(test_open || test_connect))
1130    {
1131      DERROR(IRDA_CB_ERROR, "Race condition detected...\n");
1132      return;
1133    }
1134
1135  /* If we were active, notify the control channel */
1136  if(test_open)
1137    irnet_post_event(self, IRNET_DISCONNECT_FROM,
1138                     self->saddr, self->daddr, self->rname, 0);
1139  else
1140    /* If we were trying to connect, notify the control channel */
1141    if((self->tsap) && (self != &irnet_server.s))
1142      irnet_post_event(self, IRNET_NOANSWER_FROM,
1143                       self->saddr, self->daddr, self->rname, 0);
1144
1145  /* Close our IrTTP connection, cleanup tsap */
1146  if((self->tsap) && (self != &irnet_server.s))
1147    {
1148      DEBUG(IRDA_CB_INFO, "Closing our TTP connection.\n");
1149      irttp_close_tsap(self->tsap);
1150      self->tsap = NULL;
1151    }
1152  /* Cleanup the socket in case we want to reconnect in ppp_output_wakeup() */
1153  self->stsap_sel = 0;
1154  self->daddr = DEV_ADDR_ANY;
1155  self->tx_flow = FLOW_START;
1156
1157  /* Deal with the ppp instance if it's still alive */
1158  if(self->ppp_open)
1159    {
1160      if(test_open)
1161        {
1162          /* ppp_unregister_channel() wants a user context. */
1163          schedule_work(&self->disconnect_work);
1164        }
1165      else
1166        {
1167          /* If we were trying to connect, flush (drain) ppp_generic
1168           * Tx queue (most often we have blocked it), which will
1169           * trigger an other attempt to connect. If we are passive,
1170           * this will empty the Tx queue after last try. */
1171          ppp_output_wakeup(&self->chan);
1172        }
1173    }
1174
1175  DEXIT(IRDA_TCB_TRACE, "\n");
1176}
1177
1178/*------------------------------------------------------------------*/
1179/*
1180 * Function irnet_connect_confirm (instance, sap, qos, max_sdu_size, skb)
1181 *
1182 *    Connections has been confirmed by the remote device
1183 *
1184 */
1185static void
1186irnet_connect_confirm(void *    instance,
1187                      void *    sap,
1188                      struct qos_info *qos,
1189                      __u32     max_sdu_size,
1190                      __u8      max_header_size,
1191                      struct sk_buff *skb)
1192{
1193  irnet_socket *        self = (irnet_socket *) instance;
1194
1195  DENTER(IRDA_TCB_TRACE, "(self=0x%p)\n", self);
1196
1197  /* Check if socket is closing down (via irda_irnet_destroy()) */
1198  if(! test_bit(0, &self->ttp_connect))
1199    {
1200      DERROR(IRDA_CB_ERROR, "Socket no longer connecting. Ouch !\n");
1201      return;
1202    }
1203
1204  /* How much header space do we need to reserve */
1205  self->max_header_size = max_header_size;
1206
1207  /* IrTTP max SDU size in transmit direction */
1208  self->max_sdu_size_tx = max_sdu_size;
1209  self->max_data_size = max_sdu_size;
1210#ifdef STREAM_COMPAT
1211  if(max_sdu_size == 0)
1212    self->max_data_size = irttp_get_max_seg_size(self->tsap);
1213#endif /* STREAM_COMPAT */
1214
1215  /* At this point, IrLMP has assigned our source address */
1216  self->saddr = irttp_get_saddr(self->tsap);
1217
1218  /* Allow higher layer to access IrTTP */
1219  set_bit(0, &self->ttp_open);
1220  clear_bit(0, &self->ttp_connect);     /* Not racy, IrDA traffic is serial */
1221  /* Give a kick in the ass of ppp_generic so that he sends us some data */
1222  ppp_output_wakeup(&self->chan);
1223
1224  /* Check size of received packet */
1225  if(skb->len > 0)
1226    {
1227#ifdef PASS_CONNECT_PACKETS
1228      DEBUG(IRDA_CB_INFO, "Passing connect packet to PPP.\n");
1229      /* Try to pass it to PPP */
1230      irnet_data_indication(instance, sap, skb);
1231#else /* PASS_CONNECT_PACKETS */
1232      DERROR(IRDA_CB_ERROR, "Dropping non empty packet.\n");
1233      kfree_skb(skb);   /* Note : will be optimised with other kfree... */
1234#endif /* PASS_CONNECT_PACKETS */
1235    }
1236  else
1237    kfree_skb(skb);
1238
1239  /* Notify the control channel */
1240  irnet_post_event(self, IRNET_CONNECT_TO,
1241                   self->saddr, self->daddr, self->rname, 0);
1242
1243  DEXIT(IRDA_TCB_TRACE, "\n");
1244}
1245
1246/*------------------------------------------------------------------*/
1247/*
1248 * Function irnet_flow_indication (instance, sap, flow)
1249 *
1250 *    Used by TinyTP to tell us if it can accept more data or not
1251 *
1252 */
1253static void
1254irnet_flow_indication(void *    instance,
1255                      void *    sap,
1256                      LOCAL_FLOW flow)
1257{
1258  irnet_socket *        self = (irnet_socket *) instance;
1259  LOCAL_FLOW            oldflow = self->tx_flow;
1260
1261  DENTER(IRDA_TCB_TRACE, "(self=0x%p, flow=%d)\n", self, flow);
1262
1263  /* Update our state */
1264  self->tx_flow = flow;
1265
1266  /* Check what IrTTP want us to do... */
1267  switch(flow)
1268    {
1269    case FLOW_START:
1270      DEBUG(IRDA_CB_INFO, "IrTTP wants us to start again\n");
1271      /* Check if we really need to wake up PPP */
1272      if(oldflow == FLOW_STOP)
1273        ppp_output_wakeup(&self->chan);
1274      else
1275        DEBUG(IRDA_CB_INFO, "But we were already transmitting !!!\n");
1276      break;
1277    case FLOW_STOP:
1278      DEBUG(IRDA_CB_INFO, "IrTTP wants us to slow down\n");
1279      break;
1280    default:
1281      DEBUG(IRDA_CB_INFO, "Unknown flow command!\n");
1282      break;
1283    }
1284
1285  DEXIT(IRDA_TCB_TRACE, "\n");
1286}
1287
1288/*------------------------------------------------------------------*/
1289/*
1290 * Function irnet_status_indication (instance, sap, reason, skb)
1291 *
1292 *    Link (IrLAP) status report.
1293 *
1294 */
1295static void
1296irnet_status_indication(void *  instance,
1297                        LINK_STATUS link,
1298                        LOCK_STATUS lock)
1299{
1300  irnet_socket *        self = (irnet_socket *) instance;
1301
1302  DENTER(IRDA_TCB_TRACE, "(self=0x%p)\n", self);
1303  DASSERT(self != NULL, , IRDA_CB_ERROR, "Self is NULL !!!\n");
1304
1305  /* We can only get this event if we are connected */
1306  switch(link)
1307    {
1308    case STATUS_NO_ACTIVITY:
1309      irnet_post_event(self, IRNET_BLOCKED_LINK,
1310                       self->saddr, self->daddr, self->rname, 0);
1311      break;
1312    default:
1313      DEBUG(IRDA_CB_INFO, "Unknown status...\n");
1314    }
1315
1316  DEXIT(IRDA_TCB_TRACE, "\n");
1317}
1318
1319/*------------------------------------------------------------------*/
1320/*
1321 * Function irnet_connect_indication(instance, sap, qos, max_sdu_size, userdata)
1322 *
1323 *    Incoming connection
1324 *
1325 * In theory, this function is called only on the server socket.
1326 * Some other node is attempting to connect to the IrNET service, and has
1327 * sent a connection request on our server socket.
1328 * We just redirect the connection to the relevant IrNET socket.
1329 *
1330 * Note : we also make sure that between 2 irnet nodes, there can
1331 * exist only one irnet connection.
1332 */
1333static void
1334irnet_connect_indication(void *         instance,
1335                         void *         sap,
1336                         struct qos_info *qos,
1337                         __u32          max_sdu_size,
1338                         __u8           max_header_size,
1339                         struct sk_buff *skb)
1340{
1341  irnet_socket *        server = &irnet_server.s;
1342  irnet_socket *        new = (irnet_socket *) NULL;
1343
1344  DENTER(IRDA_TCB_TRACE, "(server=0x%p)\n", server);
1345  DASSERT(instance == &irnet_server, , IRDA_CB_ERROR,
1346          "Invalid instance (0x%p) !!!\n", instance);
1347  DASSERT(sap == irnet_server.s.tsap, , IRDA_CB_ERROR, "Invalid sap !!!\n");
1348
1349  /* Try to find the most appropriate IrNET socket */
1350  new = irnet_find_socket(server);
1351
1352  /* After all this hard work, do we have an socket ? */
1353  if(new == (irnet_socket *) NULL)
1354    {
1355      DEXIT(IRDA_CB_INFO, ": No socket waiting for this connection.\n");
1356      irnet_disconnect_server(server, skb);
1357      return;
1358    }
1359
1360  /* Is the socket already busy ? */
1361  if(test_bit(0, &new->ttp_open))
1362    {
1363      DEXIT(IRDA_CB_INFO, ": Socket already connected.\n");
1364      irnet_disconnect_server(server, skb);
1365      return;
1366    }
1367
1368  /* The following code is a bit tricky, so need comments ;-)
1369   */
1370  /* If ttp_connect is set, the socket is trying to connect to the other
1371   * end and may have sent a IrTTP connection request and is waiting for
1372   * a connection response (that may never come).
1373   * Now, the pain is that the socket may have opened a tsap and is
1374   * waiting on it, while the other end is trying to connect to it on
1375   * another tsap.
1376   * Because IrNET can be peer to peer, we need to workaround this.
1377   * Furthermore, the way the irnetd script is implemented, the
1378   * target will create a second IrNET connection back to the
1379   * originator and expect the originator to bind this new connection
1380   * to the original PPPD instance.
1381   * And of course, if we don't use irnetd, we can have a race when
1382   * both side try to connect simultaneously, which could leave both
1383   * connections half closed (yuck).
1384   * Conclusions :
1385   *    1) The "originator" must accept the new connection and get rid
1386   *       of the old one so that irnetd works
1387   *    2) One side must deny the new connection to avoid races,
1388   *       but both side must agree on which side it is...
1389   * Most often, the originator is primary at the LAP layer.
1390   * Jean II
1391   */
1392  /* Now, let's look at the way I wrote the test...
1393   * We need to clear up the ttp_connect flag atomically to prevent
1394   * irnet_disconnect_indication() to mess up the tsap we are going to close.
1395   * We want to clear the ttp_connect flag only if we close the tsap,
1396   * otherwise we will never close it, so we need to check for primary
1397   * *before* doing the test on the flag.
1398   * And of course, ALLOW_SIMULT_CONNECT can disable this entirely...
1399   * Jean II
1400   */
1401
1402  /* Socket already connecting ? On primary ? */
1403  if(0
1404#ifdef ALLOW_SIMULT_CONNECT
1405     || ((irttp_is_primary(server->tsap) == 1)  /* primary */
1406         && (test_and_clear_bit(0, &new->ttp_connect)))
1407#endif /* ALLOW_SIMULT_CONNECT */
1408     )
1409    {
1410      DERROR(IRDA_CB_ERROR, "Socket already connecting, but going to reuse it !\n");
1411
1412      /* Cleanup the old TSAP if necessary - IrIAP will be cleaned up later */
1413      if(new->tsap != NULL)
1414        {
1415          /* Close the old connection the new socket was attempting,
1416           * so that we can hook it up to the new connection.
1417           * It's now safe to do it... */
1418          irttp_close_tsap(new->tsap);
1419          new->tsap = NULL;
1420        }
1421    }
1422  else
1423    {
1424      /* Three options :
1425       * 1) socket was not connecting or connected : ttp_connect should be 0.
1426       * 2) we don't want to connect the socket because we are secondary or
1427       * ALLOW_SIMULT_CONNECT is undefined. ttp_connect should be 1.
1428       * 3) we are half way in irnet_disconnect_indication(), and it's a
1429       * nice race condition... Fortunately, we can detect that by checking
1430       * if tsap is still alive. On the other hand, we can't be in
1431       * irda_irnet_destroy() otherwise we would not have found this
1432       * socket in the hashbin.
1433       * Jean II */
1434      if((test_bit(0, &new->ttp_connect)) || (new->tsap != NULL))
1435        {
1436          /* Don't mess this socket, somebody else in in charge... */
1437          DERROR(IRDA_CB_ERROR, "Race condition detected, socket in use, abort connect...\n");
1438          irnet_disconnect_server(server, skb);
1439          return;
1440        }
1441    }
1442
1443  /* So : at this point, we have a socket, and it is idle. Good ! */
1444  irnet_connect_socket(server, new, qos, max_sdu_size, max_header_size);
1445
1446  /* Check size of received packet */
1447  if(skb->len > 0)
1448    {
1449#ifdef PASS_CONNECT_PACKETS
1450      DEBUG(IRDA_CB_INFO, "Passing connect packet to PPP.\n");
1451      /* Try to pass it to PPP */
1452      irnet_data_indication(new, new->tsap, skb);
1453#else /* PASS_CONNECT_PACKETS */
1454      DERROR(IRDA_CB_ERROR, "Dropping non empty packet.\n");
1455      kfree_skb(skb);   /* Note : will be optimised with other kfree... */
1456#endif /* PASS_CONNECT_PACKETS */
1457    }
1458  else
1459    kfree_skb(skb);
1460
1461  DEXIT(IRDA_TCB_TRACE, "\n");
1462}
1463
1464
1465/********************** IRDA-IAS/LMP CALLBACKS **********************/
1466/*
1467 * These are the callbacks called by other layers of the IrDA stack,
1468 * mainly LMP for discovery and IAS for name queries.
1469 */
1470
1471/*------------------------------------------------------------------*/
1472/*
1473 * Function irnet_getvalue_confirm (result, obj_id, value, priv)
1474 *
1475 *    Got answer from remote LM-IAS, just connect
1476 *
1477 * This is the reply to a IAS query we were doing to find the TSAP of
1478 * the device we want to connect to.
1479 * If we have found a valid TSAP, just initiate the TTP connection
1480 * on this TSAP.
1481 */
1482static void
1483irnet_getvalue_confirm(int      result,
1484                       __u16    obj_id,
1485                       struct ias_value *value,
1486                       void *   priv)
1487{
1488  irnet_socket *        self = (irnet_socket *) priv;
1489
1490  DENTER(IRDA_OCB_TRACE, "(self=0x%p)\n", self);
1491  DASSERT(self != NULL, , IRDA_OCB_ERROR, "Self is NULL !!!\n");
1492
1493  /* Check if already connected (via irnet_connect_socket())
1494   * or socket is closing down (via irda_irnet_destroy()) */
1495  if(! test_bit(0, &self->ttp_connect))
1496    {
1497      DERROR(IRDA_OCB_ERROR, "Socket no longer connecting. Ouch !\n");
1498      return;
1499    }
1500
1501  /* We probably don't need to make any more queries */
1502  iriap_close(self->iriap);
1503  self->iriap = NULL;
1504
1505  /* Post process the IAS reply */
1506  self->dtsap_sel = irnet_ias_to_tsap(self, result, value);
1507
1508  /* If error, just go out */
1509  if(self->errno)
1510    {
1511      clear_bit(0, &self->ttp_connect);
1512      DERROR(IRDA_OCB_ERROR, "IAS connect failed ! (0x%X)\n", self->errno);
1513      return;
1514    }
1515
1516  DEBUG(IRDA_OCB_INFO, "daddr = %08x, lsap = %d, starting IrTTP connection\n",
1517        self->daddr, self->dtsap_sel);
1518
1519  /* Start up TTP - non blocking */
1520  irnet_connect_tsap(self);
1521
1522  DEXIT(IRDA_OCB_TRACE, "\n");
1523}
1524
1525/*------------------------------------------------------------------*/
1526/*
1527 * Function irnet_discovervalue_confirm (result, obj_id, value, priv)
1528 *
1529 *    Handle the TSAP discovery procedure state machine.
1530 *    Got answer from remote LM-IAS, try next device
1531 *
1532 * We are doing a  TSAP discovery procedure, and we got an answer to
1533 * a IAS query we were doing to find the TSAP on one of the address
1534 * in the discovery log.
1535 *
1536 * If we have found a valid TSAP for the first time, save it. If it's
1537 * not the first time we found one, complain.
1538 *
1539 * If we have more addresses in the log, just initiate a new query.
1540 * Note that those query may fail (see irnet_discover_daddr_and_lsap_sel())
1541 *
1542 * Otherwise, wrap up the procedure (cleanup), check if we have found
1543 * any device and connect to it.
1544 */
1545static void
1546irnet_discovervalue_confirm(int         result,
1547                            __u16       obj_id,
1548                            struct ias_value *value,
1549                            void *      priv)
1550{
1551  irnet_socket *        self = (irnet_socket *) priv;
1552  __u8                  dtsap_sel;              /* TSAP we are looking for */
1553
1554  DENTER(IRDA_OCB_TRACE, "(self=0x%p)\n", self);
1555  DASSERT(self != NULL, , IRDA_OCB_ERROR, "Self is NULL !!!\n");
1556
1557  /* Check if already connected (via irnet_connect_socket())
1558   * or socket is closing down (via irda_irnet_destroy()) */
1559  if(! test_bit(0, &self->ttp_connect))
1560    {
1561      DERROR(IRDA_OCB_ERROR, "Socket no longer connecting. Ouch !\n");
1562      return;
1563    }
1564
1565  /* Post process the IAS reply */
1566  dtsap_sel = irnet_ias_to_tsap(self, result, value);
1567
1568  /* Have we got something ? */
1569  if(self->errno == 0)
1570    {
1571      /* We found the requested service */
1572      if(self->daddr != DEV_ADDR_ANY)
1573        {
1574          DERROR(IRDA_OCB_ERROR, "More than one device in range supports IrNET...\n");
1575        }
1576      else
1577        {
1578          /* First time we found that one, save it ! */
1579          self->daddr = self->discoveries[self->disco_index].daddr;
1580          self->dtsap_sel = dtsap_sel;
1581        }
1582    }
1583
1584  /* If no failure */
1585  if((self->errno == -EADDRNOTAVAIL) || (self->errno == 0))
1586    {
1587      int       ret;
1588
1589      /* Search the next node */
1590      ret = irnet_discover_next_daddr(self);
1591      if(!ret)
1592        {
1593          /* In this case, the above request was non-blocking.
1594           * We will return here after a while... */
1595          return;
1596        }
1597      /* In this case, we have processed the last discovery item */
1598    }
1599
1600  /* No more queries to be done (failure or last one) */
1601
1602  /* We probably don't need to make any more queries */
1603  iriap_close(self->iriap);
1604  self->iriap = NULL;
1605
1606  /* No more items : remove the log and signal termination */
1607  DEBUG(IRDA_OCB_INFO, "Cleaning up log (0x%p)\n",
1608        self->discoveries);
1609  if(self->discoveries != NULL)
1610    {
1611      /* Cleanup our copy of the discovery log */
1612      kfree(self->discoveries);
1613      self->discoveries = NULL;
1614    }
1615  self->disco_number = -1;
1616
1617  /* Check out what we found */
1618  if(self->daddr == DEV_ADDR_ANY)
1619    {
1620      self->daddr = DEV_ADDR_ANY;
1621      clear_bit(0, &self->ttp_connect);
1622      DEXIT(IRDA_OCB_TRACE, ": cannot discover IrNET in any device !!!\n");
1623      return;
1624    }
1625
1626  /* We have a valid address - just connect */
1627
1628  DEBUG(IRDA_OCB_INFO, "daddr = %08x, lsap = %d, starting IrTTP connection\n",
1629        self->daddr, self->dtsap_sel);
1630
1631  /* Start up TTP - non blocking */
1632  irnet_connect_tsap(self);
1633
1634  DEXIT(IRDA_OCB_TRACE, "\n");
1635}
1636
1637#ifdef DISCOVERY_EVENTS
1638/*------------------------------------------------------------------*/
1639/*
1640 * Function irnet_discovery_indication (discovery)
1641 *
1642 *    Got a discovery indication from IrLMP, post an event
1643 *
1644 * Note : IrLMP take care of matching the hint mask for us, and also
1645 * check if it is a "new" node for us...
1646 *
1647 * As IrLMP filter on the IrLAN hint bit, we get both IrLAN and IrNET
1648 * nodes, so it's only at connection time that we will know if the
1649 * node support IrNET, IrLAN or both. The other solution is to check
1650 * in IAS the PNP ids and service name.
1651 * Note : even if a node support IrNET (or IrLAN), it's no guarantee
1652 * that we will be able to connect to it, the node might already be
1653 * busy...
1654 *
1655 * One last thing : in some case, this function will trigger duplicate
1656 * discovery events. On the other hand, we should catch all
1657 * discoveries properly (i.e. not miss one). Filtering duplicate here
1658 * is to messy, so we leave that to user space...
1659 */
1660static void
1661irnet_discovery_indication(discinfo_t *         discovery,
1662                           DISCOVERY_MODE       mode,
1663                           void *               priv)
1664{
1665  irnet_socket *        self = &irnet_server.s;
1666
1667  DENTER(IRDA_OCB_TRACE, "(self=0x%p)\n", self);
1668  DASSERT(priv == &irnet_server, , IRDA_OCB_ERROR,
1669          "Invalid instance (0x%p) !!!\n", priv);
1670
1671  DEBUG(IRDA_OCB_INFO, "Discovered new IrNET/IrLAN node %s...\n",
1672        discovery->info);
1673
1674  /* Notify the control channel */
1675  irnet_post_event(NULL, IRNET_DISCOVER,
1676                   discovery->saddr, discovery->daddr, discovery->info,
1677                   get_unaligned((__u16 *)discovery->hints));
1678
1679  DEXIT(IRDA_OCB_TRACE, "\n");
1680}
1681
1682/*------------------------------------------------------------------*/
1683/*
1684 * Function irnet_expiry_indication (expiry)
1685 *
1686 *    Got a expiry indication from IrLMP, post an event
1687 *
1688 * Note : IrLMP take care of matching the hint mask for us, we only
1689 * check if it is a "new" node...
1690 */
1691static void
1692irnet_expiry_indication(discinfo_t *    expiry,
1693                        DISCOVERY_MODE  mode,
1694                        void *          priv)
1695{
1696  irnet_socket *        self = &irnet_server.s;
1697
1698  DENTER(IRDA_OCB_TRACE, "(self=0x%p)\n", self);
1699  DASSERT(priv == &irnet_server, , IRDA_OCB_ERROR,
1700          "Invalid instance (0x%p) !!!\n", priv);
1701
1702  DEBUG(IRDA_OCB_INFO, "IrNET/IrLAN node %s expired...\n",
1703        expiry->info);
1704
1705  /* Notify the control channel */
1706  irnet_post_event(NULL, IRNET_EXPIRE,
1707                   expiry->saddr, expiry->daddr, expiry->info,
1708                   get_unaligned((__u16 *)expiry->hints));
1709
1710  DEXIT(IRDA_OCB_TRACE, "\n");
1711}
1712#endif /* DISCOVERY_EVENTS */
1713
1714
1715/*********************** PROC ENTRY CALLBACKS ***********************/
1716/*
1717 * We create a instance in the /proc filesystem, and here we take care
1718 * of that...
1719 */
1720
1721#ifdef CONFIG_PROC_FS
1722static int
1723irnet_proc_show(struct seq_file *m, void *v)
1724{
1725  irnet_socket *        self;
1726  char *                state;
1727  int                   i = 0;
1728
1729  /* Get the IrNET server information... */
1730  seq_printf(m, "IrNET server - ");
1731  seq_printf(m, "IrDA state: %s, ",
1732                 (irnet_server.running ? "running" : "dead"));
1733  seq_printf(m, "stsap_sel: %02x, ", irnet_server.s.stsap_sel);
1734  seq_printf(m, "dtsap_sel: %02x\n", irnet_server.s.dtsap_sel);
1735
1736  /* Do we need to continue ? */
1737  if(!irnet_server.running)
1738    return 0;
1739
1740  /* Protect access to the instance list */
1741  spin_lock_bh(&irnet_server.spinlock);
1742
1743  /* Get the sockets one by one... */
1744  self = (irnet_socket *) hashbin_get_first(irnet_server.list);
1745  while(self != NULL)
1746    {
1747      /* Start printing info about the socket. */
1748      seq_printf(m, "\nIrNET socket %d - ", i++);
1749
1750      /* First, get the requested configuration */
1751      seq_printf(m, "Requested IrDA name: \"%s\", ", self->rname);
1752      seq_printf(m, "daddr: %08x, ", self->rdaddr);
1753      seq_printf(m, "saddr: %08x\n", self->rsaddr);
1754
1755      /* Second, get all the PPP info */
1756      seq_printf(m, "   PPP state: %s",
1757                 (self->ppp_open ? "registered" : "unregistered"));
1758      if(self->ppp_open)
1759        {
1760          seq_printf(m, ", unit: ppp%d",
1761                         ppp_unit_number(&self->chan));
1762          seq_printf(m, ", channel: %d",
1763                         ppp_channel_index(&self->chan));
1764          seq_printf(m, ", mru: %d",
1765                         self->mru);
1766          /* Maybe add self->flags ? Later... */
1767        }
1768
1769      /* Then, get all the IrDA specific info... */
1770      if(self->ttp_open)
1771        state = "connected";
1772      else
1773        if(self->tsap != NULL)
1774          state = "connecting";
1775        else
1776          if(self->iriap != NULL)
1777            state = "searching";
1778          else
1779            if(self->ttp_connect)
1780              state = "weird";
1781            else
1782              state = "idle";
1783      seq_printf(m, "\n IrDA state: %s, ", state);
1784      seq_printf(m, "daddr: %08x, ", self->daddr);
1785      seq_printf(m, "stsap_sel: %02x, ", self->stsap_sel);
1786      seq_printf(m, "dtsap_sel: %02x\n", self->dtsap_sel);
1787
1788      /* Next socket, please... */
1789      self = (irnet_socket *) hashbin_get_next(irnet_server.list);
1790    }
1791
1792  /* Spin lock end */
1793  spin_unlock_bh(&irnet_server.spinlock);
1794
1795  return 0;
1796}
1797
1798static int irnet_proc_open(struct inode *inode, struct file *file)
1799{
1800        return single_open(file, irnet_proc_show, NULL);
1801}
1802
1803static const struct file_operations irnet_proc_fops = {
1804        .owner          = THIS_MODULE,
1805        .open           = irnet_proc_open,
1806        .read           = seq_read,
1807        .llseek         = seq_lseek,
1808        .release        = single_release,
1809};
1810#endif /* PROC_FS */
1811
1812
1813/********************** CONFIGURATION/CLEANUP **********************/
1814/*
1815 * Initialisation and teardown of the IrDA part, called at module
1816 * insertion and removal...
1817 */
1818
1819/*------------------------------------------------------------------*/
1820/*
1821 * Prepare the IrNET layer for operation...
1822 */
1823int __init
1824irda_irnet_init(void)
1825{
1826  int           err = 0;
1827
1828  DENTER(MODULE_TRACE, "()\n");
1829
1830  /* Pure paranoia - should be redundant */
1831  memset(&irnet_server, 0, sizeof(struct irnet_root));
1832
1833  /* Setup start of irnet instance list */
1834  irnet_server.list = hashbin_new(HB_NOLOCK);
1835  DABORT(irnet_server.list == NULL, -ENOMEM,
1836         MODULE_ERROR, "Can't allocate hashbin!\n");
1837  /* Init spinlock for instance list */
1838  spin_lock_init(&irnet_server.spinlock);
1839
1840  /* Initialise control channel */
1841  init_waitqueue_head(&irnet_events.rwait);
1842  irnet_events.index = 0;
1843  /* Init spinlock for event logging */
1844  spin_lock_init(&irnet_events.spinlock);
1845
1846#ifdef CONFIG_PROC_FS
1847  /* Add a /proc file for irnet infos */
1848  proc_create("irnet", 0, proc_irda, &irnet_proc_fops);
1849#endif /* CONFIG_PROC_FS */
1850
1851  /* Setup the IrNET server */
1852  err = irnet_setup_server();
1853
1854  if(!err)
1855    /* We are no longer functional... */
1856    irnet_server.running = 1;
1857
1858  DEXIT(MODULE_TRACE, "\n");
1859  return err;
1860}
1861
1862/*------------------------------------------------------------------*/
1863/*
1864 * Cleanup at exit...
1865 */
1866void __exit
1867irda_irnet_cleanup(void)
1868{
1869  DENTER(MODULE_TRACE, "()\n");
1870
1871  /* We are no longer there... */
1872  irnet_server.running = 0;
1873
1874#ifdef CONFIG_PROC_FS
1875  /* Remove our /proc file */
1876  remove_proc_entry("irnet", proc_irda);
1877#endif /* CONFIG_PROC_FS */
1878
1879  /* Remove our IrNET server from existence */
1880  irnet_destroy_server();
1881
1882  /* Remove all instances of IrNET socket still present */
1883  hashbin_delete(irnet_server.list, (FREE_FUNC) irda_irnet_destroy);
1884
1885  DEXIT(MODULE_TRACE, "\n");
1886}
1887
lxr.linux.no kindly hosted by Redpill Linpro AS, provider of Linux consulting and operations services since 1995.