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

📄 ircomm_tty_attach.c

📁 Linux内核源代码 为压缩文件 是<<Linux内核>>一书中的源代码
💻 C
📖 第 1 页 / 共 2 页
字号:
	ASSERT(self->magic == IRCOMM_TTY_MAGIC, return;);	self->client = FALSE;	self->max_data_size = max_data_size;	self->max_header_size = max_header_size;	self->flow = FLOW_START;	clen = skb->data[0];	if (clen)		irda_param_extract_all(self, skb->data+1, 				       IRDA_MIN(skb->len, clen), 				       &ircomm_param_info);	ircomm_tty_do_event(self, IRCOMM_TTY_CONNECT_INDICATION, NULL, NULL);	dev_kfree_skb(skb);}/* * Function ircomm_tty_link_established (self) * *    Called when the IrCOMM link is established * */void ircomm_tty_link_established(struct ircomm_tty_cb *self){	IRDA_DEBUG(2, __FUNCTION__ "()\n");	ASSERT(self != NULL, return;);	ASSERT(self->magic == IRCOMM_TTY_MAGIC, return;);	if (!self->tty)		return;		del_timer(&self->watchdog_timer);	/* 	 * IrCOMM link is now up, and if we are not using hardware	 * flow-control, then declare the hardware as running. Otherwise we	 * will have to wait for the peer device (DCE) to raise the CTS	 * line.  	 */	if (self->flags & ASYNC_CTS_FLOW) {		IRDA_DEBUG(0, __FUNCTION__ "(), waiting for CTS ...\n");		return;	} else {		IRDA_DEBUG(2, __FUNCTION__ "(), starting hardware!\n");		self->tty->hw_stopped = 0;			/* Wake up processes blocked on open */		wake_up_interruptible(&self->open_wait);	}	queue_task(&self->tqueue, &tq_immediate);	mark_bh(IMMEDIATE_BH);}/* * 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  *    the timeout */void ircomm_tty_start_watchdog_timer(struct ircomm_tty_cb *self, int timeout){	ASSERT(self != NULL, return;);	ASSERT(self->magic == IRCOMM_TTY_MAGIC, return;);	irda_start_timer(&self->watchdog_timer, timeout, (void *) self,			 ircomm_tty_watchdog_timer_expired);}/* * Function ircomm_tty_watchdog_timer_expired (data) * *    Called when the connect procedure have taken to much time. * */void ircomm_tty_watchdog_timer_expired(void *data){	struct ircomm_tty_cb *self = (struct ircomm_tty_cb *) data;		IRDA_DEBUG(2, __FUNCTION__ "()\n");	ASSERT(self != NULL, return;);	ASSERT(self->magic == IRCOMM_TTY_MAGIC, return;);	ircomm_tty_do_event(self, IRCOMM_TTY_WD_TIMER_EXPIRED, NULL, NULL);}/* * Function ircomm_tty_state_idle (self, event, skb, info) * *    Just hanging around * */static int ircomm_tty_state_idle(struct ircomm_tty_cb *self, 				 IRCOMM_TTY_EVENT event, 				 struct sk_buff *skb, 				 struct ircomm_tty_info *info){	int ret = 0;	IRDA_DEBUG(2, __FUNCTION__": state=%s, event=%s\n",		   ircomm_tty_state[self->state], ircomm_tty_event[event]);	switch (event) {	case IRCOMM_TTY_ATTACH_CABLE:		/* Try to discover any remote devices */				ircomm_tty_start_watchdog_timer(self, 3*HZ);		ircomm_tty_next_state(self, IRCOMM_TTY_SEARCH);				irlmp_discovery_request(DISCOVERY_DEFAULT_SLOTS);		break;	case IRCOMM_TTY_DISCOVERY_INDICATION:		self->daddr = info->daddr;		self->saddr = info->saddr;		if (self->iriap) {			WARNING(__FUNCTION__ 				"(), busy with a previous query\n");			return -EBUSY;		}		self->iriap = iriap_open(LSAP_ANY, IAS_CLIENT, self,					 ircomm_tty_getvalue_confirm);		iriap_getvaluebyclass_request(self->iriap,					      self->saddr, self->daddr,					      "IrDA:IrCOMM", "Parameters");				ircomm_tty_start_watchdog_timer(self, 3*HZ);		ircomm_tty_next_state(self, IRCOMM_TTY_QUERY_PARAMETERS);		break;	case IRCOMM_TTY_CONNECT_INDICATION:		del_timer(&self->watchdog_timer);		/* Accept connection */		ircomm_connect_response(self->ircomm, NULL);		ircomm_tty_next_state(self, IRCOMM_TTY_READY);		break;	case IRCOMM_TTY_WD_TIMER_EXPIRED:		/* Just stay idle */		break;	case IRCOMM_TTY_DETACH_CABLE:		ircomm_tty_next_state(self, IRCOMM_TTY_IDLE);		break;	default:		IRDA_DEBUG(2, __FUNCTION__"(), unknown event: %s\n",			   ircomm_tty_event[event]);		return -EINVAL;	}	return ret;}/* * Function ircomm_tty_state_search (self, event, skb, info) * *    Trying to discover an IrCOMM device * */static int ircomm_tty_state_search(struct ircomm_tty_cb *self, 				   IRCOMM_TTY_EVENT event, 				   struct sk_buff *skb, 				   struct ircomm_tty_info *info){	int ret = 0;	IRDA_DEBUG(2, __FUNCTION__": state=%s, event=%s\n",		   ircomm_tty_state[self->state], ircomm_tty_event[event]);	switch (event) {	case IRCOMM_TTY_DISCOVERY_INDICATION:		self->daddr = info->daddr;		self->saddr = info->saddr;		if (self->iriap) {			WARNING(__FUNCTION__ 				"(), busy with a previous query\n");			return -EBUSY;		}				self->iriap = iriap_open(LSAP_ANY, IAS_CLIENT, self,					 ircomm_tty_getvalue_confirm);				if (self->service_type == IRCOMM_3_WIRE_RAW) {			iriap_getvaluebyclass_request(self->iriap, self->saddr,						      self->daddr, "IrLPT", 						      "IrDA:IrLMP:LsapSel");			ircomm_tty_next_state(self, IRCOMM_TTY_QUERY_LSAP_SEL);		} else {			iriap_getvaluebyclass_request(self->iriap, self->saddr,						      self->daddr, 						      "IrDA:IrCOMM", 						      "Parameters");			ircomm_tty_next_state(self, IRCOMM_TTY_QUERY_PARAMETERS);		}		ircomm_tty_start_watchdog_timer(self, 3*HZ);		break;	case IRCOMM_TTY_CONNECT_INDICATION:		del_timer(&self->watchdog_timer);		/* Accept connection */		ircomm_connect_response(self->ircomm, NULL);		ircomm_tty_next_state(self, IRCOMM_TTY_READY);		break;	case IRCOMM_TTY_WD_TIMER_EXPIRED:#if 1		/* Give up */#else		/* Try to discover any remote devices */				ircomm_tty_start_watchdog_timer(self, 3*HZ);		irlmp_discovery_request(DISCOVERY_DEFAULT_SLOTS);#endif		break;	case IRCOMM_TTY_DETACH_CABLE:		ircomm_tty_next_state(self, IRCOMM_TTY_IDLE);		break;	default:		IRDA_DEBUG(2, __FUNCTION__"(), unknown event: %s\n",			   ircomm_tty_event[event]);		return -EINVAL;	}	return ret;}/* * Function ircomm_tty_state_query (self, event, skb, info) * *    Querying the remote LM-IAS for IrCOMM parameters * */static int ircomm_tty_state_query_parameters(struct ircomm_tty_cb *self, 					     IRCOMM_TTY_EVENT event, 					     struct sk_buff *skb, 					     struct ircomm_tty_info *info){	int ret = 0;	IRDA_DEBUG(2, __FUNCTION__": state=%s, event=%s\n",		   ircomm_tty_state[self->state], ircomm_tty_event[event]);	switch (event) {	case IRCOMM_TTY_GOT_PARAMETERS:		if (self->iriap) {			WARNING(__FUNCTION__ 				"(), busy with a previous query\n");			return -EBUSY;		}				self->iriap = iriap_open(LSAP_ANY, IAS_CLIENT, self,					 ircomm_tty_getvalue_confirm);		iriap_getvaluebyclass_request(self->iriap, self->saddr, 					      self->daddr, "IrDA:IrCOMM", 					      "IrDA:TinyTP:LsapSel");		ircomm_tty_start_watchdog_timer(self, 3*HZ);		ircomm_tty_next_state(self, IRCOMM_TTY_QUERY_LSAP_SEL);		break;	case IRCOMM_TTY_WD_TIMER_EXPIRED:		/* Go back to search mode */		ircomm_tty_next_state(self, IRCOMM_TTY_SEARCH);		ircomm_tty_start_watchdog_timer(self, 3*HZ); 		break;	case IRCOMM_TTY_CONNECT_INDICATION:		del_timer(&self->watchdog_timer);		/* Accept connection */		ircomm_connect_response(self->ircomm, NULL);		ircomm_tty_next_state(self, IRCOMM_TTY_READY);		break;	case IRCOMM_TTY_DETACH_CABLE:		ircomm_tty_next_state(self, IRCOMM_TTY_IDLE);		break;	default:		IRDA_DEBUG(2, __FUNCTION__"(), unknown event: %s\n",			   ircomm_tty_event[event]);		return -EINVAL;	}	return ret;}/* * Function ircomm_tty_state_query_lsap_sel (self, event, skb, info) * *    Query remote LM-IAS for the LSAP selector which we can connect to * */static int ircomm_tty_state_query_lsap_sel(struct ircomm_tty_cb *self, 					   IRCOMM_TTY_EVENT event, 					   struct sk_buff *skb, 					   struct ircomm_tty_info *info){	int ret = 0;	IRDA_DEBUG(2, __FUNCTION__": state=%s, event=%s\n",		   ircomm_tty_state[self->state], ircomm_tty_event[event]);	switch (event) {	case IRCOMM_TTY_GOT_LSAPSEL:		/* Connect to remote device */		ret = ircomm_connect_request(self->ircomm, self->dlsap_sel,					     self->saddr, self->daddr, 					     NULL, self->service_type);		ircomm_tty_start_watchdog_timer(self, 3*HZ);		ircomm_tty_next_state(self, IRCOMM_TTY_SETUP);		break;	case IRCOMM_TTY_WD_TIMER_EXPIRED:		/* Go back to search mode */		ircomm_tty_next_state(self, IRCOMM_TTY_SEARCH);		ircomm_tty_start_watchdog_timer(self, 3*HZ);		break;	case IRCOMM_TTY_CONNECT_INDICATION:		del_timer(&self->watchdog_timer);		/* Accept connection */		ircomm_connect_response(self->ircomm, NULL);		ircomm_tty_next_state(self, IRCOMM_TTY_READY);		break;	case IRCOMM_TTY_DETACH_CABLE:		ircomm_tty_next_state(self, IRCOMM_TTY_IDLE);		break;	default:		IRDA_DEBUG(2, __FUNCTION__"(), unknown event: %s\n",			   ircomm_tty_event[event]);		return -EINVAL;	}	return ret;}/* * Function ircomm_tty_state_setup (self, event, skb, info) * *    Trying to connect * */static int ircomm_tty_state_setup(struct ircomm_tty_cb *self, 				  IRCOMM_TTY_EVENT event, 				  struct sk_buff *skb, 				  struct ircomm_tty_info *info){	int ret = 0;	IRDA_DEBUG(2, __FUNCTION__": state=%s, event=%s\n",		   ircomm_tty_state[self->state], ircomm_tty_event[event]);	switch (event) {	case IRCOMM_TTY_CONNECT_CONFIRM:		del_timer(&self->watchdog_timer);		ircomm_tty_next_state(self, IRCOMM_TTY_READY);				/* 		 * Send initial parameters. This will also send out queued		 * parameters waiting for the connection to come up 		 */		ircomm_tty_send_initial_parameters(self);		ircomm_tty_link_established(self);		break;	case IRCOMM_TTY_CONNECT_INDICATION:		del_timer(&self->watchdog_timer);				/* Accept connection */		ircomm_connect_response(self->ircomm, NULL);		ircomm_tty_next_state(self, IRCOMM_TTY_READY);		break;	case IRCOMM_TTY_WD_TIMER_EXPIRED:		/* Go back to search mode */		ircomm_tty_next_state(self, IRCOMM_TTY_SEARCH);		ircomm_tty_start_watchdog_timer(self, 3*HZ);		break;	case IRCOMM_TTY_DETACH_CABLE:		/* ircomm_disconnect_request(self->ircomm, NULL); */		ircomm_tty_next_state(self, IRCOMM_TTY_IDLE);		break;	default:		IRDA_DEBUG(2, __FUNCTION__"(), unknown event: %s\n",			   ircomm_tty_event[event]);		return -EINVAL;	}	return ret;}/* * Function ircomm_tty_state_ready (self, event, skb, info) * *    IrCOMM is now connected * */static int ircomm_tty_state_ready(struct ircomm_tty_cb *self, 				  IRCOMM_TTY_EVENT event, 				  struct sk_buff *skb, 				  struct ircomm_tty_info *info){	int ret = 0;	switch (event) {	case IRCOMM_TTY_DATA_REQUEST:		ret = ircomm_data_request(self->ircomm, skb);		break;			case IRCOMM_TTY_DETACH_CABLE:		ircomm_disconnect_request(self->ircomm, NULL);		ircomm_tty_next_state(self, IRCOMM_TTY_IDLE);		break;	case IRCOMM_TTY_DISCONNECT_INDICATION:		ircomm_tty_next_state(self, IRCOMM_TTY_SEARCH);		ircomm_tty_start_watchdog_timer(self, 3*HZ);		if (self->flags & ASYNC_CHECK_CD) {			/* Drop carrier */			self->settings.dce = IRCOMM_DELTA_CD;			ircomm_tty_check_modem_status(self);		} else {			IRDA_DEBUG(0, __FUNCTION__ "(), hanging up!\n");			if (self->tty)				tty_hangup(self->tty);		}		break;	default:		IRDA_DEBUG(2, __FUNCTION__"(), unknown event: %s\n",			   ircomm_tty_event[event]);		return -EINVAL;	}	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, __FUNCTION__": state=%s, event=%s\n",		   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, __FUNCTION__": next state=%s, service type=%d\n", 		   ircomm_tty_state[self->state], self->service_type);}

⌨️ 快捷键说明

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