irnet_irda.c
上传用户:jlfgdled
上传日期:2013-04-10
资源大小:33168k
文件大小:54k
源码类别:

Linux/Unix编程

开发平台:

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 not 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.     }
  978.   /* Cleanup the socket in case we want to reconnect in ppp_output_wakeup() */
  979.   self->stsap_sel = 0;
  980.   self->daddr = DEV_ADDR_ANY;
  981.   self->tx_flow = FLOW_START;
  982.   /* Deal with the ppp instance if it's still alive */
  983.   if(self->ppp_open)
  984.     {
  985.       if(test_open)
  986. {
  987.   /* If we were connected, cleanup & close the PPP channel,
  988.    * which will kill pppd (hangup) and the rest */
  989.   ppp_unregister_channel(&self->chan);
  990.   self->ppp_open = 0;
  991. }
  992.       else
  993. {
  994.   /* If we were trying to connect, flush (drain) ppp_generic
  995.    * Tx queue (most often we have blocked it), which will
  996.    * trigger an other attempt to connect. If we are passive,
  997.    * this will empty the Tx queue after last try. */
  998.   ppp_output_wakeup(&self->chan);
  999. }
  1000.     }
  1001.   DEXIT(IRDA_TCB_TRACE, "n");
  1002. }
  1003. /*------------------------------------------------------------------*/
  1004. /*
  1005.  * Function irnet_connect_confirm (instance, sap, qos, max_sdu_size, skb)
  1006.  *
  1007.  *    Connections has been confirmed by the remote device
  1008.  *
  1009.  */
  1010. static void
  1011. irnet_connect_confirm(void * instance,
  1012.       void * sap, 
  1013.       struct qos_info *qos,
  1014.       __u32 max_sdu_size,
  1015.       __u8 max_header_size, 
  1016.       struct sk_buff *skb)
  1017. {
  1018.   irnet_socket * self = (irnet_socket *) instance;
  1019.   DENTER(IRDA_TCB_TRACE, "(self=0x%X)n", (unsigned int) self);
  1020.   /* Check if socket is closing down (via irda_irnet_destroy()) */
  1021.   if(! test_bit(0, &self->ttp_connect))
  1022.     {
  1023.       DERROR(IRDA_CB_ERROR, "Socket no longer connecting. Ouch !n");
  1024.       return;
  1025.     }
  1026.   /* How much header space do we need to reserve */
  1027.   self->max_header_size = max_header_size;
  1028.   /* IrTTP max SDU size in transmit direction */
  1029.   self->max_sdu_size_tx = max_sdu_size;
  1030.   self->max_data_size = max_sdu_size;
  1031. #ifdef STREAM_COMPAT
  1032.   if(max_sdu_size == 0)
  1033.     self->max_data_size = irttp_get_max_seg_size(self->tsap);
  1034. #endif /* STREAM_COMPAT */
  1035.   /* At this point, IrLMP has assigned our source address */
  1036.   self->saddr = irttp_get_saddr(self->tsap);
  1037.   /* Allow higher layer to access IrTTP */
  1038.   set_bit(0, &self->ttp_open);
  1039.   clear_bit(0, &self->ttp_connect); /* Not racy, IrDA traffic is serial */
  1040.   /* Give a kick in the ass of ppp_generic so that he sends us some data */
  1041.   ppp_output_wakeup(&self->chan);
  1042.   /* Check size of received packet */
  1043.   if(skb->len > 0)
  1044.     {
  1045. #ifdef PASS_CONNECT_PACKETS
  1046.       DEBUG(IRDA_CB_INFO, "Passing connect packet to PPP.n");
  1047.       /* Try to pass it to PPP */
  1048.       irnet_data_indication(instance, sap, skb);
  1049. #else /* PASS_CONNECT_PACKETS */
  1050.       DERROR(IRDA_CB_ERROR, "Dropping non empty packet.n");
  1051.       kfree_skb(skb); /* Note : will be optimised with other kfree... */
  1052. #endif /* PASS_CONNECT_PACKETS */
  1053.     }
  1054.   else
  1055.     kfree_skb(skb);
  1056.   /* Notify the control channel */
  1057.   irnet_post_event(self, IRNET_CONNECT_TO,
  1058.    self->saddr, self->daddr, self->rname);
  1059.   DEXIT(IRDA_TCB_TRACE, "n");
  1060. }
  1061. /*------------------------------------------------------------------*/
  1062. /*
  1063.  * Function irnet_flow_indication (instance, sap, flow)
  1064.  *
  1065.  *    Used by TinyTP to tell us if it can accept more data or not
  1066.  *
  1067.  */
  1068. static void
  1069. irnet_flow_indication(void * instance,
  1070.       void * sap,
  1071.       LOCAL_FLOW flow) 
  1072. {
  1073.   irnet_socket * self = (irnet_socket *) instance;
  1074.   LOCAL_FLOW oldflow = self->tx_flow;
  1075.   DENTER(IRDA_TCB_TRACE, "(self=0x%X, flow=%d)n", (unsigned int) self, flow);
  1076.   /* Update our state */
  1077.   self->tx_flow = flow;
  1078.   /* Check what IrTTP want us to do... */
  1079.   switch(flow)
  1080.     {
  1081.     case FLOW_START:
  1082.       DEBUG(IRDA_CB_INFO, "IrTTP wants us to start againn");
  1083.       /* Check if we really need to wake up PPP */
  1084.       if(oldflow == FLOW_STOP)
  1085. ppp_output_wakeup(&self->chan);
  1086.       else
  1087. DEBUG(IRDA_CB_INFO, "But we were already transmitting !!!n");
  1088.       break;
  1089.     case FLOW_STOP:
  1090.       DEBUG(IRDA_CB_INFO, "IrTTP wants us to slow downn");
  1091.       break;
  1092.     default:
  1093.       DEBUG(IRDA_CB_INFO, "Unknown flow command!n");
  1094.       break;
  1095.     }
  1096.   DEXIT(IRDA_TCB_TRACE, "n");
  1097. }
  1098. /*------------------------------------------------------------------*/
  1099. /*
  1100.  * Function irnet_status_indication (instance, sap, reason, skb)
  1101.  *
  1102.  *    Link (IrLAP) status report.
  1103.  *
  1104.  */
  1105. static void
  1106. irnet_status_indication(void * instance,
  1107. LINK_STATUS link,
  1108. LOCK_STATUS lock)
  1109. {
  1110.   irnet_socket * self = (irnet_socket *) instance;
  1111.   DENTER(IRDA_TCB_TRACE, "(self=0x%X)n", (unsigned int) self);
  1112.   DASSERT(self != NULL, , IRDA_CB_ERROR, "Self is NULL !!!n");
  1113.   /* We can only get this event if we are connected */
  1114.   switch(link)
  1115.     {
  1116.     case STATUS_NO_ACTIVITY:
  1117.       irnet_post_event(self, IRNET_BLOCKED_LINK,
  1118.        self->saddr, self->daddr, self->rname);
  1119.       break;
  1120.     default:
  1121.       DEBUG(IRDA_CB_INFO, "Unknown status...n");
  1122.     }
  1123.   DEXIT(IRDA_TCB_TRACE, "n");
  1124. }
  1125. /*------------------------------------------------------------------*/
  1126. /*
  1127.  * Function irnet_connect_indication(instance, sap, qos, max_sdu_size, userdata)
  1128.  *
  1129.  *    Incoming connection
  1130.  *
  1131.  * In theory, this function is called only on the server socket.
  1132.  * Some other node is attempting to connect to the IrNET service, and has
  1133.  * sent a connection request on our server socket.
  1134.  * We just redirect the connection to the relevant IrNET socket.
  1135.  * 
  1136.  * Note : we also make sure that between 2 irnet nodes, there can
  1137.  * exist only one irnet connection.
  1138.  */
  1139. static void
  1140. irnet_connect_indication(void * instance,
  1141.  void * sap, 
  1142.  struct qos_info *qos,
  1143.  __u32 max_sdu_size,
  1144.  __u8 max_header_size,
  1145.  struct sk_buff *skb)
  1146. {
  1147.   irnet_socket * server = &irnet_server.s;
  1148.   irnet_socket * new = (irnet_socket *) NULL;
  1149.   DENTER(IRDA_TCB_TRACE, "(server=0x%X)n", (unsigned int) server);
  1150.   DASSERT(instance == &irnet_server, , IRDA_CB_ERROR,
  1151.   "Invalid instance (0x%X) !!!n", (unsigned int) instance);
  1152.   DASSERT(sap == irnet_server.s.tsap, , IRDA_CB_ERROR, "Invalid sap !!!n");
  1153.   /* Try to find the most appropriate IrNET socket */
  1154.   new = irnet_find_socket(server);
  1155.   /* After all this hard work, do we have an socket ? */
  1156.   if(new == (irnet_socket *) NULL)
  1157.     {
  1158.       DEXIT(IRDA_CB_INFO, ": No socket waiting for this connection.n");
  1159.       irnet_disconnect_server(server, skb);
  1160.       return;
  1161.     }
  1162.   /* Is the socket already busy ? */
  1163.   if(test_bit(0, &new->ttp_open))
  1164.     {
  1165.       DEXIT(IRDA_CB_INFO, ": Socket already connected.n");
  1166.       irnet_disconnect_server(server, skb);
  1167.       return;
  1168.     }
  1169.   /* Socket connecting ?
  1170.    * Clear up flag : prevent irnet_disconnect_indication() to mess up tsap */
  1171.   if(test_and_clear_bit(0, &new->ttp_connect))
  1172.     {
  1173.       /* The socket is trying to connect to the other end and may have sent
  1174.        * a IrTTP connection request and is waiting for a connection response
  1175.        * (that may never come).
  1176.        * Now, the pain is that the socket may have opened a tsap and is
  1177.        * waiting on it, while the other end is trying to connect to it on
  1178.        * another tsap.
  1179.        */
  1180.       DERROR(IRDA_CB_ERROR, "Socket already connecting. Ouch !n");
  1181. #ifdef ALLOW_SIMULT_CONNECT
  1182.       /* Cleanup the TSAP if necessary - IrIAP will be cleaned up later */
  1183.       if(new->tsap != NULL)
  1184. {
  1185.   /* Close the connection the new socket was attempting.
  1186.    * This seems to be safe... */
  1187.   irttp_close_tsap(new->tsap);
  1188.   new->tsap = NULL;
  1189. }
  1190.       /* Note : no return, fall through... */
  1191. #else /* ALLOW_SIMULT_CONNECT */
  1192.       irnet_disconnect_server(server, skb);
  1193.       return;
  1194. #endif /* ALLOW_SIMULT_CONNECT */
  1195.     }
  1196.   else
  1197.     /* If socket is not connecting or connected, tsap should be NULL */
  1198.     if(new->tsap != NULL)
  1199.       {
  1200. /* If we are here, we are also in irnet_disconnect_indication(),
  1201.  * and it's a nice race condition... On the other hand, we can't be
  1202.  * in irda_irnet_destroy() otherwise we would not have found the
  1203.  * socket in the hashbin. */
  1204. /* Better get out of here, otherwise we will mess up tsaps ! */
  1205. DERROR(IRDA_CB_ERROR, "Race condition detected, abort connect...n");
  1206. irnet_disconnect_server(server, skb);
  1207. return;
  1208.       }
  1209.   /* So : at this point, we have a socket, and it is idle. Good ! */
  1210.   irnet_connect_socket(server, new, qos, max_sdu_size, max_header_size);
  1211.   /* Check size of received packet */
  1212.   if(skb->len > 0)
  1213.     {
  1214. #ifdef PASS_CONNECT_PACKETS
  1215.       DEBUG(IRDA_CB_INFO, "Passing connect packet to PPP.n");
  1216.       /* Try to pass it to PPP */
  1217.       irnet_data_indication(new, new->tsap, skb);
  1218. #else /* PASS_CONNECT_PACKETS */
  1219.       DERROR(IRDA_CB_ERROR, "Dropping non empty packet.n");
  1220.       kfree_skb(skb); /* Note : will be optimised with other kfree... */
  1221. #endif /* PASS_CONNECT_PACKETS */
  1222.     }
  1223.   else
  1224.     kfree_skb(skb);
  1225.   DEXIT(IRDA_TCB_TRACE, "n");
  1226. }
  1227. /********************** IRDA-IAS/LMP CALLBACKS **********************/
  1228. /*
  1229.  * These are the callbacks called by other layers of the IrDA stack,
  1230.  * mainly LMP for discovery and IAS for name queries.
  1231.  */
  1232. /*------------------------------------------------------------------*/
  1233. /*
  1234.  * Function irnet_getvalue_confirm (result, obj_id, value, priv)
  1235.  *
  1236.  *    Got answer from remote LM-IAS, just connect
  1237.  *
  1238.  * This is the reply to a IAS query we were doing to find the TSAP of
  1239.  * the device we want to connect to.
  1240.  * If we have found a valid TSAP, just initiate the TTP connection
  1241.  * on this TSAP.
  1242.  */
  1243. static void
  1244. irnet_getvalue_confirm(int result,
  1245.        __u16 obj_id, 
  1246.        struct ias_value *value,
  1247.        void * priv)
  1248. {
  1249.   irnet_socket * self = (irnet_socket *) priv;
  1250.   DENTER(IRDA_OCB_TRACE, "(self=0x%X)n", (unsigned int) self);
  1251.   DASSERT(self != NULL, , IRDA_OCB_ERROR, "Self is NULL !!!n");
  1252.   /* Check if already connected (via irnet_connect_socket())
  1253.    * or socket is closing down (via irda_irnet_destroy()) */
  1254.   if(! test_bit(0, &self->ttp_connect))
  1255.     {
  1256.       DERROR(IRDA_OCB_ERROR, "Socket no longer connecting. Ouch !n");
  1257.       return;
  1258.     }
  1259.   /* We probably don't need to make any more queries */
  1260.   iriap_close(self->iriap);
  1261.   self->iriap = NULL;
  1262.   /* Post process the IAS reply */
  1263.   self->dtsap_sel = irnet_ias_to_tsap(self, result, value);
  1264.   /* If error, just go out */
  1265.   if(self->errno)
  1266.     {
  1267.       clear_bit(0, &self->ttp_connect);
  1268.       DERROR(IRDA_OCB_ERROR, "IAS connect failed ! (0x%X)n", self->errno);
  1269.       return;
  1270.     }
  1271.   DEBUG(IRDA_OCB_INFO, "daddr = %08x, lsap = %d, starting IrTTP connectionn",
  1272. self->daddr, self->dtsap_sel);
  1273.   /* Start up TTP - non blocking */
  1274.   irnet_connect_tsap(self);
  1275.   DEXIT(IRDA_OCB_TRACE, "n");
  1276. }
  1277. /*------------------------------------------------------------------*/
  1278. /*
  1279.  * Function irnet_discovervalue_confirm (result, obj_id, value, priv)
  1280.  *
  1281.  *    Handle the TSAP discovery procedure state machine.
  1282.  *    Got answer from remote LM-IAS, try next device
  1283.  *
  1284.  * We are doing a  TSAP discovery procedure, and we got an answer to
  1285.  * a IAS query we were doing to find the TSAP on one of the address
  1286.  * in the discovery log.
  1287.  *
  1288.  * If we have found a valid TSAP for the first time, save it. If it's
  1289.  * not the first time we found one, complain.
  1290.  *
  1291.  * If we have more addresses in the log, just initiate a new query.
  1292.  * Note that those query may fail (see irnet_discover_daddr_and_lsap_sel())
  1293.  *
  1294.  * Otherwise, wrap up the procedure (cleanup), check if we have found
  1295.  * any device and connect to it.
  1296.  */
  1297. static void
  1298. irnet_discovervalue_confirm(int result,
  1299.     __u16 obj_id, 
  1300.     struct ias_value *value,
  1301.     void * priv)
  1302. {
  1303.   irnet_socket * self = (irnet_socket *) priv;
  1304.   __u8 dtsap_sel; /* TSAP we are looking for */
  1305.   DENTER(IRDA_OCB_TRACE, "(self=0x%X)n", (unsigned int) self);
  1306.   DASSERT(self != NULL, , IRDA_OCB_ERROR, "Self is NULL !!!n");
  1307.   /* Check if already connected (via irnet_connect_socket())
  1308.    * or socket is closing down (via irda_irnet_destroy()) */
  1309.   if(! test_bit(0, &self->ttp_connect))
  1310.     {
  1311.       DERROR(IRDA_OCB_ERROR, "Socket no longer connecting. Ouch !n");
  1312.       return;
  1313.     }
  1314.   /* Post process the IAS reply */
  1315.   dtsap_sel = irnet_ias_to_tsap(self, result, value);
  1316.   /* Have we got something ? */
  1317.   if(self->errno == 0)
  1318.     {
  1319.       /* We found the requested service */
  1320.       if(self->daddr != DEV_ADDR_ANY)
  1321. {
  1322.   DERROR(IRDA_OCB_ERROR, "More than one device in range supports IrNET...n");
  1323. }
  1324.       else
  1325. {
  1326.   /* First time we found that one, save it ! */
  1327.   self->daddr = self->discoveries[self->disco_index].daddr;
  1328.   self->dtsap_sel = dtsap_sel;
  1329. }
  1330.     }
  1331.   /* If no failure */
  1332.   if((self->errno == -EADDRNOTAVAIL) || (self->errno == 0))
  1333.     {
  1334.       int ret;
  1335.       /* Search the next node */
  1336.       ret = irnet_discover_next_daddr(self);
  1337.       if(!ret)
  1338. {
  1339.   /* In this case, the above request was non-blocking.
  1340.    * We will return here after a while... */
  1341.   return;
  1342. }
  1343.       /* In this case, we have processed the last discovery item */
  1344.     }
  1345.   /* No more queries to be done (failure or last one) */
  1346.   /* We probably don't need to make any more queries */
  1347.   iriap_close(self->iriap);
  1348.   self->iriap = NULL;
  1349.   /* No more items : remove the log and signal termination */
  1350.   DEBUG(IRDA_OCB_INFO, "Cleaning up log (0x%X)n",
  1351. (unsigned int) self->discoveries);
  1352.   if(self->discoveries != NULL)
  1353.     {
  1354.       /* Cleanup our copy of the discovery log */
  1355.       kfree(self->discoveries);
  1356.       self->discoveries = NULL;
  1357.     }
  1358.   self->disco_number = -1;
  1359.   /* Check out what we found */
  1360.   if(self->daddr == DEV_ADDR_ANY)
  1361.     {
  1362.       self->daddr = DEV_ADDR_ANY;
  1363.       clear_bit(0, &self->ttp_connect);
  1364.       DEXIT(IRDA_OCB_TRACE, ": cannot discover IrNET in any device !!!n");
  1365.       return;
  1366.     }
  1367.   /* We have a valid address - just connect */
  1368.   DEBUG(IRDA_OCB_INFO, "daddr = %08x, lsap = %d, starting IrTTP connectionn",
  1369. self->daddr, self->dtsap_sel);
  1370.   /* Start up TTP - non blocking */
  1371.   irnet_connect_tsap(self);
  1372.   DEXIT(IRDA_OCB_TRACE, "n");
  1373. }
  1374. #ifdef DISCOVERY_EVENTS
  1375. /*------------------------------------------------------------------*/
  1376. /*
  1377.  * Function irnet_discovery_indication (discovery)
  1378.  *
  1379.  *    Got a discovery indication from IrLMP, post an event
  1380.  *
  1381.  * Note : IrLMP take care of matching the hint mask for us, we only
  1382.  * check if it is a "new" node...
  1383.  *
  1384.  * As IrLMP filter on the IrLAN hint bit, we get both IrLAN and IrNET
  1385.  * nodes, so it's only at connection time that we will know if the
  1386.  * node support IrNET, IrLAN or both. The other solution is to check
  1387.  * in IAS the PNP ids and service name.
  1388.  * Note : even if a node support IrNET (or IrLAN), it's no guarantee
  1389.  * that we will be able to connect to it, the node might already be
  1390.  * busy...
  1391.  *
  1392.  * One last thing : in some case, this function will trigger duplicate
  1393.  * discovery events. On the other hand, we should catch all
  1394.  * discoveries properly (i.e. not miss one). Filtering duplicate here
  1395.  * is to messy, so we leave that to user space...
  1396.  */
  1397. static void
  1398. irnet_discovery_indication(discovery_t * discovery,
  1399.    DISCOVERY_MODE mode,
  1400.    void * priv)
  1401. {
  1402.   irnet_socket * self = &irnet_server.s;
  1403.   DENTER(IRDA_OCB_TRACE, "(self=0x%X)n", (unsigned int) self);
  1404.   DASSERT(priv == &irnet_server, , IRDA_OCB_ERROR,
  1405.   "Invalid instance (0x%X) !!!n", (unsigned int) priv);
  1406.   /* Check if node is discovered is a new one or an old one.
  1407.    * We check when how long ago this node was discovered, with a
  1408.    * coarse timeout (we may miss some discovery events or be delayed).
  1409.    */
  1410.   if((jiffies - discovery->first_timestamp) >= (sysctl_discovery_timeout * HZ))
  1411.     {
  1412.       return; /* Too old, not interesting -> goodbye */
  1413.     }
  1414.   DEBUG(IRDA_OCB_INFO, "Discovered new IrNET/IrLAN node %s...n",
  1415. discovery->nickname);
  1416.   /* Notify the control channel */
  1417.   irnet_post_event(NULL, IRNET_DISCOVER,
  1418.    discovery->saddr, discovery->daddr, discovery->nickname);
  1419.   DEXIT(IRDA_OCB_TRACE, "n");
  1420. }
  1421. /*------------------------------------------------------------------*/
  1422. /*
  1423.  * Function irnet_expiry_indication (expiry)
  1424.  *
  1425.  *    Got a expiry indication from IrLMP, post an event
  1426.  *
  1427.  * Note : IrLMP take care of matching the hint mask for us, we only
  1428.  * check if it is a "new" node...
  1429.  */
  1430. static void
  1431. irnet_expiry_indication(discovery_t * expiry,
  1432. DISCOVERY_MODE mode,
  1433. void * priv)
  1434. {
  1435.   irnet_socket * self = &irnet_server.s;
  1436.   DENTER(IRDA_OCB_TRACE, "(self=0x%X)n", (unsigned int) self);
  1437.   DASSERT(priv == &irnet_server, , IRDA_OCB_ERROR,
  1438.   "Invalid instance (0x%X) !!!n", (unsigned int) priv);
  1439.   DEBUG(IRDA_OCB_INFO, "IrNET/IrLAN node %s expired...n",
  1440. expiry->nickname);
  1441.   /* Notify the control channel */
  1442.   irnet_post_event(NULL, IRNET_EXPIRE,
  1443.    expiry->saddr, expiry->daddr, expiry->nickname);
  1444.   DEXIT(IRDA_OCB_TRACE, "n");
  1445. }
  1446. #endif /* DISCOVERY_EVENTS */
  1447. /*********************** PROC ENTRY CALLBACKS ***********************/
  1448. /*
  1449.  * We create a instance in the /proc filesystem, and here we take care
  1450.  * of that...
  1451.  */
  1452. #ifdef CONFIG_PROC_FS
  1453. /*------------------------------------------------------------------*/
  1454. /*
  1455.  * Function irnet_proc_read (buf, start, offset, len, unused)
  1456.  *
  1457.  *    Give some info to the /proc file system
  1458.  */
  1459. static int
  1460. irnet_proc_read(char * buf,
  1461. char ** start,
  1462. off_t offset,
  1463. int len)
  1464. {
  1465.   irnet_socket * self;
  1466.   char * state;
  1467.   unsigned long flags;
  1468.   int i = 0;
  1469.   len = 0;
  1470.   /* Get the IrNET server information... */
  1471.   len += sprintf(buf+len, "IrNET server - ");
  1472.   len += sprintf(buf+len, "IrDA state: %s, ",
  1473.  (irnet_server.running ? "running" : "dead"));
  1474.   len += sprintf(buf+len, "stsap_sel: %02x, ", irnet_server.s.stsap_sel);
  1475.   len += sprintf(buf+len, "dtsap_sel: %02xn", irnet_server.s.dtsap_sel);
  1476.   /* Do we need to continue ? */
  1477.   if(!irnet_server.running)
  1478.     return len;
  1479.   /* Protect access to the instance list */
  1480.   spin_lock_irqsave(&irnet_server.spinlock, flags);
  1481.   /* Get the sockets one by one... */
  1482.   self = (irnet_socket *) hashbin_get_first(irnet_server.list);
  1483.   while(self != NULL)
  1484.     {
  1485.       /* Start printing info about the socket. */
  1486.       len += sprintf(buf+len, "nIrNET socket %d - ", i++);
  1487.       /* First, get the requested configuration */
  1488.       len += sprintf(buf+len, "Requested IrDA name: "%s", ", self->rname);
  1489.       len += sprintf(buf+len, "daddr: %08x, ", self->rdaddr);
  1490.       len += sprintf(buf+len, "saddr: %08xn", self->rsaddr);
  1491.       /* Second, get all the PPP info */
  1492.       len += sprintf(buf+len, " PPP state: %s",
  1493.  (self->ppp_open ? "registered" : "unregistered"));
  1494.       if(self->ppp_open)
  1495. {
  1496.   len += sprintf(buf+len, ", unit: ppp%d",
  1497.  ppp_unit_number(&self->chan));
  1498.   len += sprintf(buf+len, ", channel: %d",
  1499.  ppp_channel_index(&self->chan));
  1500.   len += sprintf(buf+len, ", mru: %d",
  1501.  self->mru);
  1502.   /* Maybe add self->flags ? Later... */
  1503. }
  1504.       /* Then, get all the IrDA specific info... */
  1505.       if(self->ttp_open)
  1506. state = "connected";
  1507.       else
  1508. if(self->tsap != NULL)
  1509.   state = "connecting";
  1510. else
  1511.   if(self->iriap != NULL)
  1512.     state = "searching";
  1513.   else
  1514.     if(self->ttp_connect)
  1515.       state = "weird";
  1516.     else
  1517.       state = "idle";
  1518.       len += sprintf(buf+len, "n IrDA state: %s, ", state);
  1519.       len += sprintf(buf+len, "daddr: %08x, ", self->daddr);
  1520.       len += sprintf(buf+len, "stsap_sel: %02x, ", self->stsap_sel);
  1521.       len += sprintf(buf+len, "dtsap_sel: %02xn", self->dtsap_sel);
  1522.       /* Next socket, please... */
  1523.       self = (irnet_socket *) hashbin_get_next(irnet_server.list);
  1524.     }
  1525.   /* Spin lock end */
  1526.   spin_unlock_irqrestore(&irnet_server.spinlock, flags);
  1527.   return len;
  1528. }
  1529. #endif /* PROC_FS */
  1530. /********************** CONFIGURATION/CLEANUP **********************/
  1531. /*
  1532.  * Initialisation and teardown of the IrDA part, called at module
  1533.  * insertion and removal...
  1534.  */
  1535. /*------------------------------------------------------------------*/
  1536. /*
  1537.  * Prepare the IrNET layer for operation...
  1538.  */
  1539. int
  1540. irda_irnet_init(void)
  1541. {
  1542.   int err = 0;
  1543.   DENTER(MODULE_TRACE, "()n");
  1544.   /* Pure paranoia - should be redundant */
  1545.   memset(&irnet_server, 0, sizeof(struct irnet_root));
  1546.   /* Setup start of irnet instance list */
  1547.   irnet_server.list = hashbin_new(HB_NOLOCK); 
  1548.   DABORT(irnet_server.list == NULL, -ENOMEM,
  1549.  MODULE_ERROR, "Can't allocate hashbin!n");
  1550.   /* Init spinlock for instance list */
  1551.   spin_lock_init(&irnet_server.spinlock);
  1552.   /* Initialise control channel */
  1553.   init_waitqueue_head(&irnet_events.rwait);
  1554.   irnet_events.index = 0;
  1555.   /* Init spinlock for event logging */
  1556.   spin_lock_init(&irnet_events.spinlock);
  1557. #ifdef CONFIG_PROC_FS
  1558.   /* Add a /proc file for irnet infos */
  1559.   create_proc_info_entry("irnet", 0, proc_irda, irnet_proc_read);
  1560. #endif /* CONFIG_PROC_FS */
  1561.   /* Setup the IrNET server */
  1562.   err = irnet_setup_server();
  1563.   if(!err)
  1564.     /* We are no longer functional... */
  1565.     irnet_server.running = 1;
  1566.   DEXIT(MODULE_TRACE, "n");
  1567.   return err;
  1568. }
  1569. /*------------------------------------------------------------------*/
  1570. /*
  1571.  * Cleanup at exit...
  1572.  */
  1573. void
  1574. irda_irnet_cleanup(void)
  1575. {
  1576.   DENTER(MODULE_TRACE, "()n");
  1577.   /* We are no longer there... */
  1578.   irnet_server.running = 0;
  1579. #ifdef CONFIG_PROC_FS
  1580.   /* Remove our /proc file */
  1581.   remove_proc_entry("irnet", proc_irda);
  1582. #endif /* CONFIG_PROC_FS */
  1583.   /* Remove our IrNET server from existence */
  1584.   irnet_destroy_server();
  1585.   /* Remove all instances of IrNET socket still present */
  1586.   hashbin_delete(irnet_server.list, (FREE_FUNC) irda_irnet_destroy);
  1587.   DEXIT(MODULE_TRACE, "n");
  1588. }