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

📄 irlap.c

📁 sparc硬件平台上的红外协议
💻 C
📖 第 1 页 / 共 3 页
字号:
/*********************************************************************** Filename:      irlap.c* Version:       1.0* Description:   IrLAP implementation for Linux* Status:        Stable* Author:        Dag Brattli <dagb@cs.uit.no>* Created at:    Mon Aug  4 20:40:53 1997* Modified at:   Tue Dec 14 09:26:44 1999* Modified by:   Dag Brattli <dagb@cs.uit.no>**     Copyright (c) 1998-1999 Dag Brattli, All Rights Reserved.*     Copyright (c) 2000-2003 Jean Tourrilhes <jt@hpl.hp.com>**     This program is free software; you can redistribute it and/or*     modify it under the terms of the GNU General Public License as*     published by the Free Software Foundation; either version 2 of*     the License, or (at your option) any later version.**     This program is distributed in the hope that it will be useful,*     but WITHOUT ANY WARRANTY; without even the implied warranty of*     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the*     GNU General Public License for more details.**     You should have received a copy of the GNU General Public License*     along with this program; if not, write to the Free Software*     Foundation, Inc., 59 Temple Place, Suite 330, Boston,*     MA 02111-1307 USA*********************************************************************/#include <string.h>#include "skbuff.h"#include "irda.h"#include "irda_device.h"#include "irqueue.h"#include "irlmp.h"#include "irlmp_frame.h"#include "irlap_frame.h"#include "irlap.h"#include "timer.h"#include "qos.h"hashbin_t *irlap = NULL;int sysctl_slot_timeout = SLOT_TIMEOUT * 1000 / HZ;/* This is the delay of missed pf period before generating an event* to the application. The spec mandate 3 seconds, but in some cases* it's way too long. - Jean II */int sysctl_warn_noreply_time = 3;extern void irlap_queue_xmit(struct irlap_cb *self, struct sk_buff *skb);static void __irlap_close(struct irlap_cb *self);static void irlap_init_qos_capabilities(struct irlap_cb *self,										struct qos_info *qos_user);#ifdef CONFIG_IRDA_DEBUGstatic char *lap_reasons[] = {	"ERROR, NOT USED",		"LAP_DISC_INDICATION",		"LAP_NO_RESPONSE",		"LAP_RESET_INDICATION",		"LAP_FOUND_NONE",		"LAP_MEDIA_BUSY",		"LAP_PRIMARY_CONFLICT",		"ERROR, NOT USED",};#endif	/* CONFIG_IRDA_DEBUG */int  irlap_init(void){/* Check if the compiler did its job properly.	* May happen on some ARM configuration, check with Russell King. */	IRDA_ASSERT(sizeof(struct xid_frame) == 14, ;);	IRDA_ASSERT(sizeof(struct test_frame) == 10, ;);	IRDA_ASSERT(sizeof(struct ua_frame) == 10, ;);	IRDA_ASSERT(sizeof(struct snrm_frame) == 11, ;);	IRDA_DEBUG(1, "%s()\n", __FUNCTION__);	/* Allocate master array */	irlap = hashbin_new(HB_LOCK);	if (irlap == NULL) {		IRDA_ERROR("%s: can't allocate irlap hashbin!\n",			__FUNCTION__);		return -ENOMEM;	}		return 0;}void irlap_cleanup(void){	IRDA_ASSERT(irlap != NULL, return;);	hashbin_delete(irlap, (FREE_FUNC) __irlap_close);}void get_random_bytes(__u32* data,__u32 len){    static int temp = 1;    temp++;#ifdef BIG_ENDIN    switch(len)	{	case 1:		if (temp >= 0xff)		{			temp = 0x01;  		}		*data = temp<<24;		break;	case 2:		if (temp >= 0xffff)		{			temp = 0x01;  		}		*data = temp<<16;		break;	case 4:		if (temp >= BROADCAST)		{			temp = 1;		}    default:		*data = temp;		break;	}#else	switch(len)	{	case 1:		if (temp >= 0xff)		{			temp = 0x01;		}				break;	case 2:		if (temp >= 0xffff)		{			temp = 0x01;		}				break;	case 4:		if (temp >= BROADCAST)		{			temp = 1;		}    default:				break;	}		*data = temp;#endif	}/** Function irlap_open (driver)**    Initialize IrLAP layer**/struct irlap_cb *irlap_open(struct net_device *dev, struct qos_info *qos,							const char *hw_name){	struct irlap_cb *self;		IRDA_DEBUG(4, "%s()\n", __FUNCTION__);		/* Initialize the irlap structure. */	self =(struct irlap_cb*) malloc(sizeof(struct irlap_cb));	if (self == NULL)	{		IRDA_ERROR("%s() can not allocate memory\n",__FUNCTION__);		return NULL;	}	//初始化	memset(self,0,sizeof(struct irlap_cb));	self->magic = LAP_MAGIC;		/* Make a binding between the layers */	self->netdev = dev;		self->qos_dev = qos;	/* Copy hardware name */	if(hw_name != NULL) {		strncpy(self->hw_name, hw_name, sizeof(self->hw_name));	} else {		self->hw_name[0] = '\0';	}		/* FIXME: should we get our own field? */	dev->atalk_ptr = self;		self->state = LAP_OFFLINE;		/* Initialize transmit queue */	skb_queue_head_init(&self->txq);	skb_queue_head_init(&self->txq_ultra);	skb_queue_head_init(&self->wx_list);	/* My unique IrLAP device address! */	/* We don't want the broadcast address, neither the NULL address	* (most often used to signify "invalid"), and we don't want an	* address already in use (otherwise connect won't be able	* to select the proper link). - Jean II */	do {		//xugangan 没有考虑大小端		get_random_bytes(&self->saddr, sizeof(self->saddr));			} while ((self->saddr == 0x0) || (self->saddr == BROADCAST) ||		(hashbin_lock_find(irlap, self->saddr, NULL)) );		memcpy(dev->dev_addr, &self->saddr, 4);		//init_timer(&self->slot_timer);	//init_timer(&self->query_timer);	//init_timer(&self->discovery_timer);	//init_timer(&self->final_timer);	//init_timer(&self->poll_timer);	//init_timer(&self->wd_timer);	//init_timer(&self->backoff_timer);	//init_timer(&self->media_busy_timer);					irlap_apply_default_connection_parameters(self);		self->N3 = 3; /* # connections attemts to try before giving up */		self->state = LAP_NDM;		hashbin_insert(irlap, (irda_queue_t *) self, self->saddr, NULL);		irlmp_register_link(self, self->saddr, &self->notify);		return self;}/** Function __irlap_close (self)**    Remove IrLAP and all allocated memory. Stop any pending timers.**/static void __irlap_close(struct irlap_cb *self){	IRDA_ASSERT(self != NULL, return;);	IRDA_ASSERT(self->magic == LAP_MAGIC, return;);	/* Stop timers */	del_timer(&self->slot_timerid);	del_timer(&self->query_timerid);	del_timer(&self->discovery_timerid);	del_timer(&self->final_timerid);	del_timer(&self->poll_timerid);	del_timer(&self->wd_timerid);	del_timer(&self->backoff_timerid);	del_timer(&self->media_busy_timerid);		irlap_flush_all_queues(self);		self->magic = 0;		free(self);	self  = NULL;}/** Function irlap_close (self)**    Remove IrLAP instance**/void irlap_close(struct irlap_cb *self){	struct irlap_cb *lap;		IRDA_DEBUG(4, "%s() self = %x,self->magic= %x\n", __FUNCTION__,self,self->magic);		IRDA_ASSERT(self != NULL, return;);	IRDA_ASSERT(self->magic == LAP_MAGIC, return;);	/* We used to send a LAP_DISC_INDICATION here, but this was	* racy. This has been move within irlmp_unregister_link()	* itself. Jean II */		/* Kill the LAP and all LSAPs on top of it */	irlmp_unregister_link(self->saddr);	self->notify.instance = NULL;		/* Be sure that we manage to remove ourself from the hash */	lap = hashbin_remove(irlap, self->saddr, NULL);	if (!lap) {		IRDA_DEBUG(4, "%s(), Didn't find myself!\n", __FUNCTION__);		return;	}	__irlap_close(lap);}/** Function irlap_connect_indication (self, skb)**    Another device is attempting to make a connection**/void irlap_connect_indication(struct irlap_cb *self, struct sk_buff *skb){	IRDA_DEBUG(1, "%s()\n", __FUNCTION__);		IRDA_ASSERT(self != NULL, return;);	IRDA_ASSERT(self->magic == LAP_MAGIC, return;);		irlap_init_qos_capabilities(self, NULL); /* No user QoS! */		irlmp_link_connect_indication(self->notify.instance, self->saddr,		self->daddr, &self->qos_tx, skb);}/** Function irlap_connect_response (self, skb)**    Service user has accepted incoming connection**/void irlap_connect_response(struct irlap_cb *self, struct sk_buff *userdata){	IRDA_DEBUG(2, "%s()\n", __FUNCTION__);		irlap_do_event(self, CONNECT_RESPONSE, userdata, NULL);}/** Function irlap_connect_request (self, daddr, qos_user, sniff)**    Request connection with another device, sniffing is not implemented*    yet.**/void irlap_connect_request(struct irlap_cb *self, __u32 daddr,						   struct qos_info *qos_user, int sniff){	IRDA_DEBUG(3, "%s(), daddr=0x%08x ,\n", __FUNCTION__, daddr);		IRDA_ASSERT(self != NULL, return;);	IRDA_ASSERT(self->magic == LAP_MAGIC, return;);		self->daddr = daddr;		/*	*  If the service user specifies QoS values for this connection,	*  then use them	*/	irlap_init_qos_capabilities(self, qos_user);		if ((self->state == LAP_NDM) && !self->media_busy)	{		IRDA_DEBUG(1, "%s(), connect_pending flase\n", __FUNCTION__);		irlap_do_event(self, CONNECT_REQUEST, NULL, NULL);	}	else	{		IRDA_DEBUG(1, "%s(), connect_pending true\n", __FUNCTION__);		self->connect_pending = TRUE;	}}/** Function irlap_connect_confirm (self, skb)**    Connection request has been accepted**/void irlap_connect_confirm(struct irlap_cb *self, struct sk_buff *skb){	IRDA_DEBUG(1, "%s()\n", __FUNCTION__);		IRDA_ASSERT(self != NULL, return;);	IRDA_ASSERT(self->magic == LAP_MAGIC, return;);		irlmp_link_connect_confirm(self->notify.instance, &self->qos_tx, skb);

⌨️ 快捷键说明

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