diff options
Diffstat (limited to 'include/net/irda/irlmp.h')
-rw-r--r-- | include/net/irda/irlmp.h | 295 |
1 files changed, 295 insertions, 0 deletions
diff --git a/include/net/irda/irlmp.h b/include/net/irda/irlmp.h new file mode 100644 index 000000000000..86aefb1fda5e --- /dev/null +++ b/include/net/irda/irlmp.h | |||
@@ -0,0 +1,295 @@ | |||
1 | /********************************************************************* | ||
2 | * | ||
3 | * Filename: irlmp.h | ||
4 | * Version: 0.9 | ||
5 | * Description: IrDA Link Management Protocol (LMP) layer | ||
6 | * Status: Experimental. | ||
7 | * Author: Dag Brattli <dagb@cs.uit.no> | ||
8 | * Created at: Sun Aug 17 20:54:32 1997 | ||
9 | * Modified at: Fri Dec 10 13:23:01 1999 | ||
10 | * Modified by: Dag Brattli <dagb@cs.uit.no> | ||
11 | * | ||
12 | * Copyright (c) 1998-1999 Dag Brattli <dagb@cs.uit.no>, | ||
13 | * All Rights Reserved. | ||
14 | * Copyright (c) 2000-2002 Jean Tourrilhes <jt@hpl.hp.com> | ||
15 | * | ||
16 | * This program is free software; you can redistribute it and/or | ||
17 | * modify it under the terms of the GNU General Public License as | ||
18 | * published by the Free Software Foundation; either version 2 of | ||
19 | * the License, or (at your option) any later version. | ||
20 | * | ||
21 | * Neither Dag Brattli nor University of Tromsų admit liability nor | ||
22 | * provide warranty for any of this software. This material is | ||
23 | * provided "AS-IS" and at no charge. | ||
24 | * | ||
25 | ********************************************************************/ | ||
26 | |||
27 | #ifndef IRLMP_H | ||
28 | #define IRLMP_H | ||
29 | |||
30 | #include <asm/param.h> /* for HZ */ | ||
31 | |||
32 | #include <linux/config.h> | ||
33 | #include <linux/types.h> | ||
34 | |||
35 | #include <net/irda/irda.h> | ||
36 | #include <net/irda/qos.h> | ||
37 | #include <net/irda/irlap.h> /* LAP_MAX_HEADER, ... */ | ||
38 | #include <net/irda/irlmp_event.h> | ||
39 | #include <net/irda/irqueue.h> | ||
40 | #include <net/irda/discovery.h> | ||
41 | |||
42 | /* LSAP-SEL's */ | ||
43 | #define LSAP_MASK 0x7f | ||
44 | #define LSAP_IAS 0x00 | ||
45 | #define LSAP_ANY 0xff | ||
46 | #define LSAP_MAX 0x6f /* 0x70-0x7f are reserved */ | ||
47 | #define LSAP_CONNLESS 0x70 /* Connectionless LSAP, mostly used for Ultra */ | ||
48 | |||
49 | #define DEV_ADDR_ANY 0xffffffff | ||
50 | |||
51 | #define LMP_HEADER 2 /* Dest LSAP + Source LSAP */ | ||
52 | #define LMP_CONTROL_HEADER 4 | ||
53 | #define LMP_PID_HEADER 1 /* Used by Ultra */ | ||
54 | #define LMP_MAX_HEADER (LMP_CONTROL_HEADER+LAP_MAX_HEADER) | ||
55 | |||
56 | #define LM_MAX_CONNECTIONS 10 | ||
57 | |||
58 | #define LM_IDLE_TIMEOUT 2*HZ /* 2 seconds for now */ | ||
59 | |||
60 | typedef enum { | ||
61 | S_PNP = 0, | ||
62 | S_PDA, | ||
63 | S_COMPUTER, | ||
64 | S_PRINTER, | ||
65 | S_MODEM, | ||
66 | S_FAX, | ||
67 | S_LAN, | ||
68 | S_TELEPHONY, | ||
69 | S_COMM, | ||
70 | S_OBEX, | ||
71 | S_ANY, | ||
72 | S_END, | ||
73 | } SERVICE; | ||
74 | |||
75 | /* For selective discovery */ | ||
76 | typedef void (*DISCOVERY_CALLBACK1) (discinfo_t *, DISCOVERY_MODE, void *); | ||
77 | /* For expiry (the same) */ | ||
78 | typedef void (*DISCOVERY_CALLBACK2) (discinfo_t *, DISCOVERY_MODE, void *); | ||
79 | |||
80 | typedef struct { | ||
81 | irda_queue_t queue; /* Must be first */ | ||
82 | |||
83 | __u16_host_order hints; /* Hint bits */ | ||
84 | } irlmp_service_t; | ||
85 | |||
86 | typedef struct { | ||
87 | irda_queue_t queue; /* Must be first */ | ||
88 | |||
89 | __u16_host_order hint_mask; | ||
90 | |||
91 | DISCOVERY_CALLBACK1 disco_callback; /* Selective discovery */ | ||
92 | DISCOVERY_CALLBACK2 expir_callback; /* Selective expiration */ | ||
93 | void *priv; /* Used to identify client */ | ||
94 | } irlmp_client_t; | ||
95 | |||
96 | /* | ||
97 | * Information about each logical LSAP connection | ||
98 | */ | ||
99 | struct lsap_cb { | ||
100 | irda_queue_t queue; /* Must be first */ | ||
101 | magic_t magic; | ||
102 | |||
103 | unsigned long connected; /* set_bit used on this */ | ||
104 | int persistent; | ||
105 | |||
106 | __u8 slsap_sel; /* Source (this) LSAP address */ | ||
107 | __u8 dlsap_sel; /* Destination LSAP address (if connected) */ | ||
108 | #ifdef CONFIG_IRDA_ULTRA | ||
109 | __u8 pid; /* Used by connectionless LSAP */ | ||
110 | #endif /* CONFIG_IRDA_ULTRA */ | ||
111 | struct sk_buff *conn_skb; /* Store skb here while connecting */ | ||
112 | |||
113 | struct timer_list watchdog_timer; | ||
114 | |||
115 | IRLMP_STATE lsap_state; /* Connection state */ | ||
116 | notify_t notify; /* Indication/Confirm entry points */ | ||
117 | struct qos_info qos; /* QoS for this connection */ | ||
118 | |||
119 | struct lap_cb *lap; /* Pointer to LAP connection structure */ | ||
120 | }; | ||
121 | |||
122 | /* | ||
123 | * Used for caching the last slsap->dlsap->handle mapping | ||
124 | * | ||
125 | * We don't need to keep/match the remote address in the cache because | ||
126 | * we are associated with a specific LAP (which implies it). | ||
127 | * Jean II | ||
128 | */ | ||
129 | typedef struct { | ||
130 | int valid; | ||
131 | |||
132 | __u8 slsap_sel; | ||
133 | __u8 dlsap_sel; | ||
134 | struct lsap_cb *lsap; | ||
135 | } CACHE_ENTRY; | ||
136 | |||
137 | /* | ||
138 | * Information about each registred IrLAP layer | ||
139 | */ | ||
140 | struct lap_cb { | ||
141 | irda_queue_t queue; /* Must be first */ | ||
142 | magic_t magic; | ||
143 | |||
144 | int reason; /* LAP disconnect reason */ | ||
145 | |||
146 | IRLMP_STATE lap_state; | ||
147 | |||
148 | struct irlap_cb *irlap; /* Instance of IrLAP layer */ | ||
149 | hashbin_t *lsaps; /* LSAP associated with this link */ | ||
150 | struct lsap_cb *flow_next; /* Next lsap to be polled for Tx */ | ||
151 | |||
152 | __u8 caddr; /* Connection address */ | ||
153 | __u32 saddr; /* Source device address */ | ||
154 | __u32 daddr; /* Destination device address */ | ||
155 | |||
156 | struct qos_info *qos; /* LAP QoS for this session */ | ||
157 | struct timer_list idle_timer; | ||
158 | |||
159 | #ifdef CONFIG_IRDA_CACHE_LAST_LSAP | ||
160 | /* The lsap cache was moved from struct irlmp_cb to here because | ||
161 | * it must be associated with the specific LAP. Also, this | ||
162 | * improves performance. - Jean II */ | ||
163 | CACHE_ENTRY cache; /* Caching last slsap->dlsap->handle mapping */ | ||
164 | #endif | ||
165 | }; | ||
166 | |||
167 | /* | ||
168 | * Main structure for IrLMP | ||
169 | */ | ||
170 | struct irlmp_cb { | ||
171 | magic_t magic; | ||
172 | |||
173 | __u8 conflict_flag; | ||
174 | |||
175 | discovery_t discovery_cmd; /* Discovery command to use by IrLAP */ | ||
176 | discovery_t discovery_rsp; /* Discovery response to use by IrLAP */ | ||
177 | |||
178 | /* Last lsap picked automatically by irlmp_find_free_slsap() */ | ||
179 | int last_lsap_sel; | ||
180 | |||
181 | struct timer_list discovery_timer; | ||
182 | |||
183 | hashbin_t *links; /* IrLAP connection table */ | ||
184 | hashbin_t *unconnected_lsaps; | ||
185 | hashbin_t *clients; | ||
186 | hashbin_t *services; | ||
187 | |||
188 | hashbin_t *cachelog; /* Current discovery log */ | ||
189 | |||
190 | int running; | ||
191 | |||
192 | __u16_host_order hints; /* Hint bits */ | ||
193 | }; | ||
194 | |||
195 | /* Prototype declarations */ | ||
196 | int irlmp_init(void); | ||
197 | void irlmp_cleanup(void); | ||
198 | struct lsap_cb *irlmp_open_lsap(__u8 slsap, notify_t *notify, __u8 pid); | ||
199 | void irlmp_close_lsap( struct lsap_cb *self); | ||
200 | |||
201 | __u16 irlmp_service_to_hint(int service); | ||
202 | void *irlmp_register_service(__u16 hints); | ||
203 | int irlmp_unregister_service(void *handle); | ||
204 | void *irlmp_register_client(__u16 hint_mask, DISCOVERY_CALLBACK1 disco_clb, | ||
205 | DISCOVERY_CALLBACK2 expir_clb, void *priv); | ||
206 | int irlmp_unregister_client(void *handle); | ||
207 | int irlmp_update_client(void *handle, __u16 hint_mask, | ||
208 | DISCOVERY_CALLBACK1 disco_clb, | ||
209 | DISCOVERY_CALLBACK2 expir_clb, void *priv); | ||
210 | |||
211 | void irlmp_register_link(struct irlap_cb *, __u32 saddr, notify_t *); | ||
212 | void irlmp_unregister_link(__u32 saddr); | ||
213 | |||
214 | int irlmp_connect_request(struct lsap_cb *, __u8 dlsap_sel, | ||
215 | __u32 saddr, __u32 daddr, | ||
216 | struct qos_info *, struct sk_buff *); | ||
217 | void irlmp_connect_indication(struct lsap_cb *self, struct sk_buff *skb); | ||
218 | int irlmp_connect_response(struct lsap_cb *, struct sk_buff *); | ||
219 | void irlmp_connect_confirm(struct lsap_cb *, struct sk_buff *); | ||
220 | struct lsap_cb *irlmp_dup(struct lsap_cb *self, void *instance); | ||
221 | |||
222 | void irlmp_disconnect_indication(struct lsap_cb *self, LM_REASON reason, | ||
223 | struct sk_buff *userdata); | ||
224 | int irlmp_disconnect_request(struct lsap_cb *, struct sk_buff *userdata); | ||
225 | |||
226 | void irlmp_discovery_confirm(hashbin_t *discovery_log, DISCOVERY_MODE mode); | ||
227 | void irlmp_discovery_request(int nslots); | ||
228 | discinfo_t *irlmp_get_discoveries(int *pn, __u16 mask, int nslots); | ||
229 | void irlmp_do_expiry(void); | ||
230 | void irlmp_do_discovery(int nslots); | ||
231 | discovery_t *irlmp_get_discovery_response(void); | ||
232 | void irlmp_discovery_expiry(discinfo_t *expiry, int number); | ||
233 | |||
234 | int irlmp_data_request(struct lsap_cb *, struct sk_buff *); | ||
235 | void irlmp_data_indication(struct lsap_cb *, struct sk_buff *); | ||
236 | |||
237 | int irlmp_udata_request(struct lsap_cb *, struct sk_buff *); | ||
238 | void irlmp_udata_indication(struct lsap_cb *, struct sk_buff *); | ||
239 | |||
240 | #ifdef CONFIG_IRDA_ULTRA | ||
241 | int irlmp_connless_data_request(struct lsap_cb *, struct sk_buff *, __u8); | ||
242 | void irlmp_connless_data_indication(struct lsap_cb *, struct sk_buff *); | ||
243 | #endif /* CONFIG_IRDA_ULTRA */ | ||
244 | |||
245 | void irlmp_status_indication(struct lap_cb *, LINK_STATUS link, LOCK_STATUS lock); | ||
246 | void irlmp_flow_indication(struct lap_cb *self, LOCAL_FLOW flow); | ||
247 | |||
248 | LM_REASON irlmp_convert_lap_reason(LAP_REASON); | ||
249 | |||
250 | static inline __u32 irlmp_get_saddr(const struct lsap_cb *self) | ||
251 | { | ||
252 | return (self && self->lap) ? self->lap->saddr : 0; | ||
253 | } | ||
254 | |||
255 | static inline __u32 irlmp_get_daddr(const struct lsap_cb *self) | ||
256 | { | ||
257 | return (self && self->lap) ? self->lap->daddr : 0; | ||
258 | } | ||
259 | |||
260 | extern const char *irlmp_reasons[]; | ||
261 | extern int sysctl_discovery_timeout; | ||
262 | extern int sysctl_discovery_slots; | ||
263 | extern int sysctl_discovery; | ||
264 | extern int sysctl_lap_keepalive_time; /* in ms, default is LM_IDLE_TIMEOUT */ | ||
265 | extern struct irlmp_cb *irlmp; | ||
266 | |||
267 | /* Check if LAP queue is full. | ||
268 | * Used by IrTTP for low control, see comments in irlap.h - Jean II */ | ||
269 | static inline int irlmp_lap_tx_queue_full(struct lsap_cb *self) | ||
270 | { | ||
271 | if (self == NULL) | ||
272 | return 0; | ||
273 | if (self->lap == NULL) | ||
274 | return 0; | ||
275 | if (self->lap->irlap == NULL) | ||
276 | return 0; | ||
277 | |||
278 | return(IRLAP_GET_TX_QUEUE_LEN(self->lap->irlap) >= LAP_HIGH_THRESHOLD); | ||
279 | } | ||
280 | |||
281 | /* After doing a irlmp_dup(), this get one of the two socket back into | ||
282 | * a state where it's waiting incomming connections. | ||
283 | * Note : this can be used *only* if the socket is not yet connected | ||
284 | * (i.e. NO irlmp_connect_response() done on this socket). | ||
285 | * - Jean II */ | ||
286 | static inline void irlmp_listen(struct lsap_cb *self) | ||
287 | { | ||
288 | self->dlsap_sel = LSAP_ANY; | ||
289 | self->lap = NULL; | ||
290 | self->lsap_state = LSAP_DISCONNECTED; | ||
291 | /* Started when we received the LM_CONNECT_INDICATION */ | ||
292 | del_timer(&self->watchdog_timer); | ||
293 | } | ||
294 | |||
295 | #endif | ||