]> git.neil.brown.name Git - history.git/commitdiff
[IRDA]: Ultra sendto support.
authorJean Tourrilhes <jt@bougret.jpl.hp.com>
Mon, 9 Feb 2004 10:35:34 +0000 (02:35 -0800)
committerLinus Torvalds <torvalds@home.osdl.org>
Mon, 9 Feb 2004 10:35:34 +0000 (02:35 -0800)
<Original patch from Stephen Hemminger>
o [CORRECT] Always initialise Ultra packet/header size.
o [CORRECT] Don't allow Ultra send on unbound sockets if no
dest address is given.
o [FEATURE] Properly support Ultra sendto on unbound sockets.

include/net/irda/irlmp.h
net/irda/af_irda.c
net/irda/irlmp.c

index 32bf8ea47d142be67f5197dc9cc02e5c617b7fad..d92b02561993316927e0c0771ef938c7ce4d20cf 100644 (file)
@@ -237,7 +237,7 @@ int  irlmp_udata_request(struct lsap_cb *, struct sk_buff *);
 void irlmp_udata_indication(struct lsap_cb *, struct sk_buff *);
 
 #ifdef CONFIG_IRDA_ULTRA
-int  irlmp_connless_data_request(struct lsap_cb *, struct sk_buff *);
+int  irlmp_connless_data_request(struct lsap_cb *, struct sk_buff *, __u8);
 void irlmp_connless_data_indication(struct lsap_cb *, struct sk_buff *);
 #endif /* CONFIG_IRDA_ULTRA */
 
index 3b4f9c49062fb5d107fdc293d203ef9673eff33f..8755709686a18beb68c17237f2362e16c6989609 100644 (file)
@@ -802,9 +802,6 @@ static int irda_bind(struct socket *sock, struct sockaddr *uaddr, int addr_len)
                if (err < 0)
                        return err;
 
-               self->max_data_size = ULTRA_MAX_DATA - LMP_PID_HEADER;
-               self->max_header_size = IRDA_MAX_HEADER + LMP_PID_HEADER;
-
                /* Pretend we are connected */
                sock->state = SS_CONNECTED;
                sk->sk_state   = TCP_ESTABLISHED;
@@ -1122,6 +1119,10 @@ static int irda_create(struct socket *sock, int protocol)
 #ifdef CONFIG_IRDA_ULTRA
                case IRDAPROTO_ULTRA:
                        sock->ops = &irda_ultra_ops;
+                       /* Initialise now, because we may send on unbound
+                        * sockets. Jean II */
+                       self->max_data_size = ULTRA_MAX_DATA - LMP_PID_HEADER;
+                       self->max_header_size = IRDA_MAX_HEADER + LMP_PID_HEADER;
                        break;
 #endif /* CONFIG_IRDA_ULTRA */
                case IRDAPROTO_UNITDATA:
@@ -1584,6 +1585,8 @@ static int irda_sendmsg_ultra(struct kiocb *iocb, struct socket *sock,
 {
        struct sock *sk = sock->sk;
        struct irda_sock *self;
+       __u8 pid = 0;
+       int bound = 0;
        struct sk_buff *skb;
        unsigned char *asmptr;
        int err;
@@ -1601,6 +1604,33 @@ static int irda_sendmsg_ultra(struct kiocb *iocb, struct socket *sock,
        self = irda_sk(sk);
        ASSERT(self != NULL, return -1;);
 
+       /* Check if an address was specified with sendto. Jean II */
+       if (msg->msg_name) {
+               struct sockaddr_irda *addr = (struct sockaddr_irda *) msg->msg_name;
+               /* Check address, extract pid. Jean II */
+               if (msg->msg_namelen < sizeof(*addr))
+                       return -EINVAL;
+               if (addr->sir_family != AF_IRDA)
+                       return -EINVAL;
+
+               pid = addr->sir_lsap_sel;
+               if (pid & 0x80) {
+                       IRDA_DEBUG(0, "%s(), extension in PID not supp!\n", __FUNCTION__);
+                       return -EOPNOTSUPP;
+               }
+       } else {
+               /* Check that the socket is properly bound to an Ultra
+                * port. Jean II */
+               if ((self->lsap == NULL) ||
+                   (sk->sk_state != TCP_ESTABLISHED)) {
+                       IRDA_DEBUG(0, "%s(), socket not bound to Ultra PID.\n",
+                                  __FUNCTION__);
+                       return -ENOTCONN;
+               }
+               /* Use PID from socket */
+               bound = 1;
+       }
+
        /*
         * Check that we don't send out to big frames. This is an unreliable
         * service, so we have no fragmentation and no coalescence
@@ -1627,7 +1657,8 @@ static int irda_sendmsg_ultra(struct kiocb *iocb, struct socket *sock,
                return err;
        }
 
-       err = irlmp_connless_data_request(self->lsap, skb);
+       err = irlmp_connless_data_request((bound ? self->lsap : NULL),
+                                         skb, pid);
        if (err) {
                IRDA_DEBUG(0, "%s(), err=%d\n", __FUNCTION__, err);
                return err;
index f702c9c304619c43b3a70c064573c485d0079407..fb7397480564fe78d555cb94df4f8217209fcb29 100644 (file)
@@ -1193,7 +1193,8 @@ void irlmp_udata_indication(struct lsap_cb *self, struct sk_buff *skb)
  * Function irlmp_connless_data_request (self, skb)
  */
 #ifdef CONFIG_IRDA_ULTRA
-int irlmp_connless_data_request(struct lsap_cb *self, struct sk_buff *userdata)
+int irlmp_connless_data_request(struct lsap_cb *self, struct sk_buff *userdata,
+                               __u8 pid)
 {
        struct sk_buff *clone_skb;
        struct lap_cb *lap;
@@ -1208,7 +1209,10 @@ int irlmp_connless_data_request(struct lsap_cb *self, struct sk_buff *userdata)
 
        /* Insert protocol identifier */
        skb_push(userdata, LMP_PID_HEADER);
-       userdata->data[0] = self->pid;
+       if(self != NULL)
+         userdata->data[0] = self->pid;
+       else
+         userdata->data[0] = pid;
 
        /* Connectionless sockets must use 0x70 */
        skb_push(userdata, LMP_HEADER);