11da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/********************************************************************* 21da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 31da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Filename: iriap.c 41da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Version: 0.8 51da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Description: Information Access Protocol (IAP) 61da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Status: Experimental. 71da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Author: Dag Brattli <dagb@cs.uit.no> 81da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Created at: Thu Aug 21 00:02:07 1997 91da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Modified at: Sat Dec 25 16:42:42 1999 101da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Modified by: Dag Brattli <dagb@cs.uit.no> 111da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 121da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Copyright (c) 1998-1999 Dag Brattli <dagb@cs.uit.no>, 131da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * All Rights Reserved. 141da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Copyright (c) 2000-2003 Jean Tourrilhes <jt@hpl.hp.com> 151da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 161da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * This program is free software; you can redistribute it and/or 171da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * modify it under the terms of the GNU General Public License as 181da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * published by the Free Software Foundation; either version 2 of 191da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * the License, or (at your option) any later version. 201da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 2196de0e252cedffad61b3cb5e05662c591898e69aJan Engelhardt * Neither Dag Brattli nor University of Tromsø admit liability nor 221da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * provide warranty for any of this software. This material is 231da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * provided "AS-IS" and at no charge. 241da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 251da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds ********************************************************************/ 261da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 271da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include <linux/module.h> 281da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include <linux/types.h> 291da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include <linux/skbuff.h> 30d7fe0f241dceade9c8d4af75498765c5ff7f27e6Al Viro#include <linux/fs.h> 311da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include <linux/string.h> 321da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include <linux/init.h> 331da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include <linux/seq_file.h> 345a0e3ad6af8660be21ca98a971cd00f331318c05Tejun Heo#include <linux/slab.h> 351da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 361da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include <asm/byteorder.h> 371da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include <asm/unaligned.h> 381da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 391da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include <net/irda/irda.h> 401da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include <net/irda/irttp.h> 411da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include <net/irda/irlmp.h> 421da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include <net/irda/irias_object.h> 431da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include <net/irda/iriap_event.h> 441da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include <net/irda/iriap.h> 451da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 461da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#ifdef CONFIG_IRDA_DEBUG 471da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/* FIXME: This one should go in irlmp.c */ 4836cbd3dcc10384f813ec0814255f576c84f2bcd4Jan Engelhardtstatic const char *const ias_charset_types[] = { 491da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds "CS_ASCII", 501da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds "CS_ISO_8859_1", 511da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds "CS_ISO_8859_2", 521da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds "CS_ISO_8859_3", 531da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds "CS_ISO_8859_4", 541da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds "CS_ISO_8859_5", 551da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds "CS_ISO_8859_6", 561da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds "CS_ISO_8859_7", 571da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds "CS_ISO_8859_8", 581da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds "CS_ISO_8859_9", 591da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds "CS_UNICODE" 601da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}; 611da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#endif /* CONFIG_IRDA_DEBUG */ 621da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 631da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic hashbin_t *iriap = NULL; 641da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic void *service_handle; 651da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 661da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic void __iriap_close(struct iriap_cb *self); 671da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic int iriap_register_lsap(struct iriap_cb *self, __u8 slsap_sel, int mode); 681da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic void iriap_disconnect_indication(void *instance, void *sap, 691da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds LM_REASON reason, struct sk_buff *skb); 701da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic void iriap_connect_indication(void *instance, void *sap, 711da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds struct qos_info *qos, __u32 max_sdu_size, 721da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds __u8 max_header_size, 731da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds struct sk_buff *skb); 741da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic void iriap_connect_confirm(void *instance, void *sap, 751da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds struct qos_info *qos, 761da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds __u32 max_sdu_size, __u8 max_header_size, 771da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds struct sk_buff *skb); 781da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic int iriap_data_indication(void *instance, void *sap, 791da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds struct sk_buff *skb); 801da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 811da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic void iriap_watchdog_timer_expired(void *data); 821da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 836819bc2e1e46c71711a8dddf4040e706b02973c0YOSHIFUJI Hideakistatic inline void iriap_start_watchdog_timer(struct iriap_cb *self, 846819bc2e1e46c71711a8dddf4040e706b02973c0YOSHIFUJI Hideaki int timeout) 851da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 866819bc2e1e46c71711a8dddf4040e706b02973c0YOSHIFUJI Hideaki irda_start_timer(&self->watchdog_timer, timeout, self, 871da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds iriap_watchdog_timer_expired); 881da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 891da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 9079b3891587741dfac72cdfead1f2764b56a567b0David S. Millerstatic struct lock_class_key irias_objects_key; 9179b3891587741dfac72cdfead1f2764b56a567b0David S. Miller 921da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/* 931da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Function iriap_init (void) 941da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 951da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Initializes the IrIAP layer, called by the module initialization code 961da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * in irmod.c 971da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */ 981da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsint __init iriap_init(void) 991da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 1001da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds struct ias_object *obj; 1011da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds struct iriap_cb *server; 1021da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds __u8 oct_seq[6]; 1031da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds __u16 hints; 1041da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 1051da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* Allocate master array */ 1061da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds iriap = hashbin_new(HB_LOCK); 1071da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (!iriap) 1081da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return -ENOMEM; 1091da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 1101da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* Object repository - defined in irias_object.c */ 1111da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds irias_objects = hashbin_new(HB_LOCK); 1121da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (!irias_objects) { 1131da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds IRDA_WARNING("%s: Can't allocate irias_objects hashbin!\n", 1140dc47877a3de00ceadea0005189656ae8dc52669Harvey Harrison __func__); 1151da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds hashbin_delete(iriap, NULL); 1161da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return -ENOMEM; 1171da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 1181da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 11979b3891587741dfac72cdfead1f2764b56a567b0David S. Miller lockdep_set_class_and_name(&irias_objects->hb_spinlock, &irias_objects_key, 12079b3891587741dfac72cdfead1f2764b56a567b0David S. Miller "irias_objects"); 12179b3891587741dfac72cdfead1f2764b56a567b0David S. Miller 1221da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* 1231da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Register some default services for IrLMP 1241da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */ 1251da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds hints = irlmp_service_to_hint(S_COMPUTER); 1261da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds service_handle = irlmp_register_service(hints); 1271da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 1281da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* Register the Device object with LM-IAS */ 1291da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds obj = irias_new_object("Device", IAS_DEVICE_ID); 1301da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds irias_add_string_attrib(obj, "DeviceName", "Linux", IAS_KERNEL_ATTR); 1311da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 1321da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds oct_seq[0] = 0x01; /* Version 1 */ 1331da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds oct_seq[1] = 0x00; /* IAS support bits */ 1341da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds oct_seq[2] = 0x00; /* LM-MUX support bits */ 1351da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#ifdef CONFIG_IRDA_ULTRA 1361da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds oct_seq[2] |= 0x04; /* Connectionless Data support */ 1371da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#endif 1381da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds irias_add_octseq_attrib(obj, "IrLMPSupport", oct_seq, 3, 1391da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds IAS_KERNEL_ATTR); 1401da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds irias_insert_object(obj); 1411da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 1421da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* 1431da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Register server support with IrLMP so we can accept incoming 1441da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * connections 1451da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */ 1461da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds server = iriap_open(LSAP_IAS, IAS_SERVER, NULL, NULL); 1471da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (!server) { 1480dc47877a3de00ceadea0005189656ae8dc52669Harvey Harrison IRDA_DEBUG(0, "%s(), unable to open server\n", __func__); 1491da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return -1; 1501da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 1511da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds iriap_register_lsap(server, LSAP_IAS, IAS_SERVER); 1521da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 1531da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return 0; 1541da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 1551da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 1561da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/* 1571da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Function iriap_cleanup (void) 1581da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 1591da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Initializes the IrIAP layer, called by the module cleanup code in 1601da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * irmod.c 1611da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */ 16275a69ac6d66d2504ecbc4b46645fb0835a55a57cSamuel Ortizvoid iriap_cleanup(void) 1631da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 1641da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds irlmp_unregister_service(service_handle); 1651da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 1661da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds hashbin_delete(iriap, (FREE_FUNC) __iriap_close); 1671da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds hashbin_delete(irias_objects, (FREE_FUNC) __irias_delete_object); 1681da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 1691da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 1701da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/* 1711da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Function iriap_open (void) 1721da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 1731da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Opens an instance of the IrIAP layer, and registers with IrLMP 1741da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */ 1751da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstruct iriap_cb *iriap_open(__u8 slsap_sel, int mode, void *priv, 1761da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds CONFIRM_CALLBACK callback) 1771da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 1781da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds struct iriap_cb *self; 1791da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 1800dc47877a3de00ceadea0005189656ae8dc52669Harvey Harrison IRDA_DEBUG(2, "%s()\n", __func__); 1811da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 182b3ab09f9e1681916df349d54232fbb3f8a79bfa5Arnaldo Carvalho de Melo self = kzalloc(sizeof(*self), GFP_ATOMIC); 1831da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (!self) { 1840dc47877a3de00ceadea0005189656ae8dc52669Harvey Harrison IRDA_WARNING("%s: Unable to kmalloc!\n", __func__); 1851da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return NULL; 1861da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 1871da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 1881da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* 1891da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Initialize instance 1901da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */ 1911da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 1921da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds self->magic = IAS_MAGIC; 1931da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds self->mode = mode; 1941da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (mode == IAS_CLIENT) 1951da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds iriap_register_lsap(self, slsap_sel, mode); 1961da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 1971da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds self->confirm = callback; 1981da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds self->priv = priv; 1991da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 2001da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* iriap_getvaluebyclass_request() will construct packets before 2011da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * we connect, so this must have a sane value... Jean II */ 2021da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds self->max_header_size = LMP_MAX_HEADER; 2031da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 2041da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds init_timer(&self->watchdog_timer); 2051da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 2061da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds hashbin_insert(iriap, (irda_queue_t *) self, (long) self, NULL); 2071da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 2081da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* Initialize state machines */ 2091da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds iriap_next_client_state(self, S_DISCONNECT); 2101da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds iriap_next_call_state(self, S_MAKE_CALL); 2111da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds iriap_next_server_state(self, R_DISCONNECT); 2121da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds iriap_next_r_connect_state(self, R_WAITING); 2131da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 2141da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return self; 2151da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 2161da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus TorvaldsEXPORT_SYMBOL(iriap_open); 2171da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 2181da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/* 2191da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Function __iriap_close (self) 2201da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 2211da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Removes (deallocates) the IrIAP instance 2221da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 2231da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */ 2241da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic void __iriap_close(struct iriap_cb *self) 2251da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 2260dc47877a3de00ceadea0005189656ae8dc52669Harvey Harrison IRDA_DEBUG(4, "%s()\n", __func__); 2271da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 2281da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds IRDA_ASSERT(self != NULL, return;); 2291da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds IRDA_ASSERT(self->magic == IAS_MAGIC, return;); 2301da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 2311da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds del_timer(&self->watchdog_timer); 2321da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 2331da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (self->request_skb) 2341da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds dev_kfree_skb(self->request_skb); 2351da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 2361da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds self->magic = 0; 2371da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 2381da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds kfree(self); 2391da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 2401da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 2411da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/* 2421da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Function iriap_close (void) 2431da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 2441da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Closes IrIAP and deregisters with IrLMP 2451da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */ 2461da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsvoid iriap_close(struct iriap_cb *self) 2471da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 2481da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds struct iriap_cb *entry; 2491da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 2500dc47877a3de00ceadea0005189656ae8dc52669Harvey Harrison IRDA_DEBUG(2, "%s()\n", __func__); 2511da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 2521da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds IRDA_ASSERT(self != NULL, return;); 2531da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds IRDA_ASSERT(self->magic == IAS_MAGIC, return;); 2541da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 2551da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (self->lsap) { 2561da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds irlmp_close_lsap(self->lsap); 2571da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds self->lsap = NULL; 2581da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 2591da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 2601da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds entry = (struct iriap_cb *) hashbin_remove(iriap, (long) self, NULL); 2611da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds IRDA_ASSERT(entry == self, return;); 2621da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 2631da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds __iriap_close(self); 2641da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 2651da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus TorvaldsEXPORT_SYMBOL(iriap_close); 2661da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 2671da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic int iriap_register_lsap(struct iriap_cb *self, __u8 slsap_sel, int mode) 2681da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 2691da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds notify_t notify; 2701da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 2710dc47877a3de00ceadea0005189656ae8dc52669Harvey Harrison IRDA_DEBUG(2, "%s()\n", __func__); 2721da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 2731da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds irda_notify_init(¬ify); 2741da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds notify.connect_confirm = iriap_connect_confirm; 2751da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds notify.connect_indication = iriap_connect_indication; 2761da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds notify.disconnect_indication = iriap_disconnect_indication; 2771da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds notify.data_indication = iriap_data_indication; 2781da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds notify.instance = self; 2791da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (mode == IAS_CLIENT) 2801da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds strcpy(notify.name, "IrIAS cli"); 2811da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds else 2821da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds strcpy(notify.name, "IrIAS srv"); 2831da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 2841da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds self->lsap = irlmp_open_lsap(slsap_sel, ¬ify, 0); 2851da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (self->lsap == NULL) { 2860dc47877a3de00ceadea0005189656ae8dc52669Harvey Harrison IRDA_ERROR("%s: Unable to allocated LSAP!\n", __func__); 2871da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return -1; 2881da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 2891da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds self->slsap_sel = self->lsap->slsap_sel; 2901da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 2911da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return 0; 2921da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 2931da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 2941da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/* 2951da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Function iriap_disconnect_indication (handle, reason) 2961da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 2971da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Got disconnect, so clean up everything associated with this connection 2981da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 2991da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */ 3001da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic void iriap_disconnect_indication(void *instance, void *sap, 3011da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds LM_REASON reason, 3021da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds struct sk_buff *skb) 3031da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 3041da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds struct iriap_cb *self; 3051da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 306e15465e1808542743627f13d1c0cbb7eacc82b83Dan Carpenter IRDA_DEBUG(4, "%s(), reason=%s [%d]\n", __func__, 307e15465e1808542743627f13d1c0cbb7eacc82b83Dan Carpenter irlmp_reason_str(reason), reason); 3081da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 309ea110733874d5176cb56dcf612a629ffac09dbf0Joe Perches self = instance; 3101da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 3111da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds IRDA_ASSERT(self != NULL, return;); 3121da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds IRDA_ASSERT(self->magic == IAS_MAGIC, return;); 3131da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 3141da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds IRDA_ASSERT(iriap != NULL, return;); 3151da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 3161da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds del_timer(&self->watchdog_timer); 3171da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 3181da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* Not needed */ 3191da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (skb) 3201da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds dev_kfree_skb(skb); 3211da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 3221da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (self->mode == IAS_CLIENT) { 3230dc47877a3de00ceadea0005189656ae8dc52669Harvey Harrison IRDA_DEBUG(4, "%s(), disconnect as client\n", __func__); 3241da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 3251da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 3261da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds iriap_do_client_event(self, IAP_LM_DISCONNECT_INDICATION, 3271da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds NULL); 3281da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* 3291da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Inform service user that the request failed by sending 3301da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * it a NULL value. Warning, the client might close us, so 3311da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * remember no to use self anymore after calling confirm 3321da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */ 3331da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (self->confirm) 3341da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds self->confirm(IAS_DISCONNECT, 0, NULL, self->priv); 3351da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } else { 3360dc47877a3de00ceadea0005189656ae8dc52669Harvey Harrison IRDA_DEBUG(4, "%s(), disconnect as server\n", __func__); 3371da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds iriap_do_server_event(self, IAP_LM_DISCONNECT_INDICATION, 3381da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds NULL); 3391da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds iriap_close(self); 3401da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 3411da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 3421da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 3431da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/* 3441da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Function iriap_disconnect_request (handle) 3451da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */ 3461da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic void iriap_disconnect_request(struct iriap_cb *self) 3471da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 3481da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds struct sk_buff *tx_skb; 3491da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 3500dc47877a3de00ceadea0005189656ae8dc52669Harvey Harrison IRDA_DEBUG(4, "%s()\n", __func__); 3511da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 3521da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds IRDA_ASSERT(self != NULL, return;); 3531da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds IRDA_ASSERT(self->magic == IAS_MAGIC, return;); 3541da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 3551b0fee7d68f234be6b270cda51d9fcb71bebd780Samuel Ortiz tx_skb = alloc_skb(LMP_MAX_HEADER, GFP_ATOMIC); 3561da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (tx_skb == NULL) { 3571b0fee7d68f234be6b270cda51d9fcb71bebd780Samuel Ortiz IRDA_DEBUG(0, 3581b0fee7d68f234be6b270cda51d9fcb71bebd780Samuel Ortiz "%s(), Could not allocate an sk_buff of length %d\n", 3590dc47877a3de00ceadea0005189656ae8dc52669Harvey Harrison __func__, LMP_MAX_HEADER); 3601da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return; 3611da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 3621da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 3631da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* 3641da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Reserve space for MUX control and LAP header 3651da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */ 3661da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds skb_reserve(tx_skb, LMP_MAX_HEADER); 3671da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 3681da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds irlmp_disconnect_request(self->lsap, tx_skb); 3691da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 3701da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 3711da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/* 3721da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Function iriap_getvaluebyclass (addr, name, attr) 3731da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 3744a4efbdee278b2f4ed91aad2db5c006ff754276eMatt Mackall * Retrieve all values from attribute in all objects with given class 3751da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * name 3761da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */ 3771da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsint iriap_getvaluebyclass_request(struct iriap_cb *self, 3781da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds __u32 saddr, __u32 daddr, 3791da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds char *name, char *attr) 3801da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 3811da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds struct sk_buff *tx_skb; 3821da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds int name_len, attr_len, skb_len; 3831da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds __u8 *frame; 3841da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 3851da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds IRDA_ASSERT(self != NULL, return -1;); 3861da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds IRDA_ASSERT(self->magic == IAS_MAGIC, return -1;); 3871da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 3881da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* Client must supply the destination device address */ 3891da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (!daddr) 3901da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return -1; 3911da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 3921da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds self->daddr = daddr; 3931da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds self->saddr = saddr; 3941da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 3951da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* 3961da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Save operation, so we know what the later indication is about 3971da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */ 3981da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds self->operation = GET_VALUE_BY_CLASS; 3991da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 4001da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* Give ourselves 10 secs to finish this operation */ 4011da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds iriap_start_watchdog_timer(self, 10*HZ); 4021da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 4031da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds name_len = strlen(name); /* Up to IAS_MAX_CLASSNAME = 60 */ 4041da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds attr_len = strlen(attr); /* Up to IAS_MAX_ATTRIBNAME = 60 */ 4051da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 4061da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds skb_len = self->max_header_size+2+name_len+1+attr_len+4; 407485fb2c998a37d5c3c6aa082aa451e66db90f34aSamuel Ortiz tx_skb = alloc_skb(skb_len, GFP_ATOMIC); 4081da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (!tx_skb) 4091da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return -ENOMEM; 4101da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 4111da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* Reserve space for MUX and LAP header */ 4121da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds skb_reserve(tx_skb, self->max_header_size); 4131da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds skb_put(tx_skb, 3+name_len+attr_len); 4141da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds frame = tx_skb->data; 4151da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 4161da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* Build frame */ 4171da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds frame[0] = IAP_LST | GET_VALUE_BY_CLASS; 4181da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds frame[1] = name_len; /* Insert length of name */ 4191da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds memcpy(frame+2, name, name_len); /* Insert name */ 4201da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds frame[2+name_len] = attr_len; /* Insert length of attr */ 4211da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds memcpy(frame+3+name_len, attr, attr_len); /* Insert attr */ 4221da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 4231da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds iriap_do_client_event(self, IAP_CALL_REQUEST_GVBC, tx_skb); 4241da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 4251da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* Drop reference count - see state_s_disconnect(). */ 4261da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds dev_kfree_skb(tx_skb); 4271da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 4281da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return 0; 4291da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 4301da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus TorvaldsEXPORT_SYMBOL(iriap_getvaluebyclass_request); 4311da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 4321da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/* 4331da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Function iriap_getvaluebyclass_confirm (self, skb) 4341da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 4351da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Got result from GetValueByClass command. Parse it and return result 4361da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * to service user. 4371da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 4381da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */ 4391da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic void iriap_getvaluebyclass_confirm(struct iriap_cb *self, 4401da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds struct sk_buff *skb) 4411da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 4421da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds struct ias_value *value; 4431da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds int charset; 4441da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds __u32 value_len; 4451da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds __u32 tmp_cpu32; 4461da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds __u16 obj_id; 4471da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds __u16 len; 4481da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds __u8 type; 4491da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds __u8 *fp; 4501da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds int n; 4511da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 4521da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds IRDA_ASSERT(self != NULL, return;); 4531da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds IRDA_ASSERT(self->magic == IAS_MAGIC, return;); 4541da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds IRDA_ASSERT(skb != NULL, return;); 4551da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 4561da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* Initialize variables */ 4571da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds fp = skb->data; 4581da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds n = 2; 4591da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 4601da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* Get length, MSB first */ 461260ffeed3fd185d29f08e98fb47c09e71bb59cd8Harvey Harrison len = get_unaligned_be16(fp + n); 462260ffeed3fd185d29f08e98fb47c09e71bb59cd8Harvey Harrison n += 2; 4631da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 4640dc47877a3de00ceadea0005189656ae8dc52669Harvey Harrison IRDA_DEBUG(4, "%s(), len=%d\n", __func__, len); 4651da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 4661da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* Get object ID, MSB first */ 467260ffeed3fd185d29f08e98fb47c09e71bb59cd8Harvey Harrison obj_id = get_unaligned_be16(fp + n); 468260ffeed3fd185d29f08e98fb47c09e71bb59cd8Harvey Harrison n += 2; 4691da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 4701da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds type = fp[n++]; 4710dc47877a3de00ceadea0005189656ae8dc52669Harvey Harrison IRDA_DEBUG(4, "%s(), Value type = %d\n", __func__, type); 4721da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 4731da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds switch (type) { 4741da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case IAS_INTEGER: 4751da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds memcpy(&tmp_cpu32, fp+n, 4); n += 4; 4761da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds be32_to_cpus(&tmp_cpu32); 4771da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds value = irias_new_integer_value(tmp_cpu32); 4781da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 4791da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* Legal values restricted to 0x01-0x6f, page 15 irttp */ 4800dc47877a3de00ceadea0005189656ae8dc52669Harvey Harrison IRDA_DEBUG(4, "%s(), lsap=%d\n", __func__, value->t.integer); 4811da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds break; 4821da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case IAS_STRING: 4831da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds charset = fp[n++]; 4841da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 4851da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds switch (charset) { 4861da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case CS_ASCII: 4871da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds break; 4881da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/* case CS_ISO_8859_1: */ 4891da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/* case CS_ISO_8859_2: */ 4901da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/* case CS_ISO_8859_3: */ 4911da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/* case CS_ISO_8859_4: */ 4921da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/* case CS_ISO_8859_5: */ 4931da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/* case CS_ISO_8859_6: */ 4941da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/* case CS_ISO_8859_7: */ 4951da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/* case CS_ISO_8859_8: */ 4961da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/* case CS_ISO_8859_9: */ 4971da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/* case CS_UNICODE: */ 4981da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds default: 49990c7881ecee1f08e0a49172cf61371cf2509ee4aDan Carpenter IRDA_DEBUG(0, "%s(), charset [%d] %s, not supported\n", 50090c7881ecee1f08e0a49172cf61371cf2509ee4aDan Carpenter __func__, charset, 50190c7881ecee1f08e0a49172cf61371cf2509ee4aDan Carpenter charset < ARRAY_SIZE(ias_charset_types) ? 50290c7881ecee1f08e0a49172cf61371cf2509ee4aDan Carpenter ias_charset_types[charset] : 50390c7881ecee1f08e0a49172cf61371cf2509ee4aDan Carpenter "(unknown)"); 5041da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 5051da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* Aborting, close connection! */ 5061da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds iriap_disconnect_request(self); 5071da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return; 5081da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* break; */ 5091da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 5101da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds value_len = fp[n++]; 5110dc47877a3de00ceadea0005189656ae8dc52669Harvey Harrison IRDA_DEBUG(4, "%s(), strlen=%d\n", __func__, value_len); 5121da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 5131da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* Make sure the string is null-terminated */ 51437f9fc452d138dfc4da2ee1ce5ae85094efc3606Samuel Ortiz if (n + value_len < skb->len) 51537f9fc452d138dfc4da2ee1ce5ae85094efc3606Samuel Ortiz fp[n + value_len] = 0x00; 5161da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds IRDA_DEBUG(4, "Got string %s\n", fp+n); 5171da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 5181da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* Will truncate to IAS_MAX_STRING bytes */ 5191da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds value = irias_new_string_value(fp+n); 5201da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds break; 5211da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case IAS_OCT_SEQ: 522260ffeed3fd185d29f08e98fb47c09e71bb59cd8Harvey Harrison value_len = get_unaligned_be16(fp + n); 5231da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds n += 2; 5241da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 5251da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* Will truncate to IAS_MAX_OCTET_STRING bytes */ 5261da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds value = irias_new_octseq_value(fp+n, value_len); 5271da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds break; 5281da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds default: 5291da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds value = irias_new_missing_value(); 5301da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds break; 5311da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 5321da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 5331da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* Finished, close connection! */ 5341da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds iriap_disconnect_request(self); 5351da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 5361da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* Warning, the client might close us, so remember no to use self 5371da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * anymore after calling confirm 5381da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */ 5391da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (self->confirm) 5401da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds self->confirm(IAS_SUCCESS, obj_id, value, self->priv); 5411da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds else { 5420dc47877a3de00ceadea0005189656ae8dc52669Harvey Harrison IRDA_DEBUG(0, "%s(), missing handler!\n", __func__); 5431da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds irias_delete_value(value); 5441da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 5451da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 5461da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 5471da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/* 5481da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Function iriap_getvaluebyclass_response () 5491da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 5501da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Send answer back to remote LM-IAS 5511da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 5521da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */ 5531da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic void iriap_getvaluebyclass_response(struct iriap_cb *self, 5541da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds __u16 obj_id, 5551da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds __u8 ret_code, 5561da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds struct ias_value *value) 5571da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 5581da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds struct sk_buff *tx_skb; 5591da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds int n; 560448c31aa34b5ee947d322e8747c4cf801fc4c104Al Viro __be32 tmp_be32; 561405a42c5c8bd5731087c0ff01310731a3c1c9c24Alexey Dobriyan __be16 tmp_be16; 5621da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds __u8 *fp; 5631da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 5640dc47877a3de00ceadea0005189656ae8dc52669Harvey Harrison IRDA_DEBUG(4, "%s()\n", __func__); 5651da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 5661da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds IRDA_ASSERT(self != NULL, return;); 5671da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds IRDA_ASSERT(self->magic == IAS_MAGIC, return;); 5681da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds IRDA_ASSERT(value != NULL, return;); 5691da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds IRDA_ASSERT(value->len <= 1024, return;); 5701da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 5711da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* Initialize variables */ 5721da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds n = 0; 5731da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 5741da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* 5751da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * We must adjust the size of the response after the length of the 5761da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * value. We add 32 bytes because of the 6 bytes for the frame and 5771da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * max 5 bytes for the value coding. 5781da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */ 579485fb2c998a37d5c3c6aa082aa451e66db90f34aSamuel Ortiz tx_skb = alloc_skb(value->len + self->max_header_size + 32, 580485fb2c998a37d5c3c6aa082aa451e66db90f34aSamuel Ortiz GFP_ATOMIC); 5811da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (!tx_skb) 5821da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return; 5831da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 5841da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* Reserve space for MUX and LAP header */ 5851da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds skb_reserve(tx_skb, self->max_header_size); 5861da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds skb_put(tx_skb, 6); 5871da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 5881da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds fp = tx_skb->data; 5891da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 5901da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* Build frame */ 5911da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds fp[n++] = GET_VALUE_BY_CLASS | IAP_LST; 5921da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds fp[n++] = ret_code; 5931da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 5941da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* Insert list length (MSB first) */ 5956d82de9e576ea84b549b927e6a7775d918a427b5YOSHIFUJI Hideaki tmp_be16 = htons(0x0001); 5961da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds memcpy(fp+n, &tmp_be16, 2); n += 2; 5971da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 5981da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* Insert object identifier ( MSB first) */ 5991da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds tmp_be16 = cpu_to_be16(obj_id); 6001da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds memcpy(fp+n, &tmp_be16, 2); n += 2; 6011da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 6021da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds switch (value->type) { 6031da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case IAS_STRING: 6041da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds skb_put(tx_skb, 3 + value->len); 6051da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds fp[n++] = value->type; 6061da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds fp[n++] = 0; /* ASCII */ 6071da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds fp[n++] = (__u8) value->len; 6081da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds memcpy(fp+n, value->t.string, value->len); n+=value->len; 6091da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds break; 6101da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case IAS_INTEGER: 6111da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds skb_put(tx_skb, 5); 6121da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds fp[n++] = value->type; 6131da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 6141da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds tmp_be32 = cpu_to_be32(value->t.integer); 6151da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds memcpy(fp+n, &tmp_be32, 4); n += 4; 6161da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds break; 6171da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case IAS_OCT_SEQ: 6181da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds skb_put(tx_skb, 3 + value->len); 6191da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds fp[n++] = value->type; 6201da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 6211da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds tmp_be16 = cpu_to_be16(value->len); 6221da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds memcpy(fp+n, &tmp_be16, 2); n += 2; 6231da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds memcpy(fp+n, value->t.oct_seq, value->len); n+=value->len; 6241da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds break; 6251da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case IAS_MISSING: 6260dc47877a3de00ceadea0005189656ae8dc52669Harvey Harrison IRDA_DEBUG( 3, "%s: sending IAS_MISSING\n", __func__); 6271da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds skb_put(tx_skb, 1); 6281da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds fp[n++] = value->type; 6291da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds break; 6301da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds default: 6310dc47877a3de00ceadea0005189656ae8dc52669Harvey Harrison IRDA_DEBUG(0, "%s(), type not implemented!\n", __func__); 6321da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds break; 6331da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 6341da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds iriap_do_r_connect_event(self, IAP_CALL_RESPONSE, tx_skb); 6351da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 6361da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* Drop reference count - see state_r_execute(). */ 6371da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds dev_kfree_skb(tx_skb); 6381da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 6391da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 6401da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/* 6411da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Function iriap_getvaluebyclass_indication (self, skb) 6421da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 6431da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * getvaluebyclass is requested from peer LM-IAS 6441da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 6451da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */ 6461da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic void iriap_getvaluebyclass_indication(struct iriap_cb *self, 6471da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds struct sk_buff *skb) 6481da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 6491da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds struct ias_object *obj; 6501da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds struct ias_attrib *attrib; 6511da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds int name_len; 6521da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds int attr_len; 6531da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds char name[IAS_MAX_CLASSNAME + 1]; /* 60 bytes */ 6541da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds char attr[IAS_MAX_ATTRIBNAME + 1]; /* 60 bytes */ 6551da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds __u8 *fp; 6561da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds int n; 6571da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 6580dc47877a3de00ceadea0005189656ae8dc52669Harvey Harrison IRDA_DEBUG(4, "%s()\n", __func__); 6591da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 6601da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds IRDA_ASSERT(self != NULL, return;); 6611da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds IRDA_ASSERT(self->magic == IAS_MAGIC, return;); 6621da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds IRDA_ASSERT(skb != NULL, return;); 6631da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 6641da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds fp = skb->data; 6651da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds n = 1; 6661da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 6671da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds name_len = fp[n++]; 668d370af0ef7951188daeb15bae75db7ba57c67846Dan Rosenberg 669d370af0ef7951188daeb15bae75db7ba57c67846Dan Rosenberg IRDA_ASSERT(name_len < IAS_MAX_CLASSNAME + 1, return;); 670d370af0ef7951188daeb15bae75db7ba57c67846Dan Rosenberg 6711da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds memcpy(name, fp+n, name_len); n+=name_len; 6721da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds name[name_len] = '\0'; 6731da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 6741da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds attr_len = fp[n++]; 675d370af0ef7951188daeb15bae75db7ba57c67846Dan Rosenberg 676d370af0ef7951188daeb15bae75db7ba57c67846Dan Rosenberg IRDA_ASSERT(attr_len < IAS_MAX_ATTRIBNAME + 1, return;); 677d370af0ef7951188daeb15bae75db7ba57c67846Dan Rosenberg 6781da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds memcpy(attr, fp+n, attr_len); n+=attr_len; 6791da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds attr[attr_len] = '\0'; 6801da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 6811da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds IRDA_DEBUG(4, "LM-IAS: Looking up %s: %s\n", name, attr); 6821da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds obj = irias_find_object(name); 6831da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 6841da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (obj == NULL) { 6851da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds IRDA_DEBUG(2, "LM-IAS: Object %s not found\n", name); 6861da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds iriap_getvaluebyclass_response(self, 0x1235, IAS_CLASS_UNKNOWN, 6871da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds &irias_missing); 6881da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return; 6891da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 6901da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds IRDA_DEBUG(4, "LM-IAS: found %s, id=%d\n", obj->name, obj->id); 6911da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 6921da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds attrib = irias_find_attrib(obj, attr); 6931da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (attrib == NULL) { 6941da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds IRDA_DEBUG(2, "LM-IAS: Attribute %s not found\n", attr); 6951da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds iriap_getvaluebyclass_response(self, obj->id, 6966819bc2e1e46c71711a8dddf4040e706b02973c0YOSHIFUJI Hideaki IAS_ATTRIB_UNKNOWN, 6971da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds &irias_missing); 6981da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return; 6991da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 7001da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 7011da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* We have a match; send the value. */ 7021da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds iriap_getvaluebyclass_response(self, obj->id, IAS_SUCCESS, 7031da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds attrib->value); 7041da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 7051da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 7061da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/* 7071da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Function iriap_send_ack (void) 7081da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 7091da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Currently not used 7101da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 7111da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */ 7121da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsvoid iriap_send_ack(struct iriap_cb *self) 7131da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 7141da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds struct sk_buff *tx_skb; 7151da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds __u8 *frame; 7161da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 7170dc47877a3de00ceadea0005189656ae8dc52669Harvey Harrison IRDA_DEBUG(2, "%s()\n", __func__); 7181da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 7191da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds IRDA_ASSERT(self != NULL, return;); 7201da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds IRDA_ASSERT(self->magic == IAS_MAGIC, return;); 7211da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 7221b0fee7d68f234be6b270cda51d9fcb71bebd780Samuel Ortiz tx_skb = alloc_skb(LMP_MAX_HEADER + 1, GFP_ATOMIC); 7231da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (!tx_skb) 7241da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return; 7251da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 7261da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* Reserve space for MUX and LAP header */ 7271da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds skb_reserve(tx_skb, self->max_header_size); 7281da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds skb_put(tx_skb, 1); 7291da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds frame = tx_skb->data; 7301da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 7311da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* Build frame */ 7321da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds frame[0] = IAP_LST | IAP_ACK | self->operation; 7331da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 7341da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds irlmp_data_request(self->lsap, tx_skb); 7351da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 7361da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 7371da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsvoid iriap_connect_request(struct iriap_cb *self) 7381da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 7391da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds int ret; 7401da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 7411da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds IRDA_ASSERT(self != NULL, return;); 7421da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds IRDA_ASSERT(self->magic == IAS_MAGIC, return;); 7431da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 7441da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds ret = irlmp_connect_request(self->lsap, LSAP_IAS, 7451da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds self->saddr, self->daddr, 7461da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds NULL, NULL); 7471da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (ret < 0) { 7480dc47877a3de00ceadea0005189656ae8dc52669Harvey Harrison IRDA_DEBUG(0, "%s(), connect failed!\n", __func__); 7491da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds self->confirm(IAS_DISCONNECT, 0, NULL, self->priv); 7501da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 7511da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 7521da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 7531da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/* 7541da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Function iriap_connect_confirm (handle, skb) 7551da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 7561da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * LSAP connection confirmed! 7571da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 7581da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */ 7591da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic void iriap_connect_confirm(void *instance, void *sap, 7601da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds struct qos_info *qos, __u32 max_seg_size, 7611da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds __u8 max_header_size, 7621da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds struct sk_buff *skb) 7631da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 7641da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds struct iriap_cb *self; 7651da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 766ea110733874d5176cb56dcf612a629ffac09dbf0Joe Perches self = instance; 7671da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 7681da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds IRDA_ASSERT(self != NULL, return;); 7691da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds IRDA_ASSERT(self->magic == IAS_MAGIC, return;); 7701da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds IRDA_ASSERT(skb != NULL, return;); 7711da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 7721da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds self->max_data_size = max_seg_size; 7731da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds self->max_header_size = max_header_size; 7741da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 7751da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds del_timer(&self->watchdog_timer); 7761da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 7771da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds iriap_do_client_event(self, IAP_LM_CONNECT_CONFIRM, skb); 7781da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 7791da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* Drop reference count - see state_s_make_call(). */ 7801da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds dev_kfree_skb(skb); 7811da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 7821da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 7831da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/* 7841da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Function iriap_connect_indication ( handle, skb) 7851da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 7861da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Remote LM-IAS is requesting connection 7871da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 7881da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */ 7891da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic void iriap_connect_indication(void *instance, void *sap, 7901da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds struct qos_info *qos, __u32 max_seg_size, 7911da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds __u8 max_header_size, 7921da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds struct sk_buff *skb) 7931da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 7941da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds struct iriap_cb *self, *new; 7951da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 7960dc47877a3de00ceadea0005189656ae8dc52669Harvey Harrison IRDA_DEBUG(1, "%s()\n", __func__); 7971da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 798ea110733874d5176cb56dcf612a629ffac09dbf0Joe Perches self = instance; 7991da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 8001da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds IRDA_ASSERT(skb != NULL, return;); 8011da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds IRDA_ASSERT(self != NULL, goto out;); 8021da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds IRDA_ASSERT(self->magic == IAS_MAGIC, goto out;); 8031da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 8041da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* Start new server */ 8051da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds new = iriap_open(LSAP_IAS, IAS_SERVER, NULL, NULL); 8061da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (!new) { 8070dc47877a3de00ceadea0005189656ae8dc52669Harvey Harrison IRDA_DEBUG(0, "%s(), open failed\n", __func__); 8081da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds goto out; 8091da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 8101da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 8111da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* Now attach up the new "socket" */ 8121da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds new->lsap = irlmp_dup(self->lsap, new); 8131da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (!new->lsap) { 8140dc47877a3de00ceadea0005189656ae8dc52669Harvey Harrison IRDA_DEBUG(0, "%s(), dup failed!\n", __func__); 8151da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds goto out; 8161da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 8171da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 8181da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds new->max_data_size = max_seg_size; 8191da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds new->max_header_size = max_header_size; 8201da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 8211da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* Clean up the original one to keep it in listen state */ 8221da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds irlmp_listen(self->lsap); 8231da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 8241da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds iriap_do_server_event(new, IAP_LM_CONNECT_INDICATION, skb); 8251da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 8261da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsout: 8271da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* Drop reference count - see state_r_disconnect(). */ 8281da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds dev_kfree_skb(skb); 8291da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 8301da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 8311da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/* 8321da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Function iriap_data_indication (handle, skb) 8331da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 8341da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Receives data from connection identified by handle from IrLMP 8351da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 8361da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */ 8371da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic int iriap_data_indication(void *instance, void *sap, 8381da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds struct sk_buff *skb) 8391da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 8401da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds struct iriap_cb *self; 8411da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds __u8 *frame; 8421da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds __u8 opcode; 8431da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 8440dc47877a3de00ceadea0005189656ae8dc52669Harvey Harrison IRDA_DEBUG(3, "%s()\n", __func__); 8451da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 846ea110733874d5176cb56dcf612a629ffac09dbf0Joe Perches self = instance; 8471da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 8481da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds IRDA_ASSERT(skb != NULL, return 0;); 8491da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds IRDA_ASSERT(self != NULL, goto out;); 8501da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds IRDA_ASSERT(self->magic == IAS_MAGIC, goto out;); 8511da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 8521da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds frame = skb->data; 8531da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 8541da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (self->mode == IAS_SERVER) { 8551da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* Call server */ 8560dc47877a3de00ceadea0005189656ae8dc52669Harvey Harrison IRDA_DEBUG(4, "%s(), Calling server!\n", __func__); 8571da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds iriap_do_r_connect_event(self, IAP_RECV_F_LST, skb); 8581da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds goto out; 8591da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 8601da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds opcode = frame[0]; 8611da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (~opcode & IAP_LST) { 8621da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds IRDA_WARNING("%s:, IrIAS multiframe commands or " 8631da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds "results is not implemented yet!\n", 8640dc47877a3de00ceadea0005189656ae8dc52669Harvey Harrison __func__); 8651da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds goto out; 8661da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 8671da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 8681da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* Check for ack frames since they don't contain any data */ 8691da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (opcode & IAP_ACK) { 8700dc47877a3de00ceadea0005189656ae8dc52669Harvey Harrison IRDA_DEBUG(0, "%s() Got ack frame!\n", __func__); 8711da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds goto out; 8721da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 8731da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 8741da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds opcode &= ~IAP_LST; /* Mask away LST bit */ 8751da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 8761da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds switch (opcode) { 8771da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case GET_INFO_BASE: 8781da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds IRDA_DEBUG(0, "IrLMP GetInfoBaseDetails not implemented!\n"); 8791da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds break; 8801da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case GET_VALUE_BY_CLASS: 8811da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds iriap_do_call_event(self, IAP_RECV_F_LST, NULL); 8821da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 8831da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds switch (frame[1]) { 8841da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case IAS_SUCCESS: 8851da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds iriap_getvaluebyclass_confirm(self, skb); 8861da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds break; 8871da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case IAS_CLASS_UNKNOWN: 8880dc47877a3de00ceadea0005189656ae8dc52669Harvey Harrison IRDA_DEBUG(1, "%s(), No such class!\n", __func__); 8891da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* Finished, close connection! */ 8901da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds iriap_disconnect_request(self); 8911da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 8921da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* 8931da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Warning, the client might close us, so remember 8941da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * no to use self anymore after calling confirm 8951da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */ 8961da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (self->confirm) 8971da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds self->confirm(IAS_CLASS_UNKNOWN, 0, NULL, 8981da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds self->priv); 8991da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds break; 9001da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case IAS_ATTRIB_UNKNOWN: 9010dc47877a3de00ceadea0005189656ae8dc52669Harvey Harrison IRDA_DEBUG(1, "%s(), No such attribute!\n", __func__); 9021da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* Finished, close connection! */ 9031da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds iriap_disconnect_request(self); 9041da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 9051da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* 9061da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Warning, the client might close us, so remember 9071da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * no to use self anymore after calling confirm 9081da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */ 9091da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (self->confirm) 9101da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds self->confirm(IAS_ATTRIB_UNKNOWN, 0, NULL, 9111da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds self->priv); 9121da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds break; 9131da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 9141da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds break; 9151da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds default: 9160dc47877a3de00ceadea0005189656ae8dc52669Harvey Harrison IRDA_DEBUG(0, "%s(), Unknown op-code: %02x\n", __func__, 9171da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds opcode); 9181da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds break; 9191da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 9201da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 9211da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsout: 9221da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* Cleanup - sub-calls will have done skb_get() as needed. */ 9231da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds dev_kfree_skb(skb); 9241da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return 0; 9251da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 9261da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 9271da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/* 9281da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Function iriap_call_indication (self, skb) 9291da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 9301da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Received call to server from peer LM-IAS 9311da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 9321da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */ 9331da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsvoid iriap_call_indication(struct iriap_cb *self, struct sk_buff *skb) 9341da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 9351da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds __u8 *fp; 9361da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds __u8 opcode; 9371da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 9380dc47877a3de00ceadea0005189656ae8dc52669Harvey Harrison IRDA_DEBUG(4, "%s()\n", __func__); 9391da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 9401da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds IRDA_ASSERT(self != NULL, return;); 9411da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds IRDA_ASSERT(self->magic == IAS_MAGIC, return;); 9421da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds IRDA_ASSERT(skb != NULL, return;); 9431da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 9441da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds fp = skb->data; 9451da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 9461da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds opcode = fp[0]; 9471da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (~opcode & 0x80) { 948a572da43738f156a6c81034467da429903483687Joe Perches IRDA_WARNING("%s: IrIAS multiframe commands or results " 9490dc47877a3de00ceadea0005189656ae8dc52669Harvey Harrison "is not implemented yet!\n", __func__); 9501da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return; 9511da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 9521da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds opcode &= 0x7f; /* Mask away LST bit */ 9531da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 9541da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds switch (opcode) { 9551da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case GET_INFO_BASE: 9561da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds IRDA_WARNING("%s: GetInfoBaseDetails not implemented yet!\n", 9570dc47877a3de00ceadea0005189656ae8dc52669Harvey Harrison __func__); 9581da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds break; 9591da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case GET_VALUE_BY_CLASS: 9601da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds iriap_getvaluebyclass_indication(self, skb); 9611da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds break; 9621da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 9631da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* skb will be cleaned up in iriap_data_indication */ 9641da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 9651da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 9661da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/* 9671da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Function iriap_watchdog_timer_expired (data) 9681da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 9691da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Query has taken too long time, so abort 9701da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 9711da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */ 9721da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic void iriap_watchdog_timer_expired(void *data) 9731da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 9741da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds struct iriap_cb *self = (struct iriap_cb *) data; 9751da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 9761da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds IRDA_ASSERT(self != NULL, return;); 9771da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds IRDA_ASSERT(self->magic == IAS_MAGIC, return;); 9781da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 9791da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* iriap_close(self); */ 9801da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 9811da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 9821da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#ifdef CONFIG_PROC_FS 9831da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 98436cbd3dcc10384f813ec0814255f576c84f2bcd4Jan Engelhardtstatic const char *const ias_value_types[] = { 9851da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds "IAS_MISSING", 9861da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds "IAS_INTEGER", 9871da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds "IAS_OCT_SEQ", 9881da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds "IAS_STRING" 9891da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}; 9901da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 9916819bc2e1e46c71711a8dddf4040e706b02973c0YOSHIFUJI Hideakistatic inline struct ias_object *irias_seq_idx(loff_t pos) 9921da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 9931da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds struct ias_object *obj; 9941da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 9951da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds for (obj = (struct ias_object *) hashbin_get_first(irias_objects); 9961da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds obj; obj = (struct ias_object *) hashbin_get_next(irias_objects)) { 9971da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (pos-- == 0) 9981da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds break; 9991da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 10006819bc2e1e46c71711a8dddf4040e706b02973c0YOSHIFUJI Hideaki 10011da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return obj; 10021da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 10031da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 10041da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic void *irias_seq_start(struct seq_file *seq, loff_t *pos) 10051da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 10061da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds spin_lock_irq(&irias_objects->hb_spinlock); 10071da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 10081da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return *pos ? irias_seq_idx(*pos - 1) : SEQ_START_TOKEN; 10091da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 10101da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 10111da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic void *irias_seq_next(struct seq_file *seq, void *v, loff_t *pos) 10121da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 10131da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds ++*pos; 10141da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 10156819bc2e1e46c71711a8dddf4040e706b02973c0YOSHIFUJI Hideaki return (v == SEQ_START_TOKEN) 10161da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds ? (void *) hashbin_get_first(irias_objects) 10171da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds : (void *) hashbin_get_next(irias_objects); 10181da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 10191da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 10201da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic void irias_seq_stop(struct seq_file *seq, void *v) 10211da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 10221da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds spin_unlock_irq(&irias_objects->hb_spinlock); 10231da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 10241da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 10251da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic int irias_seq_show(struct seq_file *seq, void *v) 10261da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 10271da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (v == SEQ_START_TOKEN) 10281da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds seq_puts(seq, "LM-IAS Objects:\n"); 10291da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds else { 10301da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds struct ias_object *obj = v; 10311da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds struct ias_attrib *attrib; 10321da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 10331da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds IRDA_ASSERT(obj->magic == IAS_OBJECT_MAGIC, return -EINVAL;); 10341da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 10351da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds seq_printf(seq, "name: %s, id=%d\n", 10361da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds obj->name, obj->id); 10371da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 10381da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* Careful for priority inversions here ! 10391da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * All other uses of attrib spinlock are independent of 10401da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * the object spinlock, so we are safe. Jean II */ 10411da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds spin_lock(&obj->attribs->hb_spinlock); 10421da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 10431da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* List all attributes for this object */ 10441da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds for (attrib = (struct ias_attrib *) hashbin_get_first(obj->attribs); 10451da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds attrib != NULL; 10461da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds attrib = (struct ias_attrib *) hashbin_get_next(obj->attribs)) { 10476819bc2e1e46c71711a8dddf4040e706b02973c0YOSHIFUJI Hideaki 10481da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds IRDA_ASSERT(attrib->magic == IAS_ATTRIB_MAGIC, 10491da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds goto outloop; ); 10501da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 10511da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds seq_printf(seq, " - Attribute name: \"%s\", ", 10521da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds attrib->name); 10531da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds seq_printf(seq, "value[%s]: ", 10541da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds ias_value_types[attrib->value->type]); 10551da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 10561da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds switch (attrib->value->type) { 10571da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case IAS_INTEGER: 10581da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds seq_printf(seq, "%d\n", 10591da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds attrib->value->t.integer); 10601da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds break; 10611da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case IAS_STRING: 10621da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds seq_printf(seq, "\"%s\"\n", 10631da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds attrib->value->t.string); 10641da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds break; 10651da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case IAS_OCT_SEQ: 10666819bc2e1e46c71711a8dddf4040e706b02973c0YOSHIFUJI Hideaki seq_printf(seq, "octet sequence (%d bytes)\n", 10671da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds attrib->value->len); 10681da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds break; 10691da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case IAS_MISSING: 10701da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds seq_puts(seq, "missing\n"); 10711da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds break; 10721da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds default: 10736819bc2e1e46c71711a8dddf4040e706b02973c0YOSHIFUJI Hideaki seq_printf(seq, "type %d?\n", 10741da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds attrib->value->type); 10751da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 10761da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds seq_putc(seq, '\n'); 10771da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 10781da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 10791da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds IRDA_ASSERT_LABEL(outloop:) 10801da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds spin_unlock(&obj->attribs->hb_spinlock); 10811da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 10821da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 10831da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return 0; 10841da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 10851da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 108656b3d975bbce65f655c5612b4822da671f9fd9b2Philippe De Muyterstatic const struct seq_operations irias_seq_ops = { 10871da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds .start = irias_seq_start, 10881da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds .next = irias_seq_next, 10891da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds .stop = irias_seq_stop, 10901da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds .show = irias_seq_show, 10911da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}; 10921da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 10931da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic int irias_seq_open(struct inode *inode, struct file *file) 10941da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 10951da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds IRDA_ASSERT( irias_objects != NULL, return -EINVAL;); 10961da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 10971da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return seq_open(file, &irias_seq_ops); 10981da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 10991da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 1100da7071d7e32d15149cc513f096a3638097b66387Arjan van de Venconst struct file_operations irias_seq_fops = { 11011da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds .owner = THIS_MODULE, 11021da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds .open = irias_seq_open, 11031da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds .read = seq_read, 11041da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds .llseek = seq_lseek, 11051da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds .release = seq_release, 11061da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}; 11071da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 11081da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#endif /* PROC_FS */ 1109