1 /*********************************************************************
3 * Filename: irlmp_event.c
5 * Description: An IrDA LMP event driver for Linux
6 * Status: Experimental.
7 * Author: Dag Brattli <dagb@cs.uit.no>
8 * Created at: Mon Aug 4 20:40:53 1997
9 * Modified at: Tue Dec 14 23:04:16 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.
14 * Copyright (c) 2000-2003 Jean Tourrilhes <jt@hpl.hp.com>
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.
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.
25 ********************************************************************/
27 #include <linux/kernel.h>
29 #include <net/irda/irda.h>
30 #include <net/irda/timer.h>
31 #include <net/irda/irlap.h>
32 #include <net/irda/irlmp.h>
33 #include <net/irda/irlmp_frame.h>
34 #include <net/irda/irlmp_event.h>
36 const char *irlmp_state[] = {
42 const char *irlsap_state[] = {
46 "LSAP_DATA_TRANSFER_READY",
51 #ifdef CONFIG_IRDA_DEBUG
52 static const char *irlmp_event[] = {
55 "LM_CONNECT_RESPONSE",
56 "LM_CONNECT_INDICATION",
58 "LM_DISCONNECT_INDICATION",
59 "LM_DISCONNECT_REQUEST",
64 "LM_UDATA_INDICATION",
66 "LM_WATCHDOG_TIMEOUT",
69 "LM_LAP_CONNECT_REQUEST",
70 "LM_LAP_CONNECT_INDICATION",
71 "LM_LAP_CONNECT_CONFIRM",
72 "LM_LAP_DISCONNECT_INDICATION",
73 "LM_LAP_DISCONNECT_REQUEST",
74 "LM_LAP_DISCOVERY_REQUEST",
75 "LM_LAP_DISCOVERY_CONFIRM",
76 "LM_LAP_IDLE_TIMEOUT",
78 #endif /* CONFIG_IRDA_DEBUG */
80 /* LAP Connection control proto declarations */
81 static void irlmp_state_standby (struct lap_cb *, IRLMP_EVENT,
83 static void irlmp_state_u_connect(struct lap_cb *, IRLMP_EVENT,
85 static void irlmp_state_active (struct lap_cb *, IRLMP_EVENT,
88 /* LSAP Connection control proto declarations */
89 static int irlmp_state_disconnected(struct lsap_cb *, IRLMP_EVENT,
91 static int irlmp_state_connect (struct lsap_cb *, IRLMP_EVENT,
93 static int irlmp_state_connect_pend(struct lsap_cb *, IRLMP_EVENT,
95 static int irlmp_state_dtr (struct lsap_cb *, IRLMP_EVENT,
97 static int irlmp_state_setup (struct lsap_cb *, IRLMP_EVENT,
99 static int irlmp_state_setup_pend (struct lsap_cb *, IRLMP_EVENT,
102 static void (*lap_state[]) (struct lap_cb *, IRLMP_EVENT, struct sk_buff *) =
105 irlmp_state_u_connect,
109 static int (*lsap_state[])( struct lsap_cb *, IRLMP_EVENT, struct sk_buff *) =
111 irlmp_state_disconnected,
113 irlmp_state_connect_pend,
116 irlmp_state_setup_pend
119 static inline void irlmp_next_lap_state(struct lap_cb *self,
123 IRDA_DEBUG(4, "%s(), LMP LAP = %s\n", __FUNCTION__, irlmp_state[state]);
125 self->lap_state = state;
128 static inline void irlmp_next_lsap_state(struct lsap_cb *self,
132 IRDA_ASSERT(self != NULL, return;);
133 IRDA_DEBUG(4, "%s(), LMP LSAP = %s\n", __FUNCTION__, irlsap_state[state]);
135 self->lsap_state = state;
138 /* Do connection control events */
139 int irlmp_do_lsap_event(struct lsap_cb *self, IRLMP_EVENT event,
142 IRDA_ASSERT(self != NULL, return -1;);
143 IRDA_ASSERT(self->magic == LMP_LSAP_MAGIC, return -1;);
145 IRDA_DEBUG(4, "%s(), EVENT = %s, STATE = %s\n",
146 __FUNCTION__, irlmp_event[event], irlsap_state[ self->lsap_state]);
148 return (*lsap_state[self->lsap_state]) (self, event, skb);
152 * Function do_lap_event (event, skb, info)
154 * Do IrLAP control events
157 void irlmp_do_lap_event(struct lap_cb *self, IRLMP_EVENT event,
160 IRDA_ASSERT(self != NULL, return;);
161 IRDA_ASSERT(self->magic == LMP_LAP_MAGIC, return;);
163 IRDA_DEBUG(4, "%s(), EVENT = %s, STATE = %s\n", __FUNCTION__,
165 irlmp_state[self->lap_state]);
167 (*lap_state[self->lap_state]) (self, event, skb);
170 void irlmp_discovery_timer_expired(void *data)
172 IRDA_DEBUG(4, "%s()\n", __FUNCTION__);
174 /* We always cleanup the log (active & passive discovery) */
177 /* Active discovery is conditional */
178 if (sysctl_discovery)
179 irlmp_do_discovery(sysctl_discovery_slots);
182 irlmp_start_discovery_timer(irlmp, sysctl_discovery_timeout * HZ);
185 void irlmp_watchdog_timer_expired(void *data)
187 struct lsap_cb *self = (struct lsap_cb *) data;
189 IRDA_DEBUG(2, "%s()\n", __FUNCTION__);
191 IRDA_ASSERT(self != NULL, return;);
192 IRDA_ASSERT(self->magic == LMP_LSAP_MAGIC, return;);
194 irlmp_do_lsap_event(self, LM_WATCHDOG_TIMEOUT, NULL);
197 void irlmp_idle_timer_expired(void *data)
199 struct lap_cb *self = (struct lap_cb *) data;
201 IRDA_DEBUG(2, "%s()\n", __FUNCTION__);
203 IRDA_ASSERT(self != NULL, return;);
204 IRDA_ASSERT(self->magic == LMP_LAP_MAGIC, return;);
206 irlmp_do_lap_event(self, LM_LAP_IDLE_TIMEOUT, NULL);
210 * Send an event on all LSAPs attached to this LAP.
213 irlmp_do_all_lsap_event(hashbin_t * lsap_hashbin,
216 struct lsap_cb *lsap;
217 struct lsap_cb *lsap_next;
219 /* Note : this function use the new hashbin_find_next()
220 * function, instead of the old hashbin_get_next().
221 * This make sure that we are always pointing one lsap
222 * ahead, so that if the current lsap is removed as the
223 * result of sending the event, we don't care.
224 * Also, as we store the context ourselves, if an enumeration
225 * of the same lsap hashbin happens as the result of sending the
226 * event, we don't care.
227 * The only problem is if the next lsap is removed. In that case,
228 * hashbin_find_next() will return NULL and we will abort the
229 * enumeration. - Jean II */
231 /* Also : we don't accept any skb in input. We can *NOT* pass
232 * the same skb to multiple clients safely, we would need to
233 * skb_clone() it. - Jean II */
235 lsap = (struct lsap_cb *) hashbin_get_first(lsap_hashbin);
237 while (NULL != hashbin_find_next(lsap_hashbin,
240 (void *) &lsap_next) ) {
241 irlmp_do_lsap_event(lsap, event, NULL);
246 /*********************************************************************
248 * LAP connection control states
250 ********************************************************************/
253 * Function irlmp_state_standby (event, skb, info)
255 * STANDBY, The IrLAP connection does not exist.
258 static void irlmp_state_standby(struct lap_cb *self, IRLMP_EVENT event,
261 IRDA_DEBUG(4, "%s()\n", __FUNCTION__);
262 IRDA_ASSERT(self->irlap != NULL, return;);
265 case LM_LAP_DISCOVERY_REQUEST:
266 /* irlmp_next_station_state( LMP_DISCOVER); */
268 irlap_discovery_request(self->irlap, &irlmp->discovery_cmd);
270 case LM_LAP_CONNECT_INDICATION:
271 /* It's important to switch state first, to avoid IrLMP to
272 * think that the link is free since IrLMP may then start
273 * discovery before the connection is properly set up. DB.
275 irlmp_next_lap_state(self, LAP_ACTIVE);
277 /* Just accept connection TODO, this should be fixed */
278 irlap_connect_response(self->irlap, skb);
280 case LM_LAP_CONNECT_REQUEST:
281 IRDA_DEBUG(4, "%s() LS_CONNECT_REQUEST\n", __FUNCTION__);
283 irlmp_next_lap_state(self, LAP_U_CONNECT);
285 /* FIXME: need to set users requested QoS */
286 irlap_connect_request(self->irlap, self->daddr, NULL, 0);
288 case LM_LAP_DISCONNECT_INDICATION:
289 IRDA_DEBUG(4, "%s(), Error LM_LAP_DISCONNECT_INDICATION\n",
292 irlmp_next_lap_state(self, LAP_STANDBY);
295 IRDA_DEBUG(0, "%s(), Unknown event %s\n",
296 __FUNCTION__, irlmp_event[event]);
302 * Function irlmp_state_u_connect (event, skb, info)
304 * U_CONNECT, The layer above has tried to open an LSAP connection but
305 * since the IrLAP connection does not exist, we must first start an
306 * IrLAP connection. We are now waiting response from IrLAP.
308 static void irlmp_state_u_connect(struct lap_cb *self, IRLMP_EVENT event,
311 IRDA_DEBUG(2, "%s(), event=%s\n", __FUNCTION__, irlmp_event[event]);
314 case LM_LAP_CONNECT_INDICATION:
315 /* It's important to switch state first, to avoid IrLMP to
316 * think that the link is free since IrLMP may then start
317 * discovery before the connection is properly set up. DB.
319 irlmp_next_lap_state(self, LAP_ACTIVE);
321 /* Just accept connection TODO, this should be fixed */
322 irlap_connect_response(self->irlap, skb);
324 /* Tell LSAPs that they can start sending data */
325 irlmp_do_all_lsap_event(self->lsaps, LM_LAP_CONNECT_CONFIRM);
327 /* Note : by the time we get there (LAP retries and co),
328 * the lsaps may already have gone. This avoid getting stuck
329 * forever in LAP_ACTIVE state - Jean II */
330 if (HASHBIN_GET_SIZE(self->lsaps) == 0) {
331 IRDA_DEBUG(0, "%s() NO LSAPs !\n", __FUNCTION__);
332 irlmp_start_idle_timer(self, LM_IDLE_TIMEOUT);
335 case LM_LAP_CONNECT_REQUEST:
336 /* Already trying to connect */
338 case LM_LAP_CONNECT_CONFIRM:
339 /* For all lsap_ce E Associated do LS_Connect_confirm */
340 irlmp_next_lap_state(self, LAP_ACTIVE);
342 /* Tell LSAPs that they can start sending data */
343 irlmp_do_all_lsap_event(self->lsaps, LM_LAP_CONNECT_CONFIRM);
345 /* Note : by the time we get there (LAP retries and co),
346 * the lsaps may already have gone. This avoid getting stuck
347 * forever in LAP_ACTIVE state - Jean II */
348 if (HASHBIN_GET_SIZE(self->lsaps) == 0) {
349 IRDA_DEBUG(0, "%s() NO LSAPs !\n", __FUNCTION__);
350 irlmp_start_idle_timer(self, LM_IDLE_TIMEOUT);
353 case LM_LAP_DISCONNECT_INDICATION:
354 IRDA_DEBUG(4, "%s(), LM_LAP_DISCONNECT_INDICATION\n", __FUNCTION__);
355 irlmp_next_lap_state(self, LAP_STANDBY);
357 /* Send disconnect event to all LSAPs using this link */
358 irlmp_do_all_lsap_event(self->lsaps,
359 LM_LAP_DISCONNECT_INDICATION);
361 case LM_LAP_DISCONNECT_REQUEST:
362 IRDA_DEBUG(4, "%s(), LM_LAP_DISCONNECT_REQUEST\n", __FUNCTION__);
364 /* One of the LSAP did timeout or was closed, if it was
365 * the last one, try to get out of here - Jean II */
366 if (HASHBIN_GET_SIZE(self->lsaps) <= 1) {
367 irlap_disconnect_request(self->irlap);
371 IRDA_DEBUG(0, "%s(), Unknown event %s\n",
372 __FUNCTION__, irlmp_event[event]);
378 * Function irlmp_state_active (event, skb, info)
380 * ACTIVE, IrLAP connection is active
383 static void irlmp_state_active(struct lap_cb *self, IRLMP_EVENT event,
386 IRDA_DEBUG(4, "%s()\n", __FUNCTION__);
389 case LM_LAP_CONNECT_REQUEST:
390 IRDA_DEBUG(4, "%s(), LS_CONNECT_REQUEST\n", __FUNCTION__);
393 * IrLAP may have a pending disconnect. We tried to close
394 * IrLAP, but it was postponed because the link was
395 * busy or we were still sending packets. As we now
396 * need it, make sure it stays on. Jean II
398 irlap_clear_disconnect(self->irlap);
401 * LAP connection already active, just bounce back! Since we
402 * don't know which LSAP that tried to do this, we have to
403 * notify all LSAPs using this LAP, but that should be safe to
406 irlmp_do_all_lsap_event(self->lsaps, LM_LAP_CONNECT_CONFIRM);
408 /* Needed by connect indication */
409 irlmp_do_all_lsap_event(irlmp->unconnected_lsaps,
410 LM_LAP_CONNECT_CONFIRM);
413 case LM_LAP_DISCONNECT_REQUEST:
415 * Need to find out if we should close IrLAP or not. If there
416 * is only one LSAP connection left on this link, that LSAP
417 * must be the one that tries to close IrLAP. It will be
418 * removed later and moved to the list of unconnected LSAPs
420 if (HASHBIN_GET_SIZE(self->lsaps) > 0) {
421 /* Timer value is checked in irsysctl - Jean II */
422 irlmp_start_idle_timer(self, sysctl_lap_keepalive_time * HZ / 1000);
424 /* No more connections, so close IrLAP */
426 /* We don't want to change state just yet, because
427 * we want to reflect accurately the real state of
428 * the LAP, not the state we wish it was in,
429 * so that we don't lose LM_LAP_CONNECT_REQUEST.
430 * In some cases, IrLAP won't close the LAP
431 * immediately. For example, it might still be
432 * retrying packets or waiting for the pf bit.
433 * As the LAP always send a DISCONNECT_INDICATION
434 * in PCLOSE or SCLOSE, just change state on that.
436 irlap_disconnect_request(self->irlap);
439 case LM_LAP_IDLE_TIMEOUT:
440 if (HASHBIN_GET_SIZE(self->lsaps) == 0) {
441 /* Same reasoning as above - keep state */
442 irlap_disconnect_request(self->irlap);
445 case LM_LAP_DISCONNECT_INDICATION:
446 irlmp_next_lap_state(self, LAP_STANDBY);
448 /* In some case, at this point our side has already closed
449 * all lsaps, and we are waiting for the idle_timer to
450 * expire. If another device reconnect immediately, the
451 * idle timer will expire in the midle of the connection
452 * initialisation, screwing up things a lot...
453 * Therefore, we must stop the timer... */
454 irlmp_stop_idle_timer(self);
457 * Inform all connected LSAP's using this link
459 irlmp_do_all_lsap_event(self->lsaps,
460 LM_LAP_DISCONNECT_INDICATION);
462 /* Force an expiry of the discovery log.
463 * Now that the LAP is free, the system may attempt to
464 * connect to another device. Unfortunately, our entries
465 * are stale. There is a small window (<3s) before the
466 * normal discovery will run and where irlmp_connect_request()
467 * can get the wrong info, so make sure things get
468 * cleaned *NOW* ;-) - Jean II */
472 IRDA_DEBUG(0, "%s(), Unknown event %s\n",
473 __FUNCTION__, irlmp_event[event]);
478 /*********************************************************************
480 * LSAP connection control states
482 ********************************************************************/
485 * Function irlmp_state_disconnected (event, skb, info)
490 static int irlmp_state_disconnected(struct lsap_cb *self, IRLMP_EVENT event,
495 IRDA_DEBUG(4, "%s()\n", __FUNCTION__);
497 IRDA_ASSERT(self != NULL, return -1;);
498 IRDA_ASSERT(self->magic == LMP_LSAP_MAGIC, return -1;);
501 #ifdef CONFIG_IRDA_ULTRA
502 case LM_UDATA_INDICATION:
503 /* This is most bizzare. Those packets are aka unreliable
504 * connected, aka IrLPT or SOCK_DGRAM/IRDAPROTO_UNITDATA.
505 * Why do we pass them as Ultra ??? Jean II */
506 irlmp_connless_data_indication(self, skb);
508 #endif /* CONFIG_IRDA_ULTRA */
509 case LM_CONNECT_REQUEST:
510 IRDA_DEBUG(4, "%s(), LM_CONNECT_REQUEST\n", __FUNCTION__);
512 if (self->conn_skb) {
513 IRDA_WARNING("%s: busy with another request!\n",
517 /* Don't forget to refcount it (see irlmp_connect_request()) */
519 self->conn_skb = skb;
521 irlmp_next_lsap_state(self, LSAP_SETUP_PEND);
523 /* Start watchdog timer (5 secs for now) */
524 irlmp_start_watchdog_timer(self, 5*HZ);
526 irlmp_do_lap_event(self->lap, LM_LAP_CONNECT_REQUEST, NULL);
528 case LM_CONNECT_INDICATION:
529 if (self->conn_skb) {
530 IRDA_WARNING("%s: busy with another request!\n",
534 /* Don't forget to refcount it (see irlap_driver_rcv()) */
536 self->conn_skb = skb;
538 irlmp_next_lsap_state(self, LSAP_CONNECT_PEND);
540 /* Start watchdog timer
541 * This is not mentionned in the spec, but there is a rare
542 * race condition that can get the socket stuck.
543 * If we receive this event while our LAP is closing down,
544 * the LM_LAP_CONNECT_REQUEST get lost and we get stuck in
545 * CONNECT_PEND state forever.
546 * The other cause of getting stuck down there is if the
547 * higher layer never reply to the CONNECT_INDICATION.
548 * Anyway, it make sense to make sure that we always have
549 * a backup plan. 1 second is plenty (should be immediate).
551 irlmp_start_watchdog_timer(self, 1*HZ);
553 irlmp_do_lap_event(self->lap, LM_LAP_CONNECT_REQUEST, NULL);
556 IRDA_DEBUG(1, "%s(), Unknown event %s on LSAP %#02x\n",
557 __FUNCTION__, irlmp_event[event], self->slsap_sel);
564 * Function irlmp_state_connect (self, event, skb)
569 static int irlmp_state_connect(struct lsap_cb *self, IRLMP_EVENT event,
572 struct lsap_cb *lsap;
575 IRDA_DEBUG(4, "%s()\n", __FUNCTION__);
577 IRDA_ASSERT(self != NULL, return -1;);
578 IRDA_ASSERT(self->magic == LMP_LSAP_MAGIC, return -1;);
581 case LM_CONNECT_RESPONSE:
583 * Bind this LSAP to the IrLAP link where the connect was
586 lsap = hashbin_remove(irlmp->unconnected_lsaps, (long) self,
589 IRDA_ASSERT(lsap == self, return -1;);
590 IRDA_ASSERT(self->lap != NULL, return -1;);
591 IRDA_ASSERT(self->lap->lsaps != NULL, return -1;);
593 hashbin_insert(self->lap->lsaps, (irda_queue_t *) self,
596 set_bit(0, &self->connected); /* TRUE */
598 irlmp_send_lcf_pdu(self->lap, self->dlsap_sel,
599 self->slsap_sel, CONNECT_CNF, skb);
601 del_timer(&self->watchdog_timer);
603 irlmp_next_lsap_state(self, LSAP_DATA_TRANSFER_READY);
605 case LM_WATCHDOG_TIMEOUT:
606 /* May happen, who knows...
608 IRDA_DEBUG(0, "%s() WATCHDOG_TIMEOUT!\n", __FUNCTION__);
610 /* Disconnect, get out... - Jean II */
612 self->dlsap_sel = LSAP_ANY;
613 irlmp_next_lsap_state(self, LSAP_DISCONNECTED);
616 /* LM_LAP_DISCONNECT_INDICATION : Should never happen, we
617 * are *not* yet bound to the IrLAP link. Jean II */
618 IRDA_DEBUG(0, "%s(), Unknown event %s on LSAP %#02x\n",
619 __FUNCTION__, irlmp_event[event], self->slsap_sel);
626 * Function irlmp_state_connect_pend (event, skb, info)
631 static int irlmp_state_connect_pend(struct lsap_cb *self, IRLMP_EVENT event,
634 struct sk_buff *tx_skb;
637 IRDA_DEBUG(4, "%s()\n", __FUNCTION__);
639 IRDA_ASSERT(self != NULL, return -1;);
640 IRDA_ASSERT(self->magic == LMP_LSAP_MAGIC, return -1;);
643 case LM_CONNECT_REQUEST:
646 case LM_CONNECT_RESPONSE:
647 IRDA_DEBUG(0, "%s(), LM_CONNECT_RESPONSE, "
648 "no indication issued yet\n", __FUNCTION__);
651 case LM_DISCONNECT_REQUEST:
652 IRDA_DEBUG(0, "%s(), LM_DISCONNECT_REQUEST, "
653 "not yet bound to IrLAP connection\n", __FUNCTION__);
656 case LM_LAP_CONNECT_CONFIRM:
657 IRDA_DEBUG(4, "%s(), LS_CONNECT_CONFIRM\n", __FUNCTION__);
658 irlmp_next_lsap_state(self, LSAP_CONNECT);
660 tx_skb = self->conn_skb;
661 self->conn_skb = NULL;
663 irlmp_connect_indication(self, tx_skb);
664 /* Drop reference count - see irlmp_connect_indication(). */
665 dev_kfree_skb(tx_skb);
667 case LM_WATCHDOG_TIMEOUT:
668 /* Will happen in some rare cases because of a race condition.
669 * Just make sure we don't stay there forever...
671 IRDA_DEBUG(0, "%s() WATCHDOG_TIMEOUT!\n", __FUNCTION__);
673 /* Go back to disconnected mode, keep the socket waiting */
675 self->dlsap_sel = LSAP_ANY;
677 dev_kfree_skb(self->conn_skb);
678 self->conn_skb = NULL;
679 irlmp_next_lsap_state(self, LSAP_DISCONNECTED);
682 /* LM_LAP_DISCONNECT_INDICATION : Should never happen, we
683 * are *not* yet bound to the IrLAP link. Jean II */
684 IRDA_DEBUG(0, "%s(), Unknown event %s on LSAP %#02x\n",
685 __FUNCTION__, irlmp_event[event], self->slsap_sel);
692 * Function irlmp_state_dtr (self, event, skb)
694 * DATA_TRANSFER_READY
697 static int irlmp_state_dtr(struct lsap_cb *self, IRLMP_EVENT event,
703 IRDA_DEBUG(4, "%s()\n", __FUNCTION__);
705 IRDA_ASSERT(self != NULL, return -1;);
706 IRDA_ASSERT(self->magic == LMP_LSAP_MAGIC, return -1;);
707 IRDA_ASSERT(self->lap != NULL, return -1;);
710 case LM_DATA_REQUEST: /* Optimize for the common case */
711 irlmp_send_data_pdu(self->lap, self->dlsap_sel,
712 self->slsap_sel, FALSE, skb);
714 case LM_DATA_INDICATION: /* Optimize for the common case */
715 irlmp_data_indication(self, skb);
717 case LM_UDATA_REQUEST:
718 IRDA_ASSERT(skb != NULL, return -1;);
719 irlmp_send_data_pdu(self->lap, self->dlsap_sel,
720 self->slsap_sel, TRUE, skb);
722 case LM_UDATA_INDICATION:
723 irlmp_udata_indication(self, skb);
725 case LM_CONNECT_REQUEST:
726 IRDA_DEBUG(0, "%s(), LM_CONNECT_REQUEST, "
727 "error, LSAP already connected\n", __FUNCTION__);
730 case LM_CONNECT_RESPONSE:
731 IRDA_DEBUG(0, "%s(), LM_CONNECT_RESPONSE, "
732 "error, LSAP already connected\n", __FUNCTION__);
735 case LM_DISCONNECT_REQUEST:
736 irlmp_send_lcf_pdu(self->lap, self->dlsap_sel, self->slsap_sel,
738 irlmp_next_lsap_state(self, LSAP_DISCONNECTED);
739 /* Called only from irlmp_disconnect_request(), will
740 * unbind from LAP over there. Jean II */
742 /* Try to close the LAP connection if its still there */
744 IRDA_DEBUG(4, "%s(), trying to close IrLAP\n",
746 irlmp_do_lap_event(self->lap,
747 LM_LAP_DISCONNECT_REQUEST,
751 case LM_LAP_DISCONNECT_INDICATION:
752 irlmp_next_lsap_state(self, LSAP_DISCONNECTED);
754 reason = irlmp_convert_lap_reason(self->lap->reason);
756 irlmp_disconnect_indication(self, reason, NULL);
758 case LM_DISCONNECT_INDICATION:
759 irlmp_next_lsap_state(self, LSAP_DISCONNECTED);
761 IRDA_ASSERT(self->lap != NULL, return -1;);
762 IRDA_ASSERT(self->lap->magic == LMP_LAP_MAGIC, return -1;);
764 IRDA_ASSERT(skb != NULL, return -1;);
765 IRDA_ASSERT(skb->len > 3, return -1;);
766 reason = skb->data[3];
768 /* Try to close the LAP connection */
769 IRDA_DEBUG(4, "%s(), trying to close IrLAP\n", __FUNCTION__);
770 irlmp_do_lap_event(self->lap, LM_LAP_DISCONNECT_REQUEST, NULL);
772 irlmp_disconnect_indication(self, reason, skb);
775 IRDA_DEBUG(0, "%s(), Unknown event %s on LSAP %#02x\n",
776 __FUNCTION__, irlmp_event[event], self->slsap_sel);
783 * Function irlmp_state_setup (event, skb, info)
785 * SETUP, Station Control has set up the underlying IrLAP connection.
786 * An LSAP connection request has been transmitted to the peer
787 * LSAP-Connection Control FSM and we are awaiting reply.
789 static int irlmp_state_setup(struct lsap_cb *self, IRLMP_EVENT event,
795 IRDA_ASSERT(self != NULL, return -1;);
796 IRDA_ASSERT(self->magic == LMP_LSAP_MAGIC, return -1;);
798 IRDA_DEBUG(4, "%s()\n", __FUNCTION__);
801 case LM_CONNECT_CONFIRM:
802 irlmp_next_lsap_state(self, LSAP_DATA_TRANSFER_READY);
804 del_timer(&self->watchdog_timer);
806 irlmp_connect_confirm(self, skb);
808 case LM_DISCONNECT_INDICATION:
809 irlmp_next_lsap_state(self, LSAP_DISCONNECTED);
811 IRDA_ASSERT(self->lap != NULL, return -1;);
812 IRDA_ASSERT(self->lap->magic == LMP_LAP_MAGIC, return -1;);
814 IRDA_ASSERT(skb != NULL, return -1;);
815 IRDA_ASSERT(skb->len > 3, return -1;);
816 reason = skb->data[3];
818 /* Try to close the LAP connection */
819 IRDA_DEBUG(4, "%s(), trying to close IrLAP\n", __FUNCTION__);
820 irlmp_do_lap_event(self->lap, LM_LAP_DISCONNECT_REQUEST, NULL);
822 irlmp_disconnect_indication(self, reason, skb);
824 case LM_LAP_DISCONNECT_INDICATION:
825 irlmp_next_lsap_state(self, LSAP_DISCONNECTED);
827 del_timer(&self->watchdog_timer);
829 IRDA_ASSERT(self->lap != NULL, return -1;);
830 IRDA_ASSERT(self->lap->magic == LMP_LAP_MAGIC, return -1;);
832 reason = irlmp_convert_lap_reason(self->lap->reason);
834 irlmp_disconnect_indication(self, reason, skb);
836 case LM_WATCHDOG_TIMEOUT:
837 IRDA_DEBUG(0, "%s() WATCHDOG_TIMEOUT!\n", __FUNCTION__);
839 IRDA_ASSERT(self->lap != NULL, return -1;);
840 irlmp_do_lap_event(self->lap, LM_LAP_DISCONNECT_REQUEST, NULL);
841 irlmp_next_lsap_state(self, LSAP_DISCONNECTED);
843 irlmp_disconnect_indication(self, LM_CONNECT_FAILURE, NULL);
846 IRDA_DEBUG(0, "%s(), Unknown event %s on LSAP %#02x\n",
847 __FUNCTION__, irlmp_event[event], self->slsap_sel);
854 * Function irlmp_state_setup_pend (event, skb, info)
856 * SETUP_PEND, An LM_CONNECT_REQUEST has been received from the service
857 * user to set up an LSAP connection. A request has been sent to the
858 * LAP FSM to set up the underlying IrLAP connection, and we
859 * are awaiting confirm.
861 static int irlmp_state_setup_pend(struct lsap_cb *self, IRLMP_EVENT event,
864 struct sk_buff *tx_skb;
868 IRDA_DEBUG(4, "%s()\n", __FUNCTION__);
870 IRDA_ASSERT(self != NULL, return -1;);
871 IRDA_ASSERT(irlmp != NULL, return -1;);
874 case LM_LAP_CONNECT_CONFIRM:
875 IRDA_ASSERT(self->conn_skb != NULL, return -1;);
877 tx_skb = self->conn_skb;
878 self->conn_skb = NULL;
880 irlmp_send_lcf_pdu(self->lap, self->dlsap_sel,
881 self->slsap_sel, CONNECT_CMD, tx_skb);
882 /* Drop reference count - see irlap_data_request(). */
883 dev_kfree_skb(tx_skb);
885 irlmp_next_lsap_state(self, LSAP_SETUP);
887 case LM_WATCHDOG_TIMEOUT:
888 IRDA_DEBUG(0, "%s() : WATCHDOG_TIMEOUT !\n", __FUNCTION__);
890 IRDA_ASSERT(self->lap != NULL, return -1;);
891 irlmp_do_lap_event(self->lap, LM_LAP_DISCONNECT_REQUEST, NULL);
892 irlmp_next_lsap_state(self, LSAP_DISCONNECTED);
894 irlmp_disconnect_indication(self, LM_CONNECT_FAILURE, NULL);
896 case LM_LAP_DISCONNECT_INDICATION: /* LS_Disconnect.indication */
897 del_timer( &self->watchdog_timer);
899 irlmp_next_lsap_state(self, LSAP_DISCONNECTED);
901 reason = irlmp_convert_lap_reason(self->lap->reason);
903 irlmp_disconnect_indication(self, reason, NULL);
906 IRDA_DEBUG(0, "%s(), Unknown event %s on LSAP %#02x\n",
907 __FUNCTION__, irlmp_event[event], self->slsap_sel);