⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 irlmp_event.c

📁 linux 内核源代码
💻 C
📖 第 1 页 / 共 2 页
字号:
		 *  Inform all connected LSAP's using this link		 */		irlmp_do_all_lsap_event(self->lsaps,					LM_LAP_DISCONNECT_INDICATION);		/* Force an expiry of the discovery log.		 * Now that the LAP is free, the system may attempt to		 * connect to another device. Unfortunately, our entries		 * are stale. There is a small window (<3s) before the		 * normal discovery will run and where irlmp_connect_request()		 * can get the wrong info, so make sure things get		 * cleaned *NOW* ;-) - Jean II */		irlmp_do_expiry();		break;	default:		IRDA_DEBUG(0, "%s(), Unknown event %s\n",			 __FUNCTION__, irlmp_event[event]);		break;	}}/********************************************************************* * *    LSAP connection control states * ********************************************************************//* * Function irlmp_state_disconnected (event, skb, info) * *    DISCONNECTED * */static int irlmp_state_disconnected(struct lsap_cb *self, IRLMP_EVENT event,				    struct sk_buff *skb){	int ret = 0;	IRDA_DEBUG(4, "%s()\n", __FUNCTION__);	IRDA_ASSERT(self != NULL, return -1;);	IRDA_ASSERT(self->magic == LMP_LSAP_MAGIC, return -1;);	switch (event) {#ifdef CONFIG_IRDA_ULTRA	case LM_UDATA_INDICATION:		/* This is most bizzare. Those packets are  aka unreliable		 * connected, aka IrLPT or SOCK_DGRAM/IRDAPROTO_UNITDATA.		 * Why do we pass them as Ultra ??? Jean II */		irlmp_connless_data_indication(self, skb);		break;#endif /* CONFIG_IRDA_ULTRA */	case LM_CONNECT_REQUEST:		IRDA_DEBUG(4, "%s(), LM_CONNECT_REQUEST\n", __FUNCTION__);		if (self->conn_skb) {			IRDA_WARNING("%s: busy with another request!\n",				     __FUNCTION__);			return -EBUSY;		}		/* Don't forget to refcount it (see irlmp_connect_request()) */		skb_get(skb);		self->conn_skb = skb;		irlmp_next_lsap_state(self, LSAP_SETUP_PEND);		/* Start watchdog timer (5 secs for now) */		irlmp_start_watchdog_timer(self, 5*HZ);		irlmp_do_lap_event(self->lap, LM_LAP_CONNECT_REQUEST, NULL);		break;	case LM_CONNECT_INDICATION:		if (self->conn_skb) {			IRDA_WARNING("%s: busy with another request!\n",				     __FUNCTION__);			return -EBUSY;		}		/* Don't forget to refcount it (see irlap_driver_rcv()) */		skb_get(skb);		self->conn_skb = skb;		irlmp_next_lsap_state(self, LSAP_CONNECT_PEND);		/* Start watchdog timer		 * This is not mentionned in the spec, but there is a rare		 * race condition that can get the socket stuck.		 * If we receive this event while our LAP is closing down,		 * the LM_LAP_CONNECT_REQUEST get lost and we get stuck in		 * CONNECT_PEND state forever.		 * The other cause of getting stuck down there is if the		 * higher layer never reply to the CONNECT_INDICATION.		 * Anyway, it make sense to make sure that we always have		 * a backup plan. 1 second is plenty (should be immediate).		 * Jean II */		irlmp_start_watchdog_timer(self, 1*HZ);		irlmp_do_lap_event(self->lap, LM_LAP_CONNECT_REQUEST, NULL);		break;	default:		IRDA_DEBUG(1, "%s(), Unknown event %s on LSAP %#02x\n",			   __FUNCTION__, irlmp_event[event], self->slsap_sel);		break;	}	return ret;}/* * Function irlmp_state_connect (self, event, skb) * *    CONNECT * */static int irlmp_state_connect(struct lsap_cb *self, IRLMP_EVENT event,				struct sk_buff *skb){	struct lsap_cb *lsap;	int ret = 0;	IRDA_DEBUG(4, "%s()\n", __FUNCTION__);	IRDA_ASSERT(self != NULL, return -1;);	IRDA_ASSERT(self->magic == LMP_LSAP_MAGIC, return -1;);	switch (event) {	case LM_CONNECT_RESPONSE:		/*		 *  Bind this LSAP to the IrLAP link where the connect was		 *  received		 */		lsap = hashbin_remove(irlmp->unconnected_lsaps, (long) self,				      NULL);		IRDA_ASSERT(lsap == self, return -1;);		IRDA_ASSERT(self->lap != NULL, return -1;);		IRDA_ASSERT(self->lap->lsaps != NULL, return -1;);		hashbin_insert(self->lap->lsaps, (irda_queue_t *) self,			       (long) self, NULL);		set_bit(0, &self->connected);	/* TRUE */		irlmp_send_lcf_pdu(self->lap, self->dlsap_sel,				   self->slsap_sel, CONNECT_CNF, skb);		del_timer(&self->watchdog_timer);		irlmp_next_lsap_state(self, LSAP_DATA_TRANSFER_READY);		break;	case LM_WATCHDOG_TIMEOUT:		/* May happen, who knows...		 * Jean II */		IRDA_DEBUG(0, "%s() WATCHDOG_TIMEOUT!\n",  __FUNCTION__);		/* Disconnect, get out... - Jean II */		self->lap = NULL;		self->dlsap_sel = LSAP_ANY;		irlmp_next_lsap_state(self, LSAP_DISCONNECTED);		break;	default:		/* LM_LAP_DISCONNECT_INDICATION : Should never happen, we		 * are *not* yet bound to the IrLAP link. Jean II */		IRDA_DEBUG(0, "%s(), Unknown event %s on LSAP %#02x\n",			   __FUNCTION__, irlmp_event[event], self->slsap_sel);		break;	}	return ret;}/* * Function irlmp_state_connect_pend (event, skb, info) * *    CONNECT_PEND * */static int irlmp_state_connect_pend(struct lsap_cb *self, IRLMP_EVENT event,				    struct sk_buff *skb){	struct sk_buff *tx_skb;	int ret = 0;	IRDA_DEBUG(4, "%s()\n", __FUNCTION__);	IRDA_ASSERT(self != NULL, return -1;);	IRDA_ASSERT(self->magic == LMP_LSAP_MAGIC, return -1;);	switch (event) {	case LM_CONNECT_REQUEST:		/* Keep state */		break;	case LM_CONNECT_RESPONSE:		IRDA_DEBUG(0, "%s(), LM_CONNECT_RESPONSE, "			   "no indication issued yet\n",  __FUNCTION__);		/* Keep state */		break;	case LM_DISCONNECT_REQUEST:		IRDA_DEBUG(0, "%s(), LM_DISCONNECT_REQUEST, "			   "not yet bound to IrLAP connection\n",  __FUNCTION__);		/* Keep state */		break;	case LM_LAP_CONNECT_CONFIRM:		IRDA_DEBUG(4, "%s(), LS_CONNECT_CONFIRM\n",  __FUNCTION__);		irlmp_next_lsap_state(self, LSAP_CONNECT);		tx_skb = self->conn_skb;		self->conn_skb = NULL;		irlmp_connect_indication(self, tx_skb);		/* Drop reference count - see irlmp_connect_indication(). */		dev_kfree_skb(tx_skb);		break;	case LM_WATCHDOG_TIMEOUT:		/* Will happen in some rare cases because of a race condition.		 * Just make sure we don't stay there forever...		 * Jean II */		IRDA_DEBUG(0, "%s() WATCHDOG_TIMEOUT!\n",  __FUNCTION__);		/* Go back to disconnected mode, keep the socket waiting */		self->lap = NULL;		self->dlsap_sel = LSAP_ANY;		if(self->conn_skb)			dev_kfree_skb(self->conn_skb);		self->conn_skb = NULL;		irlmp_next_lsap_state(self, LSAP_DISCONNECTED);		break;	default:		/* LM_LAP_DISCONNECT_INDICATION : Should never happen, we		 * are *not* yet bound to the IrLAP link. Jean II */		IRDA_DEBUG(0, "%s(), Unknown event %s on LSAP %#02x\n",			   __FUNCTION__, irlmp_event[event], self->slsap_sel);		break;	}	return ret;}/* * Function irlmp_state_dtr (self, event, skb) * *    DATA_TRANSFER_READY * */static int irlmp_state_dtr(struct lsap_cb *self, IRLMP_EVENT event,			   struct sk_buff *skb){	LM_REASON reason;	int ret = 0;	IRDA_DEBUG(4, "%s()\n", __FUNCTION__);	IRDA_ASSERT(self != NULL, return -1;);	IRDA_ASSERT(self->magic == LMP_LSAP_MAGIC, return -1;);	IRDA_ASSERT(self->lap != NULL, return -1;);	switch (event) {	case LM_DATA_REQUEST: /* Optimize for the common case */		irlmp_send_data_pdu(self->lap, self->dlsap_sel,				    self->slsap_sel, FALSE, skb);		break;	case LM_DATA_INDICATION: /* Optimize for the common case */		irlmp_data_indication(self, skb);		break;	case LM_UDATA_REQUEST:		IRDA_ASSERT(skb != NULL, return -1;);		irlmp_send_data_pdu(self->lap, self->dlsap_sel,				    self->slsap_sel, TRUE, skb);		break;	case LM_UDATA_INDICATION:		irlmp_udata_indication(self, skb);		break;	case LM_CONNECT_REQUEST:		IRDA_DEBUG(0, "%s(), LM_CONNECT_REQUEST, "			   "error, LSAP already connected\n", __FUNCTION__);		/* Keep state */		break;	case LM_CONNECT_RESPONSE:		IRDA_DEBUG(0, "%s(), LM_CONNECT_RESPONSE, "			   "error, LSAP already connected\n", __FUNCTION__);		/* Keep state */		break;	case LM_DISCONNECT_REQUEST:		irlmp_send_lcf_pdu(self->lap, self->dlsap_sel, self->slsap_sel,				   DISCONNECT, skb);		irlmp_next_lsap_state(self, LSAP_DISCONNECTED);		/* Called only from irlmp_disconnect_request(), will		 * unbind from LAP over there. Jean II */		/* Try to close the LAP connection if its still there */		if (self->lap) {			IRDA_DEBUG(4, "%s(), trying to close IrLAP\n",				   __FUNCTION__);			irlmp_do_lap_event(self->lap,					   LM_LAP_DISCONNECT_REQUEST,					   NULL);		}		break;	case LM_LAP_DISCONNECT_INDICATION:		irlmp_next_lsap_state(self, LSAP_DISCONNECTED);		reason = irlmp_convert_lap_reason(self->lap->reason);		irlmp_disconnect_indication(self, reason, NULL);		break;	case LM_DISCONNECT_INDICATION:		irlmp_next_lsap_state(self, LSAP_DISCONNECTED);		IRDA_ASSERT(self->lap != NULL, return -1;);		IRDA_ASSERT(self->lap->magic == LMP_LAP_MAGIC, return -1;);		IRDA_ASSERT(skb != NULL, return -1;);		IRDA_ASSERT(skb->len > 3, return -1;);		reason = skb->data[3];		 /* Try to close the LAP connection */		IRDA_DEBUG(4, "%s(), trying to close IrLAP\n", __FUNCTION__);		irlmp_do_lap_event(self->lap, LM_LAP_DISCONNECT_REQUEST, NULL);		irlmp_disconnect_indication(self, reason, skb);		break;	default:		IRDA_DEBUG(0, "%s(), Unknown event %s on LSAP %#02x\n",			   __FUNCTION__, irlmp_event[event], self->slsap_sel);		break;	}	return ret;}/* * Function irlmp_state_setup (event, skb, info) * *    SETUP, Station Control has set up the underlying IrLAP connection. *    An LSAP connection request has been transmitted to the peer *    LSAP-Connection Control FSM and we are awaiting reply. */static int irlmp_state_setup(struct lsap_cb *self, IRLMP_EVENT event,			     struct sk_buff *skb){	LM_REASON reason;	int ret = 0;	IRDA_ASSERT(self != NULL, return -1;);	IRDA_ASSERT(self->magic == LMP_LSAP_MAGIC, return -1;);	IRDA_DEBUG(4, "%s()\n", __FUNCTION__);	switch (event) {	case LM_CONNECT_CONFIRM:		irlmp_next_lsap_state(self, LSAP_DATA_TRANSFER_READY);		del_timer(&self->watchdog_timer);		irlmp_connect_confirm(self, skb);		break;	case LM_DISCONNECT_INDICATION:		irlmp_next_lsap_state(self, LSAP_DISCONNECTED);		IRDA_ASSERT(self->lap != NULL, return -1;);		IRDA_ASSERT(self->lap->magic == LMP_LAP_MAGIC, return -1;);		IRDA_ASSERT(skb != NULL, return -1;);		IRDA_ASSERT(skb->len > 3, return -1;);		reason = skb->data[3];		 /* Try to close the LAP connection */		IRDA_DEBUG(4, "%s(), trying to close IrLAP\n",  __FUNCTION__);		irlmp_do_lap_event(self->lap, LM_LAP_DISCONNECT_REQUEST, NULL);		irlmp_disconnect_indication(self, reason, skb);		break;	case LM_LAP_DISCONNECT_INDICATION:		irlmp_next_lsap_state(self, LSAP_DISCONNECTED);		del_timer(&self->watchdog_timer);		IRDA_ASSERT(self->lap != NULL, return -1;);		IRDA_ASSERT(self->lap->magic == LMP_LAP_MAGIC, return -1;);		reason = irlmp_convert_lap_reason(self->lap->reason);		irlmp_disconnect_indication(self, reason, skb);		break;	case LM_WATCHDOG_TIMEOUT:		IRDA_DEBUG(0, "%s() WATCHDOG_TIMEOUT!\n", __FUNCTION__);		IRDA_ASSERT(self->lap != NULL, return -1;);		irlmp_do_lap_event(self->lap, LM_LAP_DISCONNECT_REQUEST, NULL);		irlmp_next_lsap_state(self, LSAP_DISCONNECTED);		irlmp_disconnect_indication(self, LM_CONNECT_FAILURE, NULL);		break;	default:		IRDA_DEBUG(0, "%s(), Unknown event %s on LSAP %#02x\n",			   __FUNCTION__, irlmp_event[event], self->slsap_sel);		break;	}	return ret;}/* * Function irlmp_state_setup_pend (event, skb, info) * *    SETUP_PEND, An LM_CONNECT_REQUEST has been received from the service *    user to set up an LSAP connection. A request has been sent to the *    LAP FSM to set up the underlying IrLAP connection, and we *    are awaiting confirm. */static int irlmp_state_setup_pend(struct lsap_cb *self, IRLMP_EVENT event,				  struct sk_buff *skb){	struct sk_buff *tx_skb;	LM_REASON reason;	int ret = 0;	IRDA_DEBUG(4, "%s()\n", __FUNCTION__);	IRDA_ASSERT(self != NULL, return -1;);	IRDA_ASSERT(irlmp != NULL, return -1;);	switch (event) {	case LM_LAP_CONNECT_CONFIRM:		IRDA_ASSERT(self->conn_skb != NULL, return -1;);		tx_skb = self->conn_skb;		self->conn_skb = NULL;		irlmp_send_lcf_pdu(self->lap, self->dlsap_sel,				   self->slsap_sel, CONNECT_CMD, tx_skb);		/* Drop reference count - see irlap_data_request(). */		dev_kfree_skb(tx_skb);		irlmp_next_lsap_state(self, LSAP_SETUP);		break;	case LM_WATCHDOG_TIMEOUT:		IRDA_DEBUG(0, "%s() : WATCHDOG_TIMEOUT !\n",  __FUNCTION__);		IRDA_ASSERT(self->lap != NULL, return -1;);		irlmp_do_lap_event(self->lap, LM_LAP_DISCONNECT_REQUEST, NULL);		irlmp_next_lsap_state(self, LSAP_DISCONNECTED);		irlmp_disconnect_indication(self, LM_CONNECT_FAILURE, NULL);		break;	case LM_LAP_DISCONNECT_INDICATION: /* LS_Disconnect.indication */		del_timer( &self->watchdog_timer);		irlmp_next_lsap_state(self, LSAP_DISCONNECTED);		reason = irlmp_convert_lap_reason(self->lap->reason);		irlmp_disconnect_indication(self, reason, NULL);		break;	default:		IRDA_DEBUG(0, "%s(), Unknown event %s on LSAP %#02x\n",			   __FUNCTION__, irlmp_event[event], self->slsap_sel);		break;	}	return ret;}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -