Commit 56c6dd27 authored by Jean Tourrilhes's avatar Jean Tourrilhes Committed by Linus Torvalds

[IRDA]: Ultra sendto support.

<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.
parent f3016267
...@@ -237,7 +237,7 @@ int irlmp_udata_request(struct lsap_cb *, struct sk_buff *); ...@@ -237,7 +237,7 @@ int irlmp_udata_request(struct lsap_cb *, struct sk_buff *);
void irlmp_udata_indication(struct lsap_cb *, struct sk_buff *); void irlmp_udata_indication(struct lsap_cb *, struct sk_buff *);
#ifdef CONFIG_IRDA_ULTRA #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 *); void irlmp_connless_data_indication(struct lsap_cb *, struct sk_buff *);
#endif /* CONFIG_IRDA_ULTRA */ #endif /* CONFIG_IRDA_ULTRA */
......
...@@ -802,9 +802,6 @@ static int irda_bind(struct socket *sock, struct sockaddr *uaddr, int addr_len) ...@@ -802,9 +802,6 @@ static int irda_bind(struct socket *sock, struct sockaddr *uaddr, int addr_len)
if (err < 0) if (err < 0)
return err; 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 */ /* Pretend we are connected */
sock->state = SS_CONNECTED; sock->state = SS_CONNECTED;
sk->sk_state = TCP_ESTABLISHED; sk->sk_state = TCP_ESTABLISHED;
...@@ -1122,6 +1119,10 @@ static int irda_create(struct socket *sock, int protocol) ...@@ -1122,6 +1119,10 @@ static int irda_create(struct socket *sock, int protocol)
#ifdef CONFIG_IRDA_ULTRA #ifdef CONFIG_IRDA_ULTRA
case IRDAPROTO_ULTRA: case IRDAPROTO_ULTRA:
sock->ops = &irda_ultra_ops; 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; break;
#endif /* CONFIG_IRDA_ULTRA */ #endif /* CONFIG_IRDA_ULTRA */
case IRDAPROTO_UNITDATA: case IRDAPROTO_UNITDATA:
...@@ -1584,6 +1585,8 @@ static int irda_sendmsg_ultra(struct kiocb *iocb, struct socket *sock, ...@@ -1584,6 +1585,8 @@ static int irda_sendmsg_ultra(struct kiocb *iocb, struct socket *sock,
{ {
struct sock *sk = sock->sk; struct sock *sk = sock->sk;
struct irda_sock *self; struct irda_sock *self;
__u8 pid = 0;
int bound = 0;
struct sk_buff *skb; struct sk_buff *skb;
unsigned char *asmptr; unsigned char *asmptr;
int err; int err;
...@@ -1601,6 +1604,33 @@ static int irda_sendmsg_ultra(struct kiocb *iocb, struct socket *sock, ...@@ -1601,6 +1604,33 @@ static int irda_sendmsg_ultra(struct kiocb *iocb, struct socket *sock,
self = irda_sk(sk); self = irda_sk(sk);
ASSERT(self != NULL, return -1;); 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 * Check that we don't send out to big frames. This is an unreliable
* service, so we have no fragmentation and no coalescence * service, so we have no fragmentation and no coalescence
...@@ -1627,7 +1657,8 @@ static int irda_sendmsg_ultra(struct kiocb *iocb, struct socket *sock, ...@@ -1627,7 +1657,8 @@ static int irda_sendmsg_ultra(struct kiocb *iocb, struct socket *sock,
return err; return err;
} }
err = irlmp_connless_data_request(self->lsap, skb); err = irlmp_connless_data_request((bound ? self->lsap : NULL),
skb, pid);
if (err) { if (err) {
IRDA_DEBUG(0, "%s(), err=%d\n", __FUNCTION__, err); IRDA_DEBUG(0, "%s(), err=%d\n", __FUNCTION__, err);
return err; return err;
......
...@@ -1193,7 +1193,8 @@ void irlmp_udata_indication(struct lsap_cb *self, struct sk_buff *skb) ...@@ -1193,7 +1193,8 @@ void irlmp_udata_indication(struct lsap_cb *self, struct sk_buff *skb)
* Function irlmp_connless_data_request (self, skb) * Function irlmp_connless_data_request (self, skb)
*/ */
#ifdef CONFIG_IRDA_ULTRA #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 sk_buff *clone_skb;
struct lap_cb *lap; struct lap_cb *lap;
...@@ -1208,7 +1209,10 @@ int irlmp_connless_data_request(struct lsap_cb *self, struct sk_buff *userdata) ...@@ -1208,7 +1209,10 @@ int irlmp_connless_data_request(struct lsap_cb *self, struct sk_buff *userdata)
/* Insert protocol identifier */ /* Insert protocol identifier */
skb_push(userdata, LMP_PID_HEADER); skb_push(userdata, LMP_PID_HEADER);
if(self != NULL)
userdata->data[0] = self->pid; userdata->data[0] = self->pid;
else
userdata->data[0] = pid;
/* Connectionless sockets must use 0x70 */ /* Connectionless sockets must use 0x70 */
skb_push(userdata, LMP_HEADER); skb_push(userdata, LMP_HEADER);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment