1 /*********************************************************************
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: Thu Jul 8 13:44:20 1999
10 * Modified by: Dag Brattli <dagb@cs.uit.no>
12 * Copyright (c) 1998-1999 Dag Brattli <dagb@cs.uit.no>,
13 * All Rights Reserved.
15 * This program is free software; you can redistribute it and/or
16 * modify it under the terms of the GNU General Public License as
17 * published by the Free Software Foundation; either version 2 of
18 * the License, or (at your option) any later version.
20 * Neither Dag Brattli nor University of Tromsø admit liability nor
21 * provide warranty for any of this software. This material is
22 * provided "AS-IS" and at no charge.
24 ********************************************************************/
29 #include <asm/param.h> /* for HZ */
31 #include <linux/config.h>
32 #include <linux/types.h>
34 #include <net/irda/irda.h>
35 #include <net/irda/qos.h>
36 #include <net/irda/irlap.h>
37 #include <net/irda/irlmp_event.h>
38 #include <net/irda/irqueue.h>
39 #include <net/irda/discovery.h>
42 #define LSAP_MASK 0x7f
46 #define DEV_ADDR_ANY 0xffffffff
48 /* Predefined LSAPs used by the various servers */
49 #define TSAP_IRLAN 0x05
50 #define LSAP_IRLPT 0x06
51 #define TSAP_IROBEX 0x07
52 #define TSAP_IRCOMM 0x08
54 #define LMP_HEADER 2 /* Dest LSAP + Source LSAP */
55 #define LMP_CONTROL_HEADER 4
56 #define LMP_MAX_HEADER (LMP_CONTROL_HEADER+LAP_MAX_HEADER)
58 #define LM_MAX_CONNECTIONS 10
60 #define LM_IDLE_TIMEOUT 2*HZ /* 2 seconds for now */
77 typedef void (*DISCOVERY_CALLBACK1
) (discovery_t
*);
78 typedef void (*DISCOVERY_CALLBACK2
) (hashbin_t
*);
81 QUEUE queue
; /* Must be first */
83 __u16 hints
; /* Hint bits */
87 QUEUE queue
; /* Must be first */
91 DISCOVERY_CALLBACK1 callback1
;
92 DISCOVERY_CALLBACK2 callback2
;
95 struct lap_cb
; /* Forward decl. */
98 * Information about each logical LSAP connection
101 QUEUE queue
; /* Must be first */
107 struct irda_statistics stats
;
109 __u8 slsap_sel
; /* Source (this) LSAP address */
110 __u8 dlsap_sel
; /* Destination LSAP address (if connected) */
112 struct sk_buff
*tmp_skb
; /* Store skb here while connecting */
114 struct timer_list watchdog_timer
;
116 IRLMP_STATE lsap_state
; /* Connection state */
117 notify_t notify
; /* Indication/Confirm entry points */
118 struct qos_info qos
; /* QoS for this connection */
120 struct lap_cb
*lap
; /* Pointer to LAP connection structure */
124 * Information about each registred IrLAP layer
127 QUEUE queue
; /* Must be first */
130 int reason
; /* LAP disconnect reason */
132 IRLMP_STATE lap_state
;
134 struct irlap_cb
*irlap
; /* Instance of IrLAP layer */
135 hashbin_t
*lsaps
; /* LSAP associated with this link */
137 __u8 caddr
; /* Connection address */
138 __u32 saddr
; /* Source device address */
139 __u32 daddr
; /* Destination device address */
141 struct qos_info
*qos
; /* LAP QoS for this session */
142 struct timer_list idle_timer
;
146 * Used for caching the last slsap->dlsap->handle mapping
153 struct lsap_cb
*lsap
;
157 * Main structure for IrLMP
164 discovery_t discovery_cmd
; /* Discovery command to use by IrLAP */
165 discovery_t discovery_rsp
; /* Discovery response to use by IrLAP */
169 #ifdef CONFIG_IRDA_CACHE_LAST_LSAP
170 CACHE_ENTRY cache
; /* Caching last slsap->dlsap->handle mapping */
172 struct timer_list discovery_timer
;
174 hashbin_t
*links
; /* IrLAP connection table */
175 hashbin_t
*unconnected_lsaps
;
184 __u16_host_order hints
; /* Hint bits */
187 /* Prototype declarations */
188 int irlmp_init(void);
189 void irlmp_cleanup(void);
190 struct lsap_cb
*irlmp_open_lsap( __u8 slsap
, notify_t
*notify
);
191 void irlmp_close_lsap( struct lsap_cb
*self
);
193 __u16
irlmp_service_to_hint(int service
);
194 __u32
irlmp_register_service(__u16 hints
);
195 int irlmp_unregister_service(__u32 handle
);
196 __u32
irlmp_register_client(__u16 hint_mask
, DISCOVERY_CALLBACK1 callback1
,
197 DISCOVERY_CALLBACK2 callback2
);
198 int irlmp_unregister_client(__u32 handle
);
199 int irlmp_update_client(__u32 handle
, __u16 hint_mask
,
200 DISCOVERY_CALLBACK1
, DISCOVERY_CALLBACK2
);
202 void irlmp_register_link(struct irlap_cb
*, __u32 saddr
, notify_t
*);
203 void irlmp_unregister_link(__u32 saddr
);
205 int irlmp_connect_request(struct lsap_cb
*, __u8 dlsap_sel
,
206 __u32 saddr
, __u32 daddr
,
207 struct qos_info
*, struct sk_buff
*);
208 void irlmp_connect_indication(struct lsap_cb
*self
, struct sk_buff
*skb
);
209 int irlmp_connect_response(struct lsap_cb
*, struct sk_buff
*);
210 void irlmp_connect_confirm(struct lsap_cb
*, struct sk_buff
*);
211 struct lsap_cb
*irlmp_dup(struct lsap_cb
*self
, void *instance
);
213 void irlmp_disconnect_indication(struct lsap_cb
*self
, LM_REASON reason
,
214 struct sk_buff
*userdata
);
215 int irlmp_disconnect_request(struct lsap_cb
*, struct sk_buff
*userdata
);
217 void irlmp_discovery_confirm(hashbin_t
*discovery_log
);
218 void irlmp_discovery_request(int nslots
);
219 void irlmp_do_discovery(int nslots
);
220 discovery_t
*irlmp_get_discovery_response(void);
222 int irlmp_data_request(struct lsap_cb
*, struct sk_buff
*);
223 inline void irlmp_udata_request(struct lsap_cb
*, struct sk_buff
*);
224 inline void irlmp_data_indication(struct lsap_cb
*, struct sk_buff
*);
225 inline void irlmp_udata_indication(struct lsap_cb
*, struct sk_buff
*);
227 void irlmp_status_request(void);
228 void irlmp_status_indication(LINK_STATUS link
, LOCK_STATUS lock
);
230 int irlmp_slsap_inuse(__u8 slsap
);
231 __u8
irlmp_find_free_slsap(void);
232 LM_REASON
irlmp_convert_lap_reason(LAP_REASON
);
234 __u32
irlmp_get_saddr(struct lsap_cb
*self
);
235 __u32
irlmp_get_daddr(struct lsap_cb
*self
);
237 extern char *lmp_reasons
[];
238 extern int sysctl_discovery_timeout
;
239 extern int sysctl_discovery_slots
;
240 extern int sysctl_discovery
;
241 extern struct irlmp_cb
*irlmp
;
243 static inline hashbin_t
*irlmp_get_cachelog(void) { return irlmp
->cachelog
; }
245 static inline int irlmp_get_lap_tx_queue_len(struct lsap_cb
*self
)
247 ASSERT(self
!= NULL
, return 0;);
248 ASSERT(self
->lap
!= NULL
, return 0;);
249 ASSERT(self
->lap
->irlap
!= NULL
, return 0;);
251 return irlap_get_tx_queue_len(self
->lap
->irlap
);