llcp.h 7.4 KB
Newer Older
S
Samuel Ortiz 已提交
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21
/*
 * Copyright (C) 2011  Intel Corporation. All rights reserved.
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the
 * Free Software Foundation, Inc.,
 * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
 */

enum llcp_state {
	LLCP_CONNECTED = 1, /* wait_for_packet() wants that */
22
	LLCP_CONNECTING,
23
	LLCP_DISCONNECTING,
S
Samuel Ortiz 已提交
24 25 26 27 28 29 30 31 32
	LLCP_CLOSED,
	LLCP_BOUND,
	LLCP_LISTEN,
};

#define LLCP_DEFAULT_LTO 100
#define LLCP_DEFAULT_RW  1
#define LLCP_DEFAULT_MIU 128

33 34 35
#define LLCP_MAX_LTO  0xff
#define LLCP_MAX_RW   15
#define LLCP_MAX_MIUX 0x7ff
36
#define LLCP_MAX_MIU (LLCP_MAX_MIUX + 128)
37

S
Samuel Ortiz 已提交
38 39 40 41 42
#define LLCP_WKS_NUM_SAP   16
#define LLCP_SDP_NUM_SAP   16
#define LLCP_LOCAL_NUM_SAP 32
#define LLCP_LOCAL_SAP_OFFSET (LLCP_WKS_NUM_SAP + LLCP_SDP_NUM_SAP)
#define LLCP_MAX_SAP (LLCP_WKS_NUM_SAP + LLCP_SDP_NUM_SAP + LLCP_LOCAL_NUM_SAP)
S
Samuel Ortiz 已提交
43
#define LLCP_SDP_UNBOUND   (LLCP_MAX_SAP + 1)
S
Samuel Ortiz 已提交
44 45 46

struct nfc_llcp_sock;

S
Samuel Ortiz 已提交
47 48 49 50 51
struct llcp_sock_list {
	struct hlist_head head;
	rwlock_t          lock;
};

52 53 54 55 56 57 58 59
struct nfc_llcp_sdp_tlv {
	u8 *tlv;
	u8 tlv_len;

	char *uri;
	u8 tid;
	u8 sap;

60 61
	unsigned long time;

62 63 64
	struct hlist_node node;
};

S
Samuel Ortiz 已提交
65 66 67 68
struct nfc_llcp_local {
	struct list_head list;
	struct nfc_dev *dev;

69 70
	struct kref ref;

S
Samuel Ortiz 已提交
71 72 73 74 75 76 77 78 79 80 81 82
	struct mutex sdp_lock;

	struct timer_list link_timer;
	struct sk_buff_head tx_queue;
	struct work_struct	 tx_work;
	struct work_struct	 rx_work;
	struct sk_buff *rx_pending;
	struct work_struct	 timeout_work;

	u32 target_idx;
	u8 rf_mode;
	u8 comm_mode;
83 84 85
	u8 lto;
	u8 rw;
	__be16 miux;
S
Samuel Ortiz 已提交
86 87 88
	unsigned long local_wks;      /* Well known services */
	unsigned long local_sdp;      /* Local services  */
	unsigned long local_sap; /* Local SAPs, not available for discovery */
S
Samuel Ortiz 已提交
89
	atomic_t local_sdp_cnt[LLCP_SDP_NUM_SAP];
S
Samuel Ortiz 已提交
90 91 92 93 94 95 96 97 98 99 100 101 102 103 104

	/* local */
	u8 gb[NFC_MAX_GT_LEN];
	u8 gb_len;

	/* remote */
	u8 remote_gb[NFC_MAX_GT_LEN];
	u8 remote_gb_len;

	u8  remote_version;
	u16 remote_miu;
	u16 remote_lto;
	u8  remote_opt;
	u16 remote_wks;

105 106
	struct mutex sdreq_lock;
	struct hlist_head pending_sdreqs;
107 108
	struct timer_list sdreq_timer;
	struct work_struct sdreq_timeout_work;
109 110
	u8 sdreq_next_tid;

S
Samuel Ortiz 已提交
111
	/* sockets array */
S
Samuel Ortiz 已提交
112 113
	struct llcp_sock_list sockets;
	struct llcp_sock_list connecting_sockets;
T
Thierry Escande 已提交
114
	struct llcp_sock_list raw_sockets;
S
Samuel Ortiz 已提交
115 116 117 118 119 120 121 122 123
};

struct nfc_llcp_sock {
	struct sock sk;
	struct nfc_dev *dev;
	struct nfc_llcp_local *local;
	u32 target_idx;
	u32 nfc_protocol;

124
	/* Link parameters */
S
Samuel Ortiz 已提交
125 126 127 128
	u8 ssap;
	u8 dsap;
	char *service_name;
	size_t service_name_len;
129
	u8 rw;
130
	__be16 miux;
131

132 133 134 135

	/* Remote link parameters */
	u8 remote_rw;
	u16 remote_miu;
S
Samuel Ortiz 已提交
136 137 138 139 140 141 142 143 144 145

	/* Link variables */
	u8 send_n;
	u8 send_ack_n;
	u8 recv_n;
	u8 recv_ack_n;

	/* Is the remote peer ready to receive */
	u8 remote_ready;

146 147 148
	/* Reserved source SAP */
	u8 reserved_ssap;

S
Samuel Ortiz 已提交
149 150 151 152 153 154 155
	struct sk_buff_head tx_queue;
	struct sk_buff_head tx_pending_queue;

	struct list_head accept_queue;
	struct sock *parent;
};

S
Samuel Ortiz 已提交
156 157 158 159 160 161 162
struct nfc_llcp_ui_cb {
	__u8 dsap;
	__u8 ssap;
};

#define nfc_llcp_ui_skb_cb(__skb) ((struct nfc_llcp_ui_cb *)&((__skb)->cb[0]))

S
Samuel Ortiz 已提交
163 164 165 166 167
#define nfc_llcp_sock(sk) ((struct nfc_llcp_sock *) (sk))
#define nfc_llcp_dev(sk)  (nfc_llcp_sock((sk))->dev)

#define LLCP_HEADER_SIZE   2
#define LLCP_SEQUENCE_SIZE 1
168
#define LLCP_AGF_PDU_HEADER_SIZE 2
S
Samuel Ortiz 已提交
169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214

/* LLCP versions: 1.1 is 1.0 plus SDP */
#define LLCP_VERSION_10 0x10
#define LLCP_VERSION_11 0x11

/* LLCP PDU types */
#define LLCP_PDU_SYMM     0x0
#define LLCP_PDU_PAX      0x1
#define LLCP_PDU_AGF      0x2
#define LLCP_PDU_UI       0x3
#define LLCP_PDU_CONNECT  0x4
#define LLCP_PDU_DISC     0x5
#define LLCP_PDU_CC       0x6
#define LLCP_PDU_DM       0x7
#define LLCP_PDU_FRMR     0x8
#define LLCP_PDU_SNL      0x9
#define LLCP_PDU_I        0xc
#define LLCP_PDU_RR       0xd
#define LLCP_PDU_RNR      0xe

/* Parameters TLV types */
#define LLCP_TLV_VERSION 0x1
#define LLCP_TLV_MIUX    0x2
#define LLCP_TLV_WKS     0x3
#define LLCP_TLV_LTO     0x4
#define LLCP_TLV_RW      0x5
#define LLCP_TLV_SN      0x6
#define LLCP_TLV_OPT     0x7
#define LLCP_TLV_SDREQ   0x8
#define LLCP_TLV_SDRES   0x9
#define LLCP_TLV_MAX     0xa

/* Well known LLCP SAP */
#define LLCP_SAP_SDP   0x1
#define LLCP_SAP_IP    0x2
#define LLCP_SAP_OBEX  0x3
#define LLCP_SAP_SNEP  0x4
#define LLCP_SAP_MAX   0xff

/* Disconnection reason code */
#define LLCP_DM_DISC    0x00
#define LLCP_DM_NOCONN  0x01
#define LLCP_DM_NOBOUND 0x02
#define LLCP_DM_REJ     0x03


S
Samuel Ortiz 已提交
215 216
void nfc_llcp_sock_link(struct llcp_sock_list *l, struct sock *s);
void nfc_llcp_sock_unlink(struct llcp_sock_list *l, struct sock *s);
217
void nfc_llcp_socket_remote_param_init(struct nfc_llcp_sock *sock);
S
Samuel Ortiz 已提交
218
struct nfc_llcp_local *nfc_llcp_find_local(struct nfc_dev *dev);
219 220
struct nfc_llcp_local *nfc_llcp_local_get(struct nfc_llcp_local *local);
int nfc_llcp_local_put(struct nfc_llcp_local *local);
S
Samuel Ortiz 已提交
221
u8 nfc_llcp_get_sdp_ssap(struct nfc_llcp_local *local,
S
Samuel Ortiz 已提交
222
			 struct nfc_llcp_sock *sock);
S
Samuel Ortiz 已提交
223 224
u8 nfc_llcp_get_local_ssap(struct nfc_llcp_local *local);
void nfc_llcp_put_ssap(struct nfc_llcp_local *local, u8 ssap);
225
int nfc_llcp_queue_i_frames(struct nfc_llcp_sock *sock);
T
Thierry Escande 已提交
226 227
void nfc_llcp_send_to_raw_sock(struct nfc_llcp_local *local,
			       struct sk_buff *skb, u8 direction);
S
Samuel Ortiz 已提交
228 229 230 231 232 233 234 235 236

/* Sock API */
struct sock *nfc_llcp_sock_alloc(struct socket *sock, int type, gfp_t gfp);
void nfc_llcp_sock_free(struct nfc_llcp_sock *sock);
void nfc_llcp_accept_unlink(struct sock *sk);
void nfc_llcp_accept_enqueue(struct sock *parent, struct sock *sk);
struct sock *nfc_llcp_accept_dequeue(struct sock *sk, struct socket *newsock);

/* TLV API */
237 238 239 240
int nfc_llcp_parse_gb_tlv(struct nfc_llcp_local *local,
			  u8 *tlv_array, u16 tlv_array_len);
int nfc_llcp_parse_connection_tlv(struct nfc_llcp_sock *sock,
				  u8 *tlv_array, u16 tlv_array_len);
S
Samuel Ortiz 已提交
241 242 243 244

/* Commands API */
void nfc_llcp_recv(void *data, struct sk_buff *skb, int err);
u8 *nfc_llcp_build_tlv(u8 type, u8 *value, u8 value_length, u8 *tlv_length);
245
struct nfc_llcp_sdp_tlv *nfc_llcp_build_sdres_tlv(u8 tid, u8 sap);
246 247
struct nfc_llcp_sdp_tlv *nfc_llcp_build_sdreq_tlv(u8 tid, char *uri,
						  size_t uri_len);
248
void nfc_llcp_free_sdp_tlv(struct nfc_llcp_sdp_tlv *sdp);
249
void nfc_llcp_free_sdp_tlv_list(struct hlist_head *sdp_head);
S
Samuel Ortiz 已提交
250 251 252 253
void nfc_llcp_recv(void *data, struct sk_buff *skb, int err);
int nfc_llcp_send_symm(struct nfc_dev *dev);
int nfc_llcp_send_connect(struct nfc_llcp_sock *sock);
int nfc_llcp_send_cc(struct nfc_llcp_sock *sock);
254 255
int nfc_llcp_send_snl_sdres(struct nfc_llcp_local *local,
			    struct hlist_head *tlv_list, size_t tlvs_len);
256 257
int nfc_llcp_send_snl_sdreq(struct nfc_llcp_local *local,
			    struct hlist_head *tlv_list, size_t tlvs_len);
S
Samuel Ortiz 已提交
258 259
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);
260
int nfc_llcp_send_i_frame(struct nfc_llcp_sock *sock,
S
Samuel Ortiz 已提交
261
			  struct msghdr *msg, size_t len);
262 263
int nfc_llcp_send_ui_frame(struct nfc_llcp_sock *sock, u8 ssap, u8 dsap,
			   struct msghdr *msg, size_t len);
264
int nfc_llcp_send_rr(struct nfc_llcp_sock *sock);
S
Samuel Ortiz 已提交
265 266 267 268

/* Socket API */
int __init nfc_llcp_sock_init(void);
void nfc_llcp_sock_exit(void);