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

📄 iriap.c

📁 linux 内核源代码
💻 C
📖 第 1 页 / 共 2 页
字号:
	__be32 tmp_be32;	__be16 tmp_be16;	__u8 *fp;	IRDA_DEBUG(4, "%s()\n", __FUNCTION__);	IRDA_ASSERT(self != NULL, return;);	IRDA_ASSERT(self->magic == IAS_MAGIC, return;);	IRDA_ASSERT(value != NULL, return;);	IRDA_ASSERT(value->len <= 1024, return;);	/* Initialize variables */	n = 0;	/*	 *  We must adjust the size of the response after the length of the	 *  value. We add 32 bytes because of the 6 bytes for the frame and	 *  max 5 bytes for the value coding.	 */	tx_skb = alloc_skb(value->len + self->max_header_size + 32,			   GFP_ATOMIC);	if (!tx_skb)		return;	/* Reserve space for MUX and LAP header */	skb_reserve(tx_skb, self->max_header_size);	skb_put(tx_skb, 6);	fp = tx_skb->data;	/* Build frame */	fp[n++] = GET_VALUE_BY_CLASS | IAP_LST;	fp[n++] = ret_code;	/* Insert list length (MSB first) */	tmp_be16 = __constant_htons(0x0001);	memcpy(fp+n, &tmp_be16, 2);  n += 2;	/* Insert object identifier ( MSB first) */	tmp_be16 = cpu_to_be16(obj_id);	memcpy(fp+n, &tmp_be16, 2); n += 2;	switch (value->type) {	case IAS_STRING:		skb_put(tx_skb, 3 + value->len);		fp[n++] = value->type;		fp[n++] = 0; /* ASCII */		fp[n++] = (__u8) value->len;		memcpy(fp+n, value->t.string, value->len); n+=value->len;		break;	case IAS_INTEGER:		skb_put(tx_skb, 5);		fp[n++] = value->type;		tmp_be32 = cpu_to_be32(value->t.integer);		memcpy(fp+n, &tmp_be32, 4); n += 4;		break;	case IAS_OCT_SEQ:		skb_put(tx_skb, 3 + value->len);		fp[n++] = value->type;		tmp_be16 = cpu_to_be16(value->len);		memcpy(fp+n, &tmp_be16, 2); n += 2;		memcpy(fp+n, value->t.oct_seq, value->len); n+=value->len;		break;	case IAS_MISSING:		IRDA_DEBUG( 3, "%s: sending IAS_MISSING\n", __FUNCTION__);		skb_put(tx_skb, 1);		fp[n++] = value->type;		break;	default:		IRDA_DEBUG(0, "%s(), type not implemented!\n", __FUNCTION__);		break;	}	iriap_do_r_connect_event(self, IAP_CALL_RESPONSE, tx_skb);	/* Drop reference count - see state_r_execute(). */	dev_kfree_skb(tx_skb);}/* * Function iriap_getvaluebyclass_indication (self, skb) * *    getvaluebyclass is requested from peer LM-IAS * */static void iriap_getvaluebyclass_indication(struct iriap_cb *self,					     struct sk_buff *skb){	struct ias_object *obj;	struct ias_attrib *attrib;	int name_len;	int attr_len;	char name[IAS_MAX_CLASSNAME + 1];	/* 60 bytes */	char attr[IAS_MAX_ATTRIBNAME + 1];	/* 60 bytes */	__u8 *fp;	int n;	IRDA_DEBUG(4, "%s()\n", __FUNCTION__);	IRDA_ASSERT(self != NULL, return;);	IRDA_ASSERT(self->magic == IAS_MAGIC, return;);	IRDA_ASSERT(skb != NULL, return;);	fp = skb->data;	n = 1;	name_len = fp[n++];	memcpy(name, fp+n, name_len); n+=name_len;	name[name_len] = '\0';	attr_len = fp[n++];	memcpy(attr, fp+n, attr_len); n+=attr_len;	attr[attr_len] = '\0';	IRDA_DEBUG(4, "LM-IAS: Looking up %s: %s\n", name, attr);	obj = irias_find_object(name);	if (obj == NULL) {		IRDA_DEBUG(2, "LM-IAS: Object %s not found\n", name);		iriap_getvaluebyclass_response(self, 0x1235, IAS_CLASS_UNKNOWN,					       &irias_missing);		return;	}	IRDA_DEBUG(4, "LM-IAS: found %s, id=%d\n", obj->name, obj->id);	attrib = irias_find_attrib(obj, attr);	if (attrib == NULL) {		IRDA_DEBUG(2, "LM-IAS: Attribute %s not found\n", attr);		iriap_getvaluebyclass_response(self, obj->id,					       IAS_ATTRIB_UNKNOWN,					       &irias_missing);		return;	}	/* We have a match; send the value.  */	iriap_getvaluebyclass_response(self, obj->id, IAS_SUCCESS,				       attrib->value);	return;}/* * Function iriap_send_ack (void) * *    Currently not used * */void iriap_send_ack(struct iriap_cb *self){	struct sk_buff *tx_skb;	__u8 *frame;	IRDA_DEBUG(2, "%s()\n", __FUNCTION__);	IRDA_ASSERT(self != NULL, return;);	IRDA_ASSERT(self->magic == IAS_MAGIC, return;);	tx_skb = alloc_skb(LMP_MAX_HEADER + 1, GFP_ATOMIC);	if (!tx_skb)		return;	/* Reserve space for MUX and LAP header */	skb_reserve(tx_skb, self->max_header_size);	skb_put(tx_skb, 1);	frame = tx_skb->data;	/* Build frame */	frame[0] = IAP_LST | IAP_ACK | self->operation;	irlmp_data_request(self->lsap, tx_skb);}void iriap_connect_request(struct iriap_cb *self){	int ret;	IRDA_ASSERT(self != NULL, return;);	IRDA_ASSERT(self->magic == IAS_MAGIC, return;);	ret = irlmp_connect_request(self->lsap, LSAP_IAS,				    self->saddr, self->daddr,				    NULL, NULL);	if (ret < 0) {		IRDA_DEBUG(0, "%s(), connect failed!\n", __FUNCTION__);		self->confirm(IAS_DISCONNECT, 0, NULL, self->priv);	}}/* * Function iriap_connect_confirm (handle, skb) * *    LSAP connection confirmed! * */static void iriap_connect_confirm(void *instance, void *sap,				  struct qos_info *qos, __u32 max_seg_size,				  __u8 max_header_size,				  struct sk_buff *skb){	struct iriap_cb *self;	self = (struct iriap_cb *) instance;	IRDA_ASSERT(self != NULL, return;);	IRDA_ASSERT(self->magic == IAS_MAGIC, return;);	IRDA_ASSERT(skb != NULL, return;);	self->max_data_size = max_seg_size;	self->max_header_size = max_header_size;	del_timer(&self->watchdog_timer);	iriap_do_client_event(self, IAP_LM_CONNECT_CONFIRM, skb);	/* Drop reference count - see state_s_make_call(). */	dev_kfree_skb(skb);}/* * Function iriap_connect_indication ( handle, skb) * *    Remote LM-IAS is requesting connection * */static void iriap_connect_indication(void *instance, void *sap,				     struct qos_info *qos, __u32 max_seg_size,				     __u8 max_header_size,				     struct sk_buff *skb){	struct iriap_cb *self, *new;	IRDA_DEBUG(1, "%s()\n", __FUNCTION__);	self = (struct iriap_cb *) instance;	IRDA_ASSERT(skb != NULL, return;);	IRDA_ASSERT(self != NULL, goto out;);	IRDA_ASSERT(self->magic == IAS_MAGIC, goto out;);	/* Start new server */	new = iriap_open(LSAP_IAS, IAS_SERVER, NULL, NULL);	if (!new) {		IRDA_DEBUG(0, "%s(), open failed\n", __FUNCTION__);		goto out;	}	/* Now attach up the new "socket" */	new->lsap = irlmp_dup(self->lsap, new);	if (!new->lsap) {		IRDA_DEBUG(0, "%s(), dup failed!\n", __FUNCTION__);		goto out;	}	new->max_data_size = max_seg_size;	new->max_header_size = max_header_size;	/* Clean up the original one to keep it in listen state */	irlmp_listen(self->lsap);	iriap_do_server_event(new, IAP_LM_CONNECT_INDICATION, skb);out:	/* Drop reference count - see state_r_disconnect(). */	dev_kfree_skb(skb);}/* * Function iriap_data_indication (handle, skb) * *    Receives data from connection identified by handle from IrLMP * */static int iriap_data_indication(void *instance, void *sap,				 struct sk_buff *skb){	struct iriap_cb *self;	__u8  *frame;	__u8  opcode;	IRDA_DEBUG(3, "%s()\n", __FUNCTION__);	self = (struct iriap_cb *) instance;	IRDA_ASSERT(skb != NULL, return 0;);	IRDA_ASSERT(self != NULL, goto out;);	IRDA_ASSERT(self->magic == IAS_MAGIC, goto out;);	frame = skb->data;	if (self->mode == IAS_SERVER) {		/* Call server */		IRDA_DEBUG(4, "%s(), Calling server!\n", __FUNCTION__);		iriap_do_r_connect_event(self, IAP_RECV_F_LST, skb);		goto out;	}	opcode = frame[0];	if (~opcode & IAP_LST) {		IRDA_WARNING("%s:, IrIAS multiframe commands or "			     "results is not implemented yet!\n",			     __FUNCTION__);		goto out;	}	/* Check for ack frames since they don't contain any data */	if (opcode & IAP_ACK) {		IRDA_DEBUG(0, "%s() Got ack frame!\n", __FUNCTION__);		goto out;	}	opcode &= ~IAP_LST; /* Mask away LST bit */	switch (opcode) {	case GET_INFO_BASE:		IRDA_DEBUG(0, "IrLMP GetInfoBaseDetails not implemented!\n");		break;	case GET_VALUE_BY_CLASS:		iriap_do_call_event(self, IAP_RECV_F_LST, NULL);		switch (frame[1]) {		case IAS_SUCCESS:			iriap_getvaluebyclass_confirm(self, skb);			break;		case IAS_CLASS_UNKNOWN:			IRDA_DEBUG(1, "%s(), No such class!\n", __FUNCTION__);			/* Finished, close connection! */			iriap_disconnect_request(self);			/*			 * Warning, the client might close us, so remember			 * no to use self anymore after calling confirm			 */			if (self->confirm)				self->confirm(IAS_CLASS_UNKNOWN, 0, NULL,					      self->priv);			break;		case IAS_ATTRIB_UNKNOWN:			IRDA_DEBUG(1, "%s(), No such attribute!\n", __FUNCTION__);			/* Finished, close connection! */			iriap_disconnect_request(self);			/*			 * Warning, the client might close us, so remember			 * no to use self anymore after calling confirm			 */			if (self->confirm)				self->confirm(IAS_ATTRIB_UNKNOWN, 0, NULL,					      self->priv);			break;		}		break;	default:		IRDA_DEBUG(0, "%s(), Unknown op-code: %02x\n", __FUNCTION__,			   opcode);		break;	}out:	/* Cleanup - sub-calls will have done skb_get() as needed. */	dev_kfree_skb(skb);	return 0;}/* * Function iriap_call_indication (self, skb) * *    Received call to server from peer LM-IAS * */void iriap_call_indication(struct iriap_cb *self, struct sk_buff *skb){	__u8 *fp;	__u8 opcode;	IRDA_DEBUG(4, "%s()\n", __FUNCTION__);	IRDA_ASSERT(self != NULL, return;);	IRDA_ASSERT(self->magic == IAS_MAGIC, return;);	IRDA_ASSERT(skb != NULL, return;);	fp = skb->data;	opcode = fp[0];	if (~opcode & 0x80) {		IRDA_WARNING("%s: IrIAS multiframe commands or results "			     "is not implemented yet!\n", __FUNCTION__);		return;	}	opcode &= 0x7f; /* Mask away LST bit */	switch (opcode) {	case GET_INFO_BASE:		IRDA_WARNING("%s: GetInfoBaseDetails not implemented yet!\n",			     __FUNCTION__);		break;	case GET_VALUE_BY_CLASS:		iriap_getvaluebyclass_indication(self, skb);		break;	}	/* skb will be cleaned up in iriap_data_indication */}/* * Function iriap_watchdog_timer_expired (data) * *    Query has taken too long time, so abort * */static void iriap_watchdog_timer_expired(void *data){	struct iriap_cb *self = (struct iriap_cb *) data;	IRDA_ASSERT(self != NULL, return;);	IRDA_ASSERT(self->magic == IAS_MAGIC, return;);	/* iriap_close(self); */}#ifdef CONFIG_PROC_FSstatic const char *ias_value_types[] = {	"IAS_MISSING",	"IAS_INTEGER",	"IAS_OCT_SEQ",	"IAS_STRING"};static inline struct ias_object *irias_seq_idx(loff_t pos){	struct ias_object *obj;	for (obj = (struct ias_object *) hashbin_get_first(irias_objects);	     obj; obj = (struct ias_object *) hashbin_get_next(irias_objects)) {		if (pos-- == 0)			break;	}	return obj;}static void *irias_seq_start(struct seq_file *seq, loff_t *pos){	spin_lock_irq(&irias_objects->hb_spinlock);	return *pos ? irias_seq_idx(*pos - 1) : SEQ_START_TOKEN;}static void *irias_seq_next(struct seq_file *seq, void *v, loff_t *pos){	++*pos;	return (v == SEQ_START_TOKEN)		? (void *) hashbin_get_first(irias_objects)		: (void *) hashbin_get_next(irias_objects);}static void irias_seq_stop(struct seq_file *seq, void *v){	spin_unlock_irq(&irias_objects->hb_spinlock);}static int irias_seq_show(struct seq_file *seq, void *v){	if (v == SEQ_START_TOKEN)		seq_puts(seq, "LM-IAS Objects:\n");	else {		struct ias_object *obj = v;		struct ias_attrib *attrib;		IRDA_ASSERT(obj->magic == IAS_OBJECT_MAGIC, return -EINVAL;);		seq_printf(seq, "name: %s, id=%d\n",			   obj->name, obj->id);		/* Careful for priority inversions here !		 * All other uses of attrib spinlock are independent of		 * the object spinlock, so we are safe. Jean II */		spin_lock(&obj->attribs->hb_spinlock);		/* List all attributes for this object */		for (attrib = (struct ias_attrib *) hashbin_get_first(obj->attribs);		     attrib != NULL;		     attrib = (struct ias_attrib *) hashbin_get_next(obj->attribs)) {			IRDA_ASSERT(attrib->magic == IAS_ATTRIB_MAGIC,				    goto outloop; );			seq_printf(seq, " - Attribute name: \"%s\", ",				   attrib->name);			seq_printf(seq, "value[%s]: ",				   ias_value_types[attrib->value->type]);			switch (attrib->value->type) {			case IAS_INTEGER:				seq_printf(seq, "%d\n",					   attrib->value->t.integer);				break;			case IAS_STRING:				seq_printf(seq, "\"%s\"\n",					   attrib->value->t.string);				break;			case IAS_OCT_SEQ:				seq_printf(seq, "octet sequence (%d bytes)\n",					   attrib->value->len);				break;			case IAS_MISSING:				seq_puts(seq, "missing\n");				break;			default:				seq_printf(seq, "type %d?\n",					   attrib->value->type);			}			seq_putc(seq, '\n');		}	IRDA_ASSERT_LABEL(outloop:)		spin_unlock(&obj->attribs->hb_spinlock);	}	return 0;}static const struct seq_operations irias_seq_ops = {	.start  = irias_seq_start,	.next   = irias_seq_next,	.stop   = irias_seq_stop,	.show   = irias_seq_show,};static int irias_seq_open(struct inode *inode, struct file *file){	IRDA_ASSERT( irias_objects != NULL, return -EINVAL;);	return seq_open(file, &irias_seq_ops);}const struct file_operations irias_seq_fops = {	.owner		= THIS_MODULE,	.open           = irias_seq_open,	.read           = seq_read,	.llseek         = seq_lseek,	.release	= seq_release,};#endif /* PROC_FS */

⌨️ 快捷键说明

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