Hi...

        Boy, it took me a bit of time, but now I've got
patch-2.2.13-irda10 working for me. Dag was right when he mentionned a
work in progress. See patch attached...
        Fixed :
        o wrong types in irda.h prevent compilation
        o typo in wrapper.c & actisys.c
        o create SEQPACKET with correct operations
        o auto-connect

        All is not perfect, though. Using SOCK_DGRAM (unitdata), the
first byte of every received packet is scrapped (missing - I suspect
the receiver path).
        And also, connect seems a bit flaky :
-----------------------------
irlap_state_ndm(), media busy!
irlap_state_ndm(), media busy!
irlmp_state_setup_pend() WATCHDOG_TIMEOUT!
irda_get_value_confirm(), IAS query failed!
irda_connect(), connect failed!
irlap_state_ndm(), media busy!
-----------------------------

        Have fun...

        Jean
diff -u -p linux/include/linux/irda.dag.h linux/include/linux/irda.h
--- linux/include/linux/irda.dag.h      Wed Dec  8 07:53:59 1999
+++ linux/include/linux/irda.h  Wed Dec  8 08:30:47 1999
@@ -22,6 +22,8 @@
  *
  ********************************************************************/
 
+#include <linux/types.h>               /* for __u8, __u32 & ... */
+
 #ifndef KERNEL_IRDA_H
 #define KERNEL_IRDA_H
 
@@ -69,11 +71,11 @@ typedef enum {
 } IRDA_DONGLE;
 
 /* Protocol types to be used for SOCK_DGRAM */
-enum {
+typedef enum {
        IRDAPROTO_UNITDATA = 0,
        IRDAPROTO_ULTRA    = 1,
        IRDAPROTO_MAX
-};
+} IRDA_DGRAM_PROTOCOLS;
 
 #define SOL_IRLMP      266 /* Same as SOL_IRDA for now */
 #define SOL_IRTTP      266 /* Same as SOL_IRDA for now */
@@ -96,21 +98,21 @@ enum {
 
 struct sockaddr_irda {
        sa_family_t   sir_family;   /* AF_IRDA */
-       uint8_t       sir_lsap_sel; /* LSAP selector */
-       uint32_t      sir_addr;     /* Device address */
+       __u8          sir_lsap_sel; /* LSAP selector */
+       __u32         sir_addr;     /* Device address */
        char          sir_name[25]; /* Usually <service>:IrDA:TinyTP */
 };
 
 struct irda_device_info {
-       uint32_t      saddr;    /* Address of local interface */
-       uint32_t      daddr;    /* Address of remote device */
+       __u32         saddr;    /* Address of local interface */
+       __u32         daddr;    /* Address of remote device */
        char          info[22]; /* Description */
-       uint8_t       charset;  /* Charset used for description */
-       uint8_t       hints[2]; /* Hint bits */
+       __u8          charset;  /* Charset used for description */
+       __u8          hints[2]; /* Hint bits */
 };
 
 struct irda_device_list {
-       uint32_t len;
+       __u32  len;
        struct irda_device_info dev[1];
 };
 
diff -u -p linux/drivers/net/irda/actisys.dag2.c linux/drivers/net/irda/actisys.c
--- linux/drivers/net/irda/actisys.dag2.c       Wed Dec  8 07:15:34 1999
+++ linux/drivers/net/irda/actisys.c    Wed Dec  8 07:16:28 1999
@@ -163,7 +163,7 @@ static int actisys_change_speed(struct i
 {
        dongle_t *self = (dongle_t *) task->instance;
        __u32 speed = (__u32) task->param;      /* Target speed */
-        int index = 0;
+        int i = 0;
        int ret = 0;
        
         IRDA_DEBUG(4, __FUNCTION__ "(), speed=%d (was %d)\n", speed, 
diff -u -p linux/net/irda/wrapper.dag2.c linux/net/irda/wrapper.c
--- linux/net/irda/wrapper.dag2.c       Wed Dec  8 07:22:03 1999
+++ linux/net/irda/wrapper.c    Wed Dec  8 07:24:52 1999
@@ -220,7 +220,7 @@ static void state_outside_frame(struct d
                rx_buff->state = BEGIN_FRAME;
                rx_buff->in_frame = TRUE;
                
-               /* Set mbusy when SOP and prev char not SOP (IrLAP 6.13.3)
+               /* Set mbusy when SOP and prev char not SOP (IrLAP 6.13.3) */
                irda_device_set_media_busy(dev, TRUE);
                break;
        case XBOF:
@@ -285,6 +285,8 @@ static void state_link_escape(struct dev
 {
        switch (byte) {
        case BOF: /* New frame? */
+               IRDA_DEBUG(1, __FUNCTION__ 
+                          "(), Discarding incomplete frame\n");
                rx_buff->state = BEGIN_FRAME;
                irda_device_set_media_busy(dev, TRUE);
                break;
@@ -326,6 +328,8 @@ static void state_inside_frame(struct de
 
        switch (byte) {
        case BOF: /* New frame? */
+               IRDA_DEBUG(1, __FUNCTION__ 
+                          "(), Discarding incomplete frame\n");
                rx_buff->state = BEGIN_FRAME;
                irda_device_set_media_busy(dev, TRUE);
                break;
diff -u -p linux/net/irda/af_irda.dag4.c linux/net/irda/af_irda.c
--- linux/net/irda/af_irda.dag4.c       Wed Dec  8 07:33:10 1999
+++ linux/net/irda/af_irda.c    Wed Dec  8 08:50:42 1999
@@ -484,6 +484,77 @@ static int irda_find_lsap_sel(struct ird
 }
 
 /*
+ * Function irda_discover_daddr_and_lsap_sel (self, name)
+ *
+ *    This try to find a device with the requested service.
+ *
+ * It basically look into the discovery log. For each address in the list,
+ * it queries the LM-IAS of the device to find if this device offer
+ * the requested service.
+ * At the first node that support the service requested, the function
+ * set both the destination address and the lsap selector to point
+ * on the service on that device.
+ */
+static int irda_discover_daddr_and_lsap_sel(struct irda_sock *self, char *name)
+{
+       discovery_t *discovery;
+       int err = -ENETUNREACH;
+
+       IRDA_DEBUG(2, __FUNCTION__ "(), name=%s\n", name);
+
+       ASSERT(self != NULL, return -1;);
+
+       /* Tell IrLMP we want to be notified */
+       irlmp_update_client(self->ckey, self->mask, NULL, 
+                           irda_discovery_indication);
+       
+       /* Do some discovery */
+       irlmp_discovery_request(self->nslots);
+               
+       /* Check if the we got some results */
+       if (!cachelog)
+               /* Wait for answer */
+               /*interruptible_sleep_on(&self->discovery_wait);*/
+               return -EAGAIN;
+
+       /* 
+        * Now, check all discovered devices (if any), and connect
+        * client only about the services that the client is
+        * interested in 
+        */
+       discovery = (discovery_t *) hashbin_get_first(cachelog);
+       while (discovery != NULL) {
+               /* Mask out the ones we don't want */
+               if (discovery->hints.word & self->mask) {
+                       /* Try this address */
+                       self->daddr = discovery->daddr;
+                       IRDA_DEBUG(1, __FUNCTION__ "(), trying daddr = %08x\n", 
+self->daddr);
+
+                       /* Query remote LM-IAS for this service */
+                       err = irda_find_lsap_sel(self, name);
+                       if (err == 0)
+                               /* We found the requested service */
+                               break;
+               }
+
+               /* Next node, maybe we will be more lucky...  */
+               discovery = (discovery_t *) hashbin_get_next(cachelog);
+       }
+       cachelog = NULL;
+
+       /* Check out what we found */
+       if(err) {
+               IRDA_DEBUG(0, __FUNCTION__ "(), cannot discover requested service 
+''%s'' in any discovered device !!!\n", name);
+               self->daddr = 0;        /* Guessing */
+               return(err);
+       }
+
+       IRDA_DEBUG(0, __FUNCTION__ "(), discovered requested service ''%s'' at address 
+%08x\n", name, self->daddr);
+
+       return 0;
+}
+
+/*
  * Function irda_getname (sock, uaddr, uaddr_len, peer)
  *
  *    Return the our own, or peers socket address (sockaddr_irda)
@@ -735,17 +806,25 @@ static int irda_connect(struct socket *s
                return -EINVAL;
 
        /* Check if user supplied the required destination device address */
-       if (!addr->sir_addr)
-               return -EINVAL;
-
-       self->daddr = addr->sir_addr;
-       IRDA_DEBUG(1, __FUNCTION__ "(), daddr = %08x\n", self->daddr);
-
-       /* Query remote LM-IAS */
-       err = irda_find_lsap_sel(self, addr->sir_name);
-       if (err) {
-               IRDA_DEBUG(0, __FUNCTION__ "(), connect failed!\n");
-               return err;
+       if (!addr->sir_addr) {
+               /* Try to find one suitable */
+               err = irda_discover_daddr_and_lsap_sel(self, addr->sir_name);
+               if (err) {
+                       IRDA_DEBUG(0, __FUNCTION__ "(), auto-connect failed!\n");
+                       return -EINVAL;
+               }
+       }
+       else {
+               /* Use the one provided by the user */
+               self->daddr = addr->sir_addr;
+               IRDA_DEBUG(1, __FUNCTION__ "(), daddr = %08x\n", self->daddr);
+
+               /* Query remote LM-IAS */
+               err = irda_find_lsap_sel(self, addr->sir_name);
+               if (err) {
+                       IRDA_DEBUG(0, __FUNCTION__ "(), connect failed!\n");
+                       return err;
+               }
        }
 
        /* Check if we have opened a local TSAP */
@@ -838,6 +917,7 @@ static int irda_create(struct socket *so
        case SOCK_SEQPACKET:
                sock->ops = &irda_seqpacket_ops;
                self->max_sdu_size_rx = TTP_SAR_UNBOUND;
+               break;
        case SOCK_DGRAM:
                switch (protocol) {
                case IRDAPROTO_ULTRA:
@@ -1043,6 +1123,9 @@ static int irda_recvmsg_dgram(struct soc
        copied     = skb->len;
        
        if (copied > size) {
+               IRDA_DEBUG(2, __FUNCTION__ 
+                          "(), Received truncated frame (%d < %d)!\n",
+                          copied, size);
                copied = size;
                msg->msg_flags |= MSG_TRUNC;
        }

Reply via email to