llcp_commands.c revision 427a2eb1f568c9c5934a36105232c94553db9b69
110e38391c0e242e53e30094f6c00553418ab2f2eDave Chinner/*
210e38391c0e242e53e30094f6c00553418ab2f2eDave Chinner * Copyright (C) 2011  Intel Corporation. All rights reserved.
310e38391c0e242e53e30094f6c00553418ab2f2eDave Chinner *
410e38391c0e242e53e30094f6c00553418ab2f2eDave Chinner * This program is free software; you can redistribute it and/or modify
510e38391c0e242e53e30094f6c00553418ab2f2eDave Chinner * it under the terms of the GNU General Public License as published by
610e38391c0e242e53e30094f6c00553418ab2f2eDave Chinner * the Free Software Foundation; either version 2 of the License, or
710e38391c0e242e53e30094f6c00553418ab2f2eDave Chinner * (at your option) any later version.
810e38391c0e242e53e30094f6c00553418ab2f2eDave Chinner *
910e38391c0e242e53e30094f6c00553418ab2f2eDave Chinner * This program is distributed in the hope that it will be useful,
1010e38391c0e242e53e30094f6c00553418ab2f2eDave Chinner * but WITHOUT ANY WARRANTY; without even the implied warranty of
1110e38391c0e242e53e30094f6c00553418ab2f2eDave Chinner * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
1210e38391c0e242e53e30094f6c00553418ab2f2eDave Chinner * GNU General Public License for more details.
1310e38391c0e242e53e30094f6c00553418ab2f2eDave Chinner *
1410e38391c0e242e53e30094f6c00553418ab2f2eDave Chinner * You should have received a copy of the GNU General Public License
1510e38391c0e242e53e30094f6c00553418ab2f2eDave Chinner * along with this program; if not, write to the
1610e38391c0e242e53e30094f6c00553418ab2f2eDave Chinner * Free Software Foundation, Inc.,
1710e38391c0e242e53e30094f6c00553418ab2f2eDave Chinner * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
1810e38391c0e242e53e30094f6c00553418ab2f2eDave Chinner */
1910e38391c0e242e53e30094f6c00553418ab2f2eDave Chinner
20239880ef6454ccff2ba8d762c3f86e8278f0ce1cDave Chinner#define pr_fmt(fmt) "llcp: %s: " fmt, __func__
21239880ef6454ccff2ba8d762c3f86e8278f0ce1cDave Chinner
2210e38391c0e242e53e30094f6c00553418ab2f2eDave Chinner#include <linux/init.h>
2310e38391c0e242e53e30094f6c00553418ab2f2eDave Chinner#include <linux/kernel.h>
2410e38391c0e242e53e30094f6c00553418ab2f2eDave Chinner#include <linux/module.h>
2510e38391c0e242e53e30094f6c00553418ab2f2eDave Chinner#include <linux/nfc.h>
2610e38391c0e242e53e30094f6c00553418ab2f2eDave Chinner
2710e38391c0e242e53e30094f6c00553418ab2f2eDave Chinner#include <net/nfc/nfc.h>
2810e38391c0e242e53e30094f6c00553418ab2f2eDave Chinner
29957935dcd8e11d6f789b4ed769b376040e15565bChristoph Hellwig#include "../nfc.h"
3010e38391c0e242e53e30094f6c00553418ab2f2eDave Chinner#include "llcp.h"
3110e38391c0e242e53e30094f6c00553418ab2f2eDave Chinner
3210e38391c0e242e53e30094f6c00553418ab2f2eDave Chinnerstatic u8 llcp_tlv_length[LLCP_TLV_MAX] = {
3310e38391c0e242e53e30094f6c00553418ab2f2eDave Chinner	0,
3410e38391c0e242e53e30094f6c00553418ab2f2eDave Chinner	1, /* VERSION */
353eff1268994f72266b660782e87f215720c29639Dave Chinner	2, /* MIUX */
36957935dcd8e11d6f789b4ed769b376040e15565bChristoph Hellwig	2, /* WKS */
373eff1268994f72266b660782e87f215720c29639Dave Chinner	1, /* LTO */
383eff1268994f72266b660782e87f215720c29639Dave Chinner	1, /* RW */
39957935dcd8e11d6f789b4ed769b376040e15565bChristoph Hellwig	0, /* SN */
4010e38391c0e242e53e30094f6c00553418ab2f2eDave Chinner	1, /* OPT */
4110e38391c0e242e53e30094f6c00553418ab2f2eDave Chinner	0, /* SDREQ */
4210e38391c0e242e53e30094f6c00553418ab2f2eDave Chinner	2, /* SDRES */
43957935dcd8e11d6f789b4ed769b376040e15565bChristoph Hellwig
4410e38391c0e242e53e30094f6c00553418ab2f2eDave Chinner};
4510e38391c0e242e53e30094f6c00553418ab2f2eDave Chinner
4610e38391c0e242e53e30094f6c00553418ab2f2eDave Chinnerstatic u8 llcp_tlv8(u8 *tlv, u8 type)
4710e38391c0e242e53e30094f6c00553418ab2f2eDave Chinner{
4810e38391c0e242e53e30094f6c00553418ab2f2eDave Chinner	if (tlv[0] != type || tlv[1] != llcp_tlv_length[tlv[0]])
4910e38391c0e242e53e30094f6c00553418ab2f2eDave Chinner		return 0;
5010e38391c0e242e53e30094f6c00553418ab2f2eDave Chinner
5110e38391c0e242e53e30094f6c00553418ab2f2eDave Chinner	return tlv[2];
5210e38391c0e242e53e30094f6c00553418ab2f2eDave Chinner}
53957935dcd8e11d6f789b4ed769b376040e15565bChristoph Hellwig
5410e38391c0e242e53e30094f6c00553418ab2f2eDave Chinnerstatic u8 llcp_tlv16(u8 *tlv, u8 type)
5510e38391c0e242e53e30094f6c00553418ab2f2eDave Chinner{
5610e38391c0e242e53e30094f6c00553418ab2f2eDave Chinner	if (tlv[0] != type || tlv[1] != llcp_tlv_length[tlv[0]])
5710e38391c0e242e53e30094f6c00553418ab2f2eDave Chinner		return 0;
5810e38391c0e242e53e30094f6c00553418ab2f2eDave Chinner
5910e38391c0e242e53e30094f6c00553418ab2f2eDave Chinner	return be16_to_cpu(*((__be16 *)(tlv + 2)));
6010e38391c0e242e53e30094f6c00553418ab2f2eDave Chinner}
6110e38391c0e242e53e30094f6c00553418ab2f2eDave Chinner
6210e38391c0e242e53e30094f6c00553418ab2f2eDave Chinner
6310e38391c0e242e53e30094f6c00553418ab2f2eDave Chinnerstatic u8 llcp_tlv_version(u8 *tlv)
6410e38391c0e242e53e30094f6c00553418ab2f2eDave Chinner{
6510e38391c0e242e53e30094f6c00553418ab2f2eDave Chinner	return llcp_tlv8(tlv, LLCP_TLV_VERSION);
6610e38391c0e242e53e30094f6c00553418ab2f2eDave Chinner}
6710e38391c0e242e53e30094f6c00553418ab2f2eDave Chinner
68957935dcd8e11d6f789b4ed769b376040e15565bChristoph Hellwigstatic u16 llcp_tlv_miux(u8 *tlv)
6910e38391c0e242e53e30094f6c00553418ab2f2eDave Chinner{
7010e38391c0e242e53e30094f6c00553418ab2f2eDave Chinner	return llcp_tlv16(tlv, LLCP_TLV_MIUX) & 0x7f;
7110e38391c0e242e53e30094f6c00553418ab2f2eDave Chinner}
7210e38391c0e242e53e30094f6c00553418ab2f2eDave Chinner
7310e38391c0e242e53e30094f6c00553418ab2f2eDave Chinnerstatic u16 llcp_tlv_wks(u8 *tlv)
7410e38391c0e242e53e30094f6c00553418ab2f2eDave Chinner{
7510e38391c0e242e53e30094f6c00553418ab2f2eDave Chinner	return llcp_tlv16(tlv, LLCP_TLV_WKS);
760c9ba97318fc9a905bcc1419b6966de061203a70Alex Elder}
7710e38391c0e242e53e30094f6c00553418ab2f2eDave Chinner
7810e38391c0e242e53e30094f6c00553418ab2f2eDave Chinnerstatic u16 llcp_tlv_lto(u8 *tlv)
79e69522a8cc51fbefbfe9d178ad177f7b6ca00ebdJoe Perches{
800c9ba97318fc9a905bcc1419b6966de061203a70Alex Elder	return llcp_tlv8(tlv, LLCP_TLV_LTO);
8110e38391c0e242e53e30094f6c00553418ab2f2eDave Chinner}
8210e38391c0e242e53e30094f6c00553418ab2f2eDave Chinner
8310e38391c0e242e53e30094f6c00553418ab2f2eDave Chinnerstatic u8 llcp_tlv_opt(u8 *tlv)
8410e38391c0e242e53e30094f6c00553418ab2f2eDave Chinner{
8510e38391c0e242e53e30094f6c00553418ab2f2eDave Chinner	return llcp_tlv8(tlv, LLCP_TLV_OPT);
8610e38391c0e242e53e30094f6c00553418ab2f2eDave Chinner}
8710e38391c0e242e53e30094f6c00553418ab2f2eDave Chinner
88957935dcd8e11d6f789b4ed769b376040e15565bChristoph Hellwigstatic u8 llcp_tlv_rw(u8 *tlv)
8910e38391c0e242e53e30094f6c00553418ab2f2eDave Chinner{
9010e38391c0e242e53e30094f6c00553418ab2f2eDave Chinner	return llcp_tlv8(tlv, LLCP_TLV_RW) & 0xf;
910c9ba97318fc9a905bcc1419b6966de061203a70Alex Elder}
9210e38391c0e242e53e30094f6c00553418ab2f2eDave Chinner
939130090b5f04f7e7bc29b944e0b1ba494fff3f98Dave Chinneru8 *nfc_llcp_build_tlv(u8 type, u8 *value, u8 value_length, u8 *tlv_length)
949130090b5f04f7e7bc29b944e0b1ba494fff3f98Dave Chinner{
95742ae1e35b038ed65ddd86182723441ea74db765Dave Chinner	u8 *tlv, length;
96742ae1e35b038ed65ddd86182723441ea74db765Dave Chinner
97742ae1e35b038ed65ddd86182723441ea74db765Dave Chinner	pr_debug("type %d\n", type);
98742ae1e35b038ed65ddd86182723441ea74db765Dave Chinner
99742ae1e35b038ed65ddd86182723441ea74db765Dave Chinner	if (type >= LLCP_TLV_MAX)
100742ae1e35b038ed65ddd86182723441ea74db765Dave Chinner		return NULL;
101742ae1e35b038ed65ddd86182723441ea74db765Dave Chinner
102742ae1e35b038ed65ddd86182723441ea74db765Dave Chinner	length = llcp_tlv_length[type];
1039130090b5f04f7e7bc29b944e0b1ba494fff3f98Dave Chinner	if (length == 0 && value_length == 0)
1049130090b5f04f7e7bc29b944e0b1ba494fff3f98Dave Chinner		return NULL;
1059130090b5f04f7e7bc29b944e0b1ba494fff3f98Dave Chinner	else
1069130090b5f04f7e7bc29b944e0b1ba494fff3f98Dave Chinner		length = value_length;
1079130090b5f04f7e7bc29b944e0b1ba494fff3f98Dave Chinner
1089130090b5f04f7e7bc29b944e0b1ba494fff3f98Dave Chinner	*tlv_length = 2 + length;
1099130090b5f04f7e7bc29b944e0b1ba494fff3f98Dave Chinner	tlv = kzalloc(2 + length, GFP_KERNEL);
1109130090b5f04f7e7bc29b944e0b1ba494fff3f98Dave Chinner	if (tlv == NULL)
1119130090b5f04f7e7bc29b944e0b1ba494fff3f98Dave Chinner		return tlv;
1129130090b5f04f7e7bc29b944e0b1ba494fff3f98Dave Chinner
1139130090b5f04f7e7bc29b944e0b1ba494fff3f98Dave Chinner	tlv[0] = type;
1149130090b5f04f7e7bc29b944e0b1ba494fff3f98Dave Chinner	tlv[1] = length;
115	memcpy(tlv + 2, value, length);
116
117	return tlv;
118}
119
120int nfc_llcp_parse_tlv(struct nfc_llcp_local *local,
121		       u8 *tlv_array, u16 tlv_array_len)
122{
123	u8 *tlv = tlv_array, type, length, offset = 0;
124
125	pr_debug("TLV array length %d\n", tlv_array_len);
126
127	if (local == NULL)
128		return -ENODEV;
129
130	while (offset < tlv_array_len) {
131		type = tlv[0];
132		length = tlv[1];
133
134		pr_debug("type 0x%x length %d\n", type, length);
135
136		switch (type) {
137		case LLCP_TLV_VERSION:
138			local->remote_version = llcp_tlv_version(tlv);
139			break;
140		case LLCP_TLV_MIUX:
141			local->remote_miu = llcp_tlv_miux(tlv) + 128;
142			break;
143		case LLCP_TLV_WKS:
144			local->remote_wks = llcp_tlv_wks(tlv);
145			break;
146		case LLCP_TLV_LTO:
147			local->remote_lto = llcp_tlv_lto(tlv) * 10;
148			break;
149		case LLCP_TLV_OPT:
150			local->remote_opt = llcp_tlv_opt(tlv);
151			break;
152		case LLCP_TLV_RW:
153			local->remote_rw = llcp_tlv_rw(tlv);
154			break;
155		case LLCP_TLV_SN:
156			break;
157		default:
158			pr_err("Invalid gt tlv value 0x%x\n", type);
159			break;
160		}
161
162		offset += length + 2;
163		tlv += length + 2;
164	}
165
166	pr_debug("version 0x%x miu %d lto %d opt 0x%x wks 0x%x rw %d\n",
167		 local->remote_version, local->remote_miu,
168		 local->remote_lto, local->remote_opt,
169		 local->remote_wks, local->remote_rw);
170
171	return 0;
172}
173
174static struct sk_buff *llcp_add_header(struct sk_buff *pdu,
175				       u8 dsap, u8 ssap, u8 ptype)
176{
177	u8 header[2];
178
179	pr_debug("ptype 0x%x dsap 0x%x ssap 0x%x\n", ptype, dsap, ssap);
180
181	header[0] = (u8)((dsap << 2) | (ptype >> 2));
182	header[1] = (u8)((ptype << 6) | ssap);
183
184	pr_debug("header 0x%x 0x%x\n", header[0], header[1]);
185
186	memcpy(skb_put(pdu, LLCP_HEADER_SIZE), header, LLCP_HEADER_SIZE);
187
188	return pdu;
189}
190
191static struct sk_buff *llcp_add_tlv(struct sk_buff *pdu, u8 *tlv,
192				    u8 tlv_length)
193{
194	/* XXX Add an skb length check */
195
196	if (tlv == NULL)
197		return NULL;
198
199	memcpy(skb_put(pdu, tlv_length), tlv, tlv_length);
200
201	return pdu;
202}
203
204static struct sk_buff *llcp_allocate_pdu(struct nfc_llcp_sock *sock,
205					 u8 cmd, u16 size)
206{
207	struct sk_buff *skb;
208	int err;
209
210	if (sock->ssap == 0)
211		return NULL;
212
213	skb = nfc_alloc_send_skb(sock->dev, &sock->sk, MSG_DONTWAIT,
214				 size + LLCP_HEADER_SIZE, &err);
215	if (skb == NULL) {
216		pr_err("Could not allocate PDU\n");
217		return NULL;
218	}
219
220	skb = llcp_add_header(skb, sock->dsap, sock->ssap, cmd);
221
222	return skb;
223}
224
225int nfc_llcp_disconnect(struct nfc_llcp_sock *sock)
226{
227	struct sk_buff *skb;
228	struct nfc_dev *dev;
229	struct nfc_llcp_local *local;
230	u16 size = 0;
231
232	pr_debug("Sending DISC\n");
233
234	local = sock->local;
235	if (local == NULL)
236		return -ENODEV;
237
238	dev = sock->dev;
239	if (dev == NULL)
240		return -ENODEV;
241
242	size += LLCP_HEADER_SIZE;
243	size += dev->tx_headroom + dev->tx_tailroom + NFC_HEADER_SIZE;
244
245	skb = alloc_skb(size, GFP_ATOMIC);
246	if (skb == NULL)
247		return -ENOMEM;
248
249	skb_reserve(skb, dev->tx_headroom + NFC_HEADER_SIZE);
250
251	skb = llcp_add_header(skb, sock->ssap, sock->dsap, LLCP_PDU_DISC);
252
253	skb_queue_tail(&local->tx_queue, skb);
254
255	return 0;
256}
257
258int nfc_llcp_send_symm(struct nfc_dev *dev)
259{
260	struct sk_buff *skb;
261	struct nfc_llcp_local *local;
262	u16 size = 0;
263
264	pr_debug("Sending SYMM\n");
265
266	local = nfc_llcp_find_local(dev);
267	if (local == NULL)
268		return -ENODEV;
269
270	size += LLCP_HEADER_SIZE;
271	size += dev->tx_headroom + dev->tx_tailroom + NFC_HEADER_SIZE;
272
273	skb = alloc_skb(size, GFP_KERNEL);
274	if (skb == NULL)
275		return -ENOMEM;
276
277	skb_reserve(skb, dev->tx_headroom + NFC_HEADER_SIZE);
278
279	skb = llcp_add_header(skb, 0, 0, LLCP_PDU_SYMM);
280
281	return nfc_data_exchange(dev, local->target_idx, skb,
282				 nfc_llcp_recv, local);
283}
284
285int nfc_llcp_send_connect(struct nfc_llcp_sock *sock)
286{
287	struct nfc_llcp_local *local;
288	struct sk_buff *skb;
289	u8 *service_name_tlv = NULL, service_name_tlv_length;
290	u8 *miux_tlv = NULL, miux_tlv_length;
291	u8 *rw_tlv = NULL, rw_tlv_length, rw;
292	__be16 miux;
293	int err;
294	u16 size = 0;
295
296	pr_debug("Sending CONNECT\n");
297
298	local = sock->local;
299	if (local == NULL)
300		return -ENODEV;
301
302	if (sock->service_name != NULL) {
303		service_name_tlv = nfc_llcp_build_tlv(LLCP_TLV_SN,
304						      sock->service_name,
305						      sock->service_name_len,
306						      &service_name_tlv_length);
307		size += service_name_tlv_length;
308	}
309
310	miux = cpu_to_be16(LLCP_MAX_MIUX);
311	miux_tlv = nfc_llcp_build_tlv(LLCP_TLV_MIUX, (u8 *)&miux, 0,
312				      &miux_tlv_length);
313	size += miux_tlv_length;
314
315	rw = LLCP_MAX_RW;
316	rw_tlv = nfc_llcp_build_tlv(LLCP_TLV_RW, &rw, 0, &rw_tlv_length);
317	size += rw_tlv_length;
318
319	pr_debug("SKB size %d SN length %zu\n", size, sock->service_name_len);
320
321	skb = llcp_allocate_pdu(sock, LLCP_PDU_CONNECT, size);
322	if (skb == NULL) {
323		err = -ENOMEM;
324		goto error_tlv;
325	}
326
327	if (service_name_tlv != NULL)
328		skb = llcp_add_tlv(skb, service_name_tlv,
329				   service_name_tlv_length);
330
331	skb = llcp_add_tlv(skb, miux_tlv, miux_tlv_length);
332	skb = llcp_add_tlv(skb, rw_tlv, rw_tlv_length);
333
334	skb_queue_tail(&local->tx_queue, skb);
335
336	return 0;
337
338error_tlv:
339	pr_err("error %d\n", err);
340
341	kfree(service_name_tlv);
342	kfree(miux_tlv);
343	kfree(rw_tlv);
344
345	return err;
346}
347
348int nfc_llcp_send_cc(struct nfc_llcp_sock *sock)
349{
350	struct nfc_llcp_local *local;
351	struct sk_buff *skb;
352	u8 *miux_tlv = NULL, miux_tlv_length;
353	u8 *rw_tlv = NULL, rw_tlv_length, rw;
354	__be16 miux;
355	int err;
356	u16 size = 0;
357
358	pr_debug("Sending CC\n");
359
360	local = sock->local;
361	if (local == NULL)
362		return -ENODEV;
363
364	miux = cpu_to_be16(LLCP_MAX_MIUX);
365	miux_tlv = nfc_llcp_build_tlv(LLCP_TLV_MIUX, (u8 *)&miux, 0,
366				      &miux_tlv_length);
367	size += miux_tlv_length;
368
369	rw = LLCP_MAX_RW;
370	rw_tlv = nfc_llcp_build_tlv(LLCP_TLV_RW, &rw, 0, &rw_tlv_length);
371	size += rw_tlv_length;
372
373	skb = llcp_allocate_pdu(sock, LLCP_PDU_CC, size);
374	if (skb == NULL) {
375		err = -ENOMEM;
376		goto error_tlv;
377	}
378
379	skb = llcp_add_tlv(skb, miux_tlv, miux_tlv_length);
380	skb = llcp_add_tlv(skb, rw_tlv, rw_tlv_length);
381
382	skb_queue_tail(&local->tx_queue, skb);
383
384	return 0;
385
386error_tlv:
387	pr_err("error %d\n", err);
388
389	kfree(miux_tlv);
390	kfree(rw_tlv);
391
392	return err;
393}
394
395int nfc_llcp_send_dm(struct nfc_llcp_local *local, u8 ssap, u8 dsap, u8 reason)
396{
397	struct sk_buff *skb;
398	struct nfc_dev *dev;
399	u16 size = 1; /* Reason code */
400
401	pr_debug("Sending DM reason 0x%x\n", reason);
402
403	if (local == NULL)
404		return -ENODEV;
405
406	dev = local->dev;
407	if (dev == NULL)
408		return -ENODEV;
409
410	size += LLCP_HEADER_SIZE;
411	size += dev->tx_headroom + dev->tx_tailroom + NFC_HEADER_SIZE;
412
413	skb = alloc_skb(size, GFP_KERNEL);
414	if (skb == NULL)
415		return -ENOMEM;
416
417	skb_reserve(skb, dev->tx_headroom + NFC_HEADER_SIZE);
418
419	skb = llcp_add_header(skb, ssap, dsap, LLCP_PDU_DM);
420
421	memcpy(skb_put(skb, 1), &reason, 1);
422
423	skb_queue_head(&local->tx_queue, skb);
424
425	return 0;
426}
427
428int nfc_llcp_send_disconnect(struct nfc_llcp_sock *sock)
429{
430	struct sk_buff *skb;
431	struct nfc_llcp_local *local;
432
433	pr_debug("Send DISC\n");
434
435	local = sock->local;
436	if (local == NULL)
437		return -ENODEV;
438
439	skb = llcp_allocate_pdu(sock, LLCP_PDU_DISC, 0);
440	if (skb == NULL)
441		return -ENOMEM;
442
443	skb_queue_head(&local->tx_queue, skb);
444
445	return 0;
446}
447
448int nfc_llcp_send_i_frame(struct nfc_llcp_sock *sock,
449			  struct msghdr *msg, size_t len)
450{
451	struct sk_buff *pdu;
452	struct sock *sk = &sock->sk;
453	struct nfc_llcp_local *local;
454	size_t frag_len = 0, remaining_len;
455	u8 *msg_data, *msg_ptr;
456
457	pr_debug("Send I frame len %zd\n", len);
458
459	local = sock->local;
460	if (local == NULL)
461		return -ENODEV;
462
463	msg_data = kzalloc(len, GFP_KERNEL);
464	if (msg_data == NULL)
465		return -ENOMEM;
466
467	if (memcpy_fromiovec(msg_data, msg->msg_iov, len)) {
468		kfree(msg_data);
469		return -EFAULT;
470	}
471
472	remaining_len = len;
473	msg_ptr = msg_data;
474
475	while (remaining_len > 0) {
476
477		frag_len = min_t(u16, local->remote_miu, remaining_len);
478
479		pr_debug("Fragment %zd bytes remaining %zd",
480			 frag_len, remaining_len);
481
482		pdu = llcp_allocate_pdu(sock, LLCP_PDU_I,
483					frag_len + LLCP_SEQUENCE_SIZE);
484		if (pdu == NULL)
485			return -ENOMEM;
486
487		skb_put(pdu, LLCP_SEQUENCE_SIZE);
488
489		memcpy(skb_put(pdu, frag_len), msg_ptr, frag_len);
490
491		skb_queue_head(&sock->tx_queue, pdu);
492
493		lock_sock(sk);
494
495		nfc_llcp_queue_i_frames(sock);
496
497		release_sock(sk);
498
499		remaining_len -= frag_len;
500		msg_ptr += len;
501	}
502
503	kfree(msg_data);
504
505	return 0;
506}
507
508int nfc_llcp_send_rr(struct nfc_llcp_sock *sock)
509{
510	struct sk_buff *skb;
511	struct nfc_llcp_local *local;
512
513	pr_debug("Send rr nr %d\n", sock->recv_n);
514
515	local = sock->local;
516	if (local == NULL)
517		return -ENODEV;
518
519	skb = llcp_allocate_pdu(sock, LLCP_PDU_RR, LLCP_SEQUENCE_SIZE);
520	if (skb == NULL)
521		return -ENOMEM;
522
523	skb_put(skb, LLCP_SEQUENCE_SIZE);
524
525	skb->data[2] = sock->recv_n % 16;
526
527	skb_queue_head(&local->tx_queue, skb);
528
529	return 0;
530}
531