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

📄 irlap.c

📁 sparc硬件平台上的红外协议
💻 C
📖 第 1 页 / 共 3 页
字号:
}/** Function irlap_data_indication (self, skb)**    Received data frames from IR-port, so we just pass them up to*    IrLMP for further processing**/void irlap_data_indication(struct irlap_cb *self, struct sk_buff *skb,						   int unreliable){	/* Hide LAP header from IrLMP layer */	IRDA_DEBUG(3, "%s()\n", __FUNCTION__);	skb_pull(skb, LAP_ADDR_HEADER+LAP_CTRL_HEADER);		irlmp_link_data_indication(self->notify.instance, skb, unreliable);}/** Function irlap_data_request (self, skb)**    Queue data for transmission, must wait until XMIT state**/void irlap_data_request(struct irlap_cb *self, struct sk_buff *skb,						int unreliable){	int i=0;		IRDA_ASSERT(self != NULL, return;);	IRDA_ASSERT(self->magic == LAP_MAGIC, return;);		IRDA_DEBUG(1, "%s()\n", __FUNCTION__);			IRDA_DEBUG(1, "%s()\n", __FUNCTION__);		skb_push(skb, LAP_ADDR_HEADER+LAP_CTRL_HEADER);		/*	*  Must set frame format now so that the rest of the code knows	*  if its dealing with an I or an UI frame	*/	if (unreliable)		skb->data[1] = UI_FRAME;	else		skb->data[1] = I_FRAME;		/* Don't forget to refcount it - see irlmp_connect_request(). */	skb_get(skb);		/* Add at the end of the queue (keep ordering) - Jean II */	skb_queue_tail(&self->txq, skb);				/*	*  Send event if this frame only if we are in the right state	*  FIXME: udata should be sent first! (skb_queue_head?)	*/	if ((self->state == LAP_XMIT_P) || (self->state == LAP_XMIT_S)) {	/* If we are not already processing the Tx queue, trigger		* transmission immediately - Jean II */		IRDA_DEBUG(4, "first %s()\n", __FUNCTION__);		if((skb_queue_len(&self->txq) <= 1) && (!self->local_busy))		{			IRDA_DEBUG(4, "send %s()\n", __FUNCTION__);			irlap_do_event(self, DATA_REQUEST, skb, NULL);		}		/* Otherwise, the packets will be sent normally at the		* next pf-poll - Jean II */	}}/** Function irlap_disconnect_request (void)**    Request to disconnect connection by service user*/void irlap_disconnect_request(struct irlap_cb *self){	IRDA_DEBUG(3, "%s(),%d,nrms = %d\n", __FUNCTION__,self->state,LAP_NRM_S);		IRDA_ASSERT(self != NULL, return;);	IRDA_ASSERT(self->magic == LAP_MAGIC, return;);		/* Don't disconnect until all data frames are successfully sent */	if (!skb_queue_empty(&self->txq)) {		self->disconnect_pending = TRUE;		return;	}		/* Check if we are in the right state for disconnecting */	switch (self->state) {	case LAP_XMIT_P:        /* FALLTROUGH */	case LAP_XMIT_S:        /* FALLTROUGH */	case LAP_CONN:          /* FALLTROUGH */	case LAP_RESET_WAIT:    /* FALLTROUGH */	case LAP_RESET_CHECK:		irlap_do_event(self, DISCONNECT_REQUEST, NULL, NULL);		break;	default:		IRDA_DEBUG(2, "%s(), disconnect pending!\n", __FUNCTION__);		self->disconnect_pending = TRUE;		break;	}}extern int sendover_flag ;extern int rec_over_flag;/** Function irlap_disconnect_indication (void)**    Disconnect request from other device**/void irlap_disconnect_indication(struct irlap_cb *self, LAP_REASON reason){	IRDA_DEBUG(1, "%s(), reason=%s\n", __FUNCTION__, lap_reasons[reason]);		IRDA_ASSERT(self != NULL, return;);	IRDA_ASSERT(self->magic == LAP_MAGIC, return;);		/* Flush queues */	irlap_flush_all_queues(self);		switch (reason) {	case LAP_RESET_INDICATION:		IRDA_DEBUG(1, "%s(), Sending reset request!\n", __FUNCTION__);		irlap_do_event(self, RESET_REQUEST, NULL, NULL);		break;	case LAP_NO_RESPONSE:	   /* FALLTROUGH */	case LAP_DISC_INDICATION:  /* FALLTROUGH */	case LAP_FOUND_NONE:       /* FALLTROUGH */	case LAP_MEDIA_BUSY:		irlmp_link_disconnect_indication(self->notify.instance, self,			reason, NULL);		break;	default:		IRDA_ERROR("%s: Unknown reason %d\n", __FUNCTION__, reason);	}		rec_over_flag = 1;	sendover_flag = 1;}/** Function irlap_discovery_request (gen_addr_bit)**    Start one single discovery operation.**/void irlap_discovery_request(struct irlap_cb *self, discovery_t *discovery){	struct irlap_info info;		IRDA_ASSERT(self != NULL, return;);	IRDA_ASSERT(self->magic == LAP_MAGIC, return;);	IRDA_ASSERT(discovery != NULL, return;);		IRDA_DEBUG(1, "%s(), nslots = %d\n", __FUNCTION__, discovery->nslots);		IRDA_ASSERT((discovery->nslots == 1) || (discovery->nslots == 6) ||		(discovery->nslots == 8) || (discovery->nslots == 16),		return;);		/* Discovery is only possible in NDM mode */	if (self->state != LAP_NDM) {		IRDA_DEBUG(4, "%s(), discovery only possible in NDM mode\n",			__FUNCTION__);		irlap_discovery_confirm(self, NULL);		/* Note : in theory, if we are not in NDM, we could postpone		* the discovery like we do for connection request.		* In practice, it's not worth it. If the media was busy,		* it's likely next time around it won't be busy. If we are		* in REPLY state, we will get passive discovery info & event.		* Jean II */		return;	}		/* Check if last discovery request finished in time, or if	* it was aborted due to the media busy flag. */	if (self->discovery_log != NULL) {		hashbin_delete(self->discovery_log, (FREE_FUNC) free);		self->discovery_log = NULL;	}		/* All operations will occur at predictable time, no need to lock */	self->discovery_log = hashbin_new(HB_NOLOCK);		if (self->discovery_log == NULL) {		IRDA_WARNING("%s(), Unable to allocate discovery log!\n",			__FUNCTION__);		return;	}		info.S = discovery->nslots; /* Number of slots */	info.s = 0; /* Current slot */	self->discovery_cmd = discovery;	info.discovery = discovery;		/* sysctl_slot_timeout bounds are checked in irsysctl.c - Jean II */	self->slot_timeout = sysctl_slot_timeout * HZ / 1000;		irlap_do_event(self, DISCOVERY_REQUEST, NULL, &info);}/** Function irlap_discovery_confirm (log)**    A device has been discovered in front of this station, we*    report directly to LMP.*/void irlap_discovery_confirm(struct irlap_cb *self, hashbin_t *discovery_log){	IRDA_DEBUG(1, "%s() addr %x\n", __FUNCTION__,self);	IRDA_ASSERT(self != NULL, return;);	IRDA_ASSERT(self->magic == LAP_MAGIC, return;);		IRDA_ASSERT(self->notify.instance != NULL, return;);		/*	* Check for successful discovery, since we are then allowed to clear	* the media busy condition (IrLAP 6.13.4 - p.94). This should allow	* us to make connection attempts much faster and easier (i.e. no	* collisions).	* Setting media busy to false will also generate an event allowing	* to process pending events in NDM state machine.	* Note : the spec doesn't define what's a successful discovery is.	* If we want Ultra to work, it's successful even if there is	* nobody discovered - Jean II	*/	if (discovery_log)		irda_device_set_media_busy(self->netdev, FALSE);		/* Inform IrLMP */	irlmp_link_discovery_confirm(self->notify.instance, discovery_log);}/** Function irlap_discovery_indication (log)**    Somebody is trying to discover us!**/void irlap_discovery_indication(struct irlap_cb *self, discovery_t *discovery){	IRDA_DEBUG(1, "%s()\n", __FUNCTION__);		IRDA_ASSERT(self != NULL, return;);	IRDA_ASSERT(self->magic == LAP_MAGIC, return;);	IRDA_ASSERT(discovery != NULL, return;);		IRDA_ASSERT(self->notify.instance != NULL, return;);		/* A device is very likely to connect immediately after it performs	* a successful discovery. This means that in our case, we are much	* more likely to receive a connection request over the medium.	* So, we backoff to avoid collisions.	* IrLAP spec 6.13.4 suggest 100ms...	* Note : this little trick actually make a *BIG* difference. If I set	* my Linux box with discovery enabled and one Ultra frame sent every	* second, my Palm has no trouble connecting to it every time !	* Jean II */	irda_device_set_media_busy(self->netdev, SMALL);		irlmp_link_discovery_indication(self->notify.instance, discovery);}/** Function irlap_status_indication (quality_of_link)*/void irlap_status_indication(struct irlap_cb *self, int quality_of_link){	switch (quality_of_link) {	case STATUS_NO_ACTIVITY:		IRDA_MESSAGE("IrLAP, no activity on link!\n");		break;	case STATUS_NOISY:		IRDA_MESSAGE("IrLAP, noisy link!\n");		break;	default:		break;	}	irlmp_status_indication(self->notify.instance,		quality_of_link, LOCK_NO_CHANGE);}/** Function irlap_reset_indication (void)*/void irlap_reset_indication(struct irlap_cb *self){	IRDA_DEBUG(1, "%s()\n", __FUNCTION__);		IRDA_ASSERT(self != NULL, return;);	IRDA_ASSERT(self->magic == LAP_MAGIC, return;);		if (self->state == LAP_RESET_WAIT)		irlap_do_event(self, RESET_REQUEST, NULL, NULL);	else		irlap_do_event(self, RESET_RESPONSE, NULL, NULL);}/** Function irlap_reset_confirm (void)*/void irlap_reset_confirm(void){	IRDA_DEBUG(1, "%s()\n", __FUNCTION__);}/** Function irlap_generate_rand_time_slot (S, s)**    Generate a random time slot between s and S-1 where*    S = Number of slots (0 -> S-1)*    s = Current slot*/int irlap_generate_rand_time_slot(int S, int s){	static int rand;	int slot;		IRDA_ASSERT((S - s) > 0, return 0;);	// modify by xugan	time_t i_time = kern_time_get();	rand += i_time;	rand ^= (rand << 12);	rand ^= (rand >> 20);		slot = s + rand % (S-s);		IRDA_ASSERT((slot >= s) || (slot < S), return 0;);		return slot;}/** Function irlap_update_nr_received (nr)**    Remove all acknowledged frames in current window queue. This code is*    not intuitive and you should not try to change it. If you think it*    contains bugs, please mail a patch to the author instead.*/void irlap_update_nr_received(struct irlap_cb *self, int nr){	struct sk_buff *skb = NULL;	int count = 0;		/*	* Remove all the ack-ed frames from the window queue.	*/		/*	*  Optimize for the common case. It is most likely that the receiver	*  will acknowledge all the frames we have sent! So in that case we	*  delete all frames stored in window.	*/	if (nr == self->vs) {		while ((skb = skb_dequeue(&self->wx_list)) != NULL) {			dev_kfree_skb(skb);		}		/* The last acked frame is the next to send minus one */		self->va = nr - 1;	} else {		/* Remove all acknowledged frames in current window */		while ((skb_peek(&self->wx_list) != NULL) &&			(((self->va+1) % 8) != nr))		{			skb = skb_dequeue(&self->wx_list);			dev_kfree_skb(skb);						self->va = (self->va + 1) % 8;			count++;		}	}		/* Advance window */	self->window = self->window_size - skb_queue_len(&self->wx_list);

⌨️ 快捷键说明

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