diff options
author | Samuel Ortiz <sameo@linux.intel.com> | 2012-10-16 15:01:40 +0200 |
---|---|---|
committer | Samuel Ortiz <sameo@linux.intel.com> | 2012-10-26 18:26:50 +0200 |
commit | 94f418a206648c9be6fd84d6681d6956b8f8b106 (patch) | |
tree | 2fba318547f6b1ad3d3b1324c8eb1e854acc0ca6 /net/nfc | |
parent | 31ca61a8dffa5c7171d00cfa40a2845e190863c0 (diff) | |
download | kernel_goldelico_gta04-94f418a206648c9be6fd84d6681d6956b8f8b106.zip kernel_goldelico_gta04-94f418a206648c9be6fd84d6681d6956b8f8b106.tar.gz kernel_goldelico_gta04-94f418a206648c9be6fd84d6681d6956b8f8b106.tar.bz2 |
NFC: UI frame sending routine implementation
UI frames still need to follow the MIU rule, and they need to use the
client passed dsap as the listening socket dsap is stuck on SDP.
Signed-off-by: Samuel Ortiz <sameo@linux.intel.com>
Diffstat (limited to 'net/nfc')
-rw-r--r-- | net/nfc/llcp/commands.c | 46 | ||||
-rw-r--r-- | net/nfc/llcp/llcp.h | 2 |
2 files changed, 48 insertions, 0 deletions
diff --git a/net/nfc/llcp/commands.c b/net/nfc/llcp/commands.c index 6db280d..7941535 100644 --- a/net/nfc/llcp/commands.c +++ b/net/nfc/llcp/commands.c @@ -579,6 +579,52 @@ int nfc_llcp_send_i_frame(struct nfc_llcp_sock *sock, return len; } +int nfc_llcp_send_ui_frame(struct nfc_llcp_sock *sock, u8 ssap, u8 dsap, + struct msghdr *msg, size_t len) +{ + struct sk_buff *pdu; + struct nfc_llcp_local *local; + size_t frag_len = 0, remaining_len; + u8 *msg_ptr; + int err; + + pr_debug("Send UI frame len %zd\n", len); + + local = sock->local; + if (local == NULL) + return -ENODEV; + + remaining_len = len; + msg_ptr = (u8 *) msg->msg_iov; + + while (remaining_len > 0) { + + frag_len = min_t(size_t, sock->miu, remaining_len); + + pr_debug("Fragment %zd bytes remaining %zd", + frag_len, remaining_len); + + pdu = nfc_alloc_send_skb(sock->dev, &sock->sk, MSG_DONTWAIT, + frag_len + LLCP_HEADER_SIZE, &err); + if (pdu == NULL) { + pr_err("Could not allocate PDU\n"); + continue; + } + + pdu = llcp_add_header(pdu, dsap, ssap, LLCP_PDU_UI); + + memcpy(skb_put(pdu, frag_len), msg_ptr, frag_len); + + /* No need to check for the peer RW for UI frames */ + skb_queue_tail(&local->tx_queue, pdu); + + remaining_len -= frag_len; + msg_ptr += frag_len; + } + + return len; +} + int nfc_llcp_send_rr(struct nfc_llcp_sock *sock) { struct sk_buff *skb; diff --git a/net/nfc/llcp/llcp.h b/net/nfc/llcp/llcp.h index e06d035..276da3a 100644 --- a/net/nfc/llcp/llcp.h +++ b/net/nfc/llcp/llcp.h @@ -221,6 +221,8 @@ int nfc_llcp_send_dm(struct nfc_llcp_local *local, u8 ssap, u8 dsap, u8 reason); int nfc_llcp_send_disconnect(struct nfc_llcp_sock *sock); int nfc_llcp_send_i_frame(struct nfc_llcp_sock *sock, struct msghdr *msg, size_t len); +int nfc_llcp_send_ui_frame(struct nfc_llcp_sock *sock, u8 ssap, u8 dsap, + struct msghdr *msg, size_t len); int nfc_llcp_send_rr(struct nfc_llcp_sock *sock); /* Socket API */ |