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