ircomm_tty_ias_register(self);
+ /* Check if somebody has already connected to us */
+ if (ircomm_is_connected(self->ircomm)) {
+ IRDA_DEBUG(0, "%s(), already connected!\n", __FUNCTION__ );
+ return 0;
+ }
+
ircomm_tty_do_event(self, IRCOMM_TTY_ATTACH_CABLE, NULL, NULL);
return 0;
del_timer(&self->watchdog_timer);
- /* Remove discovery handler */
- if (self->ckey) {
- irlmp_unregister_client(self->ckey);
- self->ckey = NULL;
- }
/* Remove IrCOMM hint bits */
- if (self->skey) {
- irlmp_unregister_service(self->skey);
- self->skey = NULL;
- }
+ irlmp_unregister_client(self->ckey);
+ irlmp_unregister_service(self->skey);
if (self->iriap) {
iriap_close(self->iriap);
ASSERT(self != NULL, return;);
ASSERT(self->magic == IRCOMM_TTY_MAGIC, return;);
- /* Compute hint bits based on service */
- hints = irlmp_service_to_hint(S_COMM);
- if (self->service_type & IRCOMM_3_WIRE_RAW)
- hints |= irlmp_service_to_hint(S_PRINTER);
-
- /* Advertise IrCOMM hint bit in discovery */
- if (!self->skey)
- self->skey = irlmp_register_service(hints);
- /* Set up a discovery handler */
- if (!self->ckey)
- self->ckey = irlmp_register_client(hints,
- ircomm_tty_discovery_indication,
- NULL, (void *) self);
-
- /* If already done, no need to do it again */
- if (self->obj)
- return;
-
if (self->service_type & IRCOMM_3_WIRE_RAW) {
+ hints = irlmp_service_to_hint(S_PRINTER);
+ hints |= irlmp_service_to_hint(S_COMM);
+
/* Register IrLPT with LM-IAS */
self->obj = irias_new_object("IrLPT", IAS_IRLPT_ID);
irias_add_integer_attrib(self->obj, "IrDA:IrLMP:LsapSel",
self->slsap_sel, IAS_KERNEL_ATTR);
+ irias_insert_object(self->obj);
} else {
+ hints = irlmp_service_to_hint(S_COMM);
+
/* Register IrCOMM with LM-IAS */
self->obj = irias_new_object("IrDA:IrCOMM", IAS_IRCOMM_ID);
irias_add_integer_attrib(self->obj, "IrDA:TinyTP:LsapSel",
/* Register parameters with LM-IAS */
irias_add_octseq_attrib(self->obj, "Parameters", oct_seq, 6,
IAS_KERNEL_ATTR);
+ irias_insert_object(self->obj);
}
- irias_insert_object(self->obj);
-}
-
-/*
- * Function ircomm_tty_ias_unregister (self)
- *
- * Remove our IAS object and client hook while connected.
- *
- */
-static void ircomm_tty_ias_unregister(struct ircomm_tty_cb *self)
-{
- /* Remove LM-IAS object now so it is not reused.
- * IrCOMM deals very poorly with multiple incoming connections.
- * It should looks a lot more like IrNET, and "dup" a server TSAP
- * to the application TSAP (based on various rules).
- * This is a cheap workaround allowing multiple clients to
- * connect to us. It will not always work.
- * Each IrCOMM socket has an IAS entry. Incoming connection will
- * pick the first one found. So, when we are fully connected,
- * we remove our IAS entries so that the next IAS entry is used.
- * We do that for *both* client and server, because a server
- * can also create client instances.
- * Jean II */
- if (self->obj) {
- irias_delete_object(self->obj);
- self->obj = NULL;
- }
-
-#if 0
- /* Remove discovery handler.
- * While we are connected, we no longer need to receive
- * discovery events. This would be the case if there is
- * multiple IrLAP interfaces. Jean II */
- if (self->ckey) {
- irlmp_unregister_client(self->ckey);
- self->ckey = NULL;
- }
-#endif
+ self->skey = irlmp_register_service(hints);
+ self->ckey = irlmp_register_client(hints,
+ ircomm_tty_discovery_indication,
+ NULL, (void *) self);
}
/*
info.daddr = discovery->daddr;
info.saddr = discovery->saddr;
- /* FIXME. We have a locking problem on the hashbin here.
- * We probably need to use hashbin_find_next(), but we first
+ /* FIXME. We probably need to use hashbin_find_next(), but we first
* need to ensure that "line" is unique. - Jean II */
self = (struct ircomm_tty_cb *) hashbin_get_first(ircomm_tty);
while (self != NULL) {
del_timer(&self->watchdog_timer);
+ /* Remove LM-IAS object now so it is not reused.
+ * IrCOMM deals very poorly with multiple incoming connections.
+ * It should looks a lot more like IrNET, and "dup" a server TSAP
+ * to the application TSAP (based on various rules).
+ * This is a cheap workaround allowing multiple clients to
+ * connect to us. It will not always work.
+ * Each IrCOMM socket has an IAS entry. Incoming connection will
+ * pick the first one found. So, when we are fully connected,
+ * we remove our IAS entries so that the next IAS entry is used.
+ * We do that for *both* client and server, because a server
+ * can also create client instances.
+ * Jean II */
+ if (self->obj) {
+ irias_delete_object(self->obj);
+ self->obj = NULL;
+ }
+
/*
* IrCOMM link is now up, and if we are not using hardware
* flow-control, then declare the hardware as running. Otherwise we
}
/*
- * Function ircomm_tty_start_watchdog_timer (self, timeout)
+ * Function irlan_start_watchdog_timer (self, timeout)
*
* Start the watchdog timer. This timer is used to make sure that any
* connection attempt is successful, and if not, we will retry after
ircomm_tty_do_event(self, IRCOMM_TTY_WD_TIMER_EXPIRED, NULL, NULL);
}
-
-/*
- * Function ircomm_tty_do_event (self, event, skb)
- *
- * Process event
- *
- */
-int ircomm_tty_do_event(struct ircomm_tty_cb *self, IRCOMM_TTY_EVENT event,
- struct sk_buff *skb, struct ircomm_tty_info *info)
-{
- ASSERT(self != NULL, return -1;);
- ASSERT(self->magic == IRCOMM_TTY_MAGIC, return -1;);
-
- IRDA_DEBUG(2, "%s: state=%s, event=%s\n", __FUNCTION__ ,
- ircomm_tty_state[self->state], ircomm_tty_event[event]);
-
- return (*state[self->state])(self, event, skb, info);
-}
-
-/*
- * Function ircomm_tty_next_state (self, state)
- *
- * Switch state
- *
- */
-static inline void ircomm_tty_next_state(struct ircomm_tty_cb *self, IRCOMM_TTY_STATE state)
-{
- /*
- ASSERT(self != NULL, return;);
- ASSERT(self->magic == IRCOMM_TTY_MAGIC, return;);
-
- IRDA_DEBUG(2, "%s: next state=%s, service type=%d\n", __FUNCTION__ ,
- ircomm_tty_state[self->state], self->service_type);
- */
- self->state = state;
-}
-
/*
* Function ircomm_tty_state_idle (self, event, skb, info)
*
break;
case IRCOMM_TTY_CONNECT_INDICATION:
del_timer(&self->watchdog_timer);
- ircomm_tty_ias_unregister(self);
/* Accept connection */
ircomm_connect_response(self->ircomm, NULL);
break;
case IRCOMM_TTY_CONNECT_INDICATION:
del_timer(&self->watchdog_timer);
- ircomm_tty_ias_unregister(self);
/* Accept connection */
ircomm_connect_response(self->ircomm, NULL);
break;
case IRCOMM_TTY_CONNECT_INDICATION:
del_timer(&self->watchdog_timer);
- ircomm_tty_ias_unregister(self);
/* Accept connection */
ircomm_connect_response(self->ircomm, NULL);
switch (event) {
case IRCOMM_TTY_CONNECT_CONFIRM:
del_timer(&self->watchdog_timer);
- ircomm_tty_ias_unregister(self);
+ ircomm_tty_next_state(self, IRCOMM_TTY_READY);
/*
* Send initial parameters. This will also send out queued
*/
ircomm_tty_send_initial_parameters(self);
ircomm_tty_link_established(self);
- ircomm_tty_next_state(self, IRCOMM_TTY_READY);
break;
case IRCOMM_TTY_CONNECT_INDICATION:
del_timer(&self->watchdog_timer);
- ircomm_tty_ias_unregister(self);
/* Accept connection */
ircomm_connect_response(self->ircomm, NULL);
ircomm_tty_next_state(self, IRCOMM_TTY_IDLE);
break;
case IRCOMM_TTY_DISCONNECT_INDICATION:
- ircomm_tty_ias_register(self);
ircomm_tty_next_state(self, IRCOMM_TTY_SEARCH);
ircomm_tty_start_watchdog_timer(self, 3*HZ);
return ret;
}
+/*
+ * Function ircomm_tty_do_event (self, event, skb)
+ *
+ * Process event
+ *
+ */
+int ircomm_tty_do_event(struct ircomm_tty_cb *self, IRCOMM_TTY_EVENT event,
+ struct sk_buff *skb, struct ircomm_tty_info *info)
+{
+ ASSERT(self != NULL, return -1;);
+ ASSERT(self->magic == IRCOMM_TTY_MAGIC, return -1;);
+
+ IRDA_DEBUG(2, "%s: state=%s, event=%s\n", __FUNCTION__ ,
+ ircomm_tty_state[self->state], ircomm_tty_event[event]);
+
+ return (*state[self->state])(self, event, skb, info);
+}
+
+/*
+ * Function ircomm_tty_next_state (self, state)
+ *
+ * Switch state
+ *
+ */
+void ircomm_tty_next_state(struct ircomm_tty_cb *self, IRCOMM_TTY_STATE state)
+{
+ ASSERT(self != NULL, return;);
+ ASSERT(self->magic == IRCOMM_TTY_MAGIC, return;);
+
+ self->state = state;
+
+ IRDA_DEBUG(2, "%s: next state=%s, service type=%d\n", __FUNCTION__ ,
+ ircomm_tty_state[self->state], self->service_type);
+}
+