irnet_irda.c
上传用户:lgb322
上传日期:2013-02-24
资源大小:30529k
文件大小:54k
源码类别:

嵌入式Linux

开发平台:

Unix_Linux

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