iriap.c revision 0dc47877a3de00ceadea0005189656ae8dc52669
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> 341da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 351da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include <asm/byteorder.h> 361da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include <asm/unaligned.h> 371da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 381da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include <net/irda/irda.h> 391da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include <net/irda/irttp.h> 401da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include <net/irda/irlmp.h> 411da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include <net/irda/irias_object.h> 421da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include <net/irda/iriap_event.h> 431da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include <net/irda/iriap.h> 441da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 451da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#ifdef CONFIG_IRDA_DEBUG 461da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/* FIXME: This one should go in irlmp.c */ 471da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic const char *ias_charset_types[] = { 481da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds "CS_ASCII", 491da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds "CS_ISO_8859_1", 501da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds "CS_ISO_8859_2", 511da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds "CS_ISO_8859_3", 521da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds "CS_ISO_8859_4", 531da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds "CS_ISO_8859_5", 541da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds "CS_ISO_8859_6", 551da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds "CS_ISO_8859_7", 561da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds "CS_ISO_8859_8", 571da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds "CS_ISO_8859_9", 581da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds "CS_UNICODE" 591da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}; 601da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#endif /* CONFIG_IRDA_DEBUG */ 611da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 621da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic hashbin_t *iriap = NULL; 631da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic void *service_handle; 641da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 651da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic void __iriap_close(struct iriap_cb *self); 661da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic int iriap_register_lsap(struct iriap_cb *self, __u8 slsap_sel, int mode); 671da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic void iriap_disconnect_indication(void *instance, void *sap, 681da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds LM_REASON reason, struct sk_buff *skb); 691da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic void iriap_connect_indication(void *instance, void *sap, 701da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds struct qos_info *qos, __u32 max_sdu_size, 711da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds __u8 max_header_size, 721da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds struct sk_buff *skb); 731da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic void iriap_connect_confirm(void *instance, void *sap, 741da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds struct qos_info *qos, 751da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds __u32 max_sdu_size, __u8 max_header_size, 761da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds struct sk_buff *skb); 771da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic int iriap_data_indication(void *instance, void *sap, 781da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds struct sk_buff *skb); 791da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 801da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic void iriap_watchdog_timer_expired(void *data); 811da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 826819bc2e1e46c71711a8dddf4040e706b02973c0YOSHIFUJI Hideakistatic inline void iriap_start_watchdog_timer(struct iriap_cb *self, 836819bc2e1e46c71711a8dddf4040e706b02973c0YOSHIFUJI Hideaki int timeout) 841da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 856819bc2e1e46c71711a8dddf4040e706b02973c0YOSHIFUJI Hideaki irda_start_timer(&self->watchdog_timer, timeout, self, 861da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds iriap_watchdog_timer_expired); 871da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 881da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 891da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/* 901da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Function iriap_init (void) 911da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 921da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Initializes the IrIAP layer, called by the module initialization code 931da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * in irmod.c 941da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */ 951da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsint __init iriap_init(void) 961da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 971da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds struct ias_object *obj; 981da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds struct iriap_cb *server; 991da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds __u8 oct_seq[6]; 1001da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds __u16 hints; 1011da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 1021da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* Allocate master array */ 1031da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds iriap = hashbin_new(HB_LOCK); 1041da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (!iriap) 1051da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return -ENOMEM; 1061da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 1071da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* Object repository - defined in irias_object.c */ 1081da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds irias_objects = hashbin_new(HB_LOCK); 1091da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (!irias_objects) { 1101da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds IRDA_WARNING("%s: Can't allocate irias_objects hashbin!\n", 1110dc47877a3de00ceadea0005189656ae8dc52669Harvey Harrison __func__); 1121da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds hashbin_delete(iriap, NULL); 1131da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return -ENOMEM; 1141da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 1151da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 1161da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* 1171da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Register some default services for IrLMP 1181da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */ 1191da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds hints = irlmp_service_to_hint(S_COMPUTER); 1201da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds service_handle = irlmp_register_service(hints); 1211da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 1221da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* Register the Device object with LM-IAS */ 1231da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds obj = irias_new_object("Device", IAS_DEVICE_ID); 1241da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds irias_add_string_attrib(obj, "DeviceName", "Linux", IAS_KERNEL_ATTR); 1251da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 1261da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds oct_seq[0] = 0x01; /* Version 1 */ 1271da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds oct_seq[1] = 0x00; /* IAS support bits */ 1281da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds oct_seq[2] = 0x00; /* LM-MUX support bits */ 1291da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#ifdef CONFIG_IRDA_ULTRA 1301da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds oct_seq[2] |= 0x04; /* Connectionless Data support */ 1311da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#endif 1321da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds irias_add_octseq_attrib(obj, "IrLMPSupport", oct_seq, 3, 1331da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds IAS_KERNEL_ATTR); 1341da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds irias_insert_object(obj); 1351da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 1361da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* 1371da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Register server support with IrLMP so we can accept incoming 1381da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * connections 1391da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */ 1401da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds server = iriap_open(LSAP_IAS, IAS_SERVER, NULL, NULL); 1411da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (!server) { 1420dc47877a3de00ceadea0005189656ae8dc52669Harvey Harrison IRDA_DEBUG(0, "%s(), unable to open server\n", __func__); 1431da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return -1; 1441da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 1451da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds iriap_register_lsap(server, LSAP_IAS, IAS_SERVER); 1461da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 1471da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return 0; 1481da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 1491da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 1501da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/* 1511da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Function iriap_cleanup (void) 1521da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 1531da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Initializes the IrIAP layer, called by the module cleanup code in 1541da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * irmod.c 1551da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */ 15675a69ac6d66d2504ecbc4b46645fb0835a55a57cSamuel Ortizvoid iriap_cleanup(void) 1571da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 1581da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds irlmp_unregister_service(service_handle); 1591da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 1601da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds hashbin_delete(iriap, (FREE_FUNC) __iriap_close); 1611da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds hashbin_delete(irias_objects, (FREE_FUNC) __irias_delete_object); 1621da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 1631da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 1641da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/* 1651da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Function iriap_open (void) 1661da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 1671da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Opens an instance of the IrIAP layer, and registers with IrLMP 1681da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */ 1691da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstruct iriap_cb *iriap_open(__u8 slsap_sel, int mode, void *priv, 1701da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds CONFIRM_CALLBACK callback) 1711da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 1721da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds struct iriap_cb *self; 1731da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 1740dc47877a3de00ceadea0005189656ae8dc52669Harvey Harrison IRDA_DEBUG(2, "%s()\n", __func__); 1751da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 176b3ab09f9e1681916df349d54232fbb3f8a79bfa5Arnaldo Carvalho de Melo self = kzalloc(sizeof(*self), GFP_ATOMIC); 1771da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (!self) { 1780dc47877a3de00ceadea0005189656ae8dc52669Harvey Harrison IRDA_WARNING("%s: Unable to kmalloc!\n", __func__); 1791da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return NULL; 1801da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 1811da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 1821da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* 1831da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Initialize instance 1841da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */ 1851da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 1861da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds self->magic = IAS_MAGIC; 1871da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds self->mode = mode; 1881da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (mode == IAS_CLIENT) 1891da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds iriap_register_lsap(self, slsap_sel, mode); 1901da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 1911da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds self->confirm = callback; 1921da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds self->priv = priv; 1931da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 1941da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* iriap_getvaluebyclass_request() will construct packets before 1951da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * we connect, so this must have a sane value... Jean II */ 1961da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds self->max_header_size = LMP_MAX_HEADER; 1971da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 1981da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds init_timer(&self->watchdog_timer); 1991da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 2001da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds hashbin_insert(iriap, (irda_queue_t *) self, (long) self, NULL); 2011da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 2021da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* Initialize state machines */ 2031da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds iriap_next_client_state(self, S_DISCONNECT); 2041da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds iriap_next_call_state(self, S_MAKE_CALL); 2051da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds iriap_next_server_state(self, R_DISCONNECT); 2061da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds iriap_next_r_connect_state(self, R_WAITING); 2071da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 2081da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return self; 2091da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 2101da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus TorvaldsEXPORT_SYMBOL(iriap_open); 2111da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 2121da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/* 2131da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Function __iriap_close (self) 2141da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 2151da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Removes (deallocates) the IrIAP instance 2161da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 2171da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */ 2181da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic void __iriap_close(struct iriap_cb *self) 2191da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 2200dc47877a3de00ceadea0005189656ae8dc52669Harvey Harrison IRDA_DEBUG(4, "%s()\n", __func__); 2211da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 2221da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds IRDA_ASSERT(self != NULL, return;); 2231da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds IRDA_ASSERT(self->magic == IAS_MAGIC, return;); 2241da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 2251da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds del_timer(&self->watchdog_timer); 2261da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 2271da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (self->request_skb) 2281da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds dev_kfree_skb(self->request_skb); 2291da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 2301da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds self->magic = 0; 2311da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 2321da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds kfree(self); 2331da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 2341da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 2351da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/* 2361da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Function iriap_close (void) 2371da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 2381da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Closes IrIAP and deregisters with IrLMP 2391da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */ 2401da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsvoid iriap_close(struct iriap_cb *self) 2411da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 2421da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds struct iriap_cb *entry; 2431da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 2440dc47877a3de00ceadea0005189656ae8dc52669Harvey Harrison IRDA_DEBUG(2, "%s()\n", __func__); 2451da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 2461da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds IRDA_ASSERT(self != NULL, return;); 2471da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds IRDA_ASSERT(self->magic == IAS_MAGIC, return;); 2481da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 2491da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (self->lsap) { 2501da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds irlmp_close_lsap(self->lsap); 2511da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds self->lsap = NULL; 2521da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 2531da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 2541da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds entry = (struct iriap_cb *) hashbin_remove(iriap, (long) self, NULL); 2551da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds IRDA_ASSERT(entry == self, return;); 2561da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 2571da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds __iriap_close(self); 2581da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 2591da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus TorvaldsEXPORT_SYMBOL(iriap_close); 2601da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 2611da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic int iriap_register_lsap(struct iriap_cb *self, __u8 slsap_sel, int mode) 2621da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 2631da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds notify_t notify; 2641da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 2650dc47877a3de00ceadea0005189656ae8dc52669Harvey Harrison IRDA_DEBUG(2, "%s()\n", __func__); 2661da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 2671da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds irda_notify_init(¬ify); 2681da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds notify.connect_confirm = iriap_connect_confirm; 2691da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds notify.connect_indication = iriap_connect_indication; 2701da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds notify.disconnect_indication = iriap_disconnect_indication; 2711da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds notify.data_indication = iriap_data_indication; 2721da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds notify.instance = self; 2731da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (mode == IAS_CLIENT) 2741da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds strcpy(notify.name, "IrIAS cli"); 2751da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds else 2761da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds strcpy(notify.name, "IrIAS srv"); 2771da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 2781da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds self->lsap = irlmp_open_lsap(slsap_sel, ¬ify, 0); 2791da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (self->lsap == NULL) { 2800dc47877a3de00ceadea0005189656ae8dc52669Harvey Harrison IRDA_ERROR("%s: Unable to allocated LSAP!\n", __func__); 2811da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return -1; 2821da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 2831da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds self->slsap_sel = self->lsap->slsap_sel; 2841da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 2851da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return 0; 2861da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 2871da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 2881da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/* 2891da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Function iriap_disconnect_indication (handle, reason) 2901da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 2911da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Got disconnect, so clean up everything associated with this connection 2921da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 2931da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */ 2941da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic void iriap_disconnect_indication(void *instance, void *sap, 2951da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds LM_REASON reason, 2961da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds struct sk_buff *skb) 2971da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 2981da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds struct iriap_cb *self; 2991da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 3000dc47877a3de00ceadea0005189656ae8dc52669Harvey Harrison IRDA_DEBUG(4, "%s(), reason=%s\n", __func__, irlmp_reasons[reason]); 3011da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 3021da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds self = (struct iriap_cb *) instance; 3031da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 3041da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds IRDA_ASSERT(self != NULL, return;); 3051da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds IRDA_ASSERT(self->magic == IAS_MAGIC, return;); 3061da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 3071da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds IRDA_ASSERT(iriap != NULL, return;); 3081da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 3091da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds del_timer(&self->watchdog_timer); 3101da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 3111da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* Not needed */ 3121da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (skb) 3131da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds dev_kfree_skb(skb); 3141da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 3151da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (self->mode == IAS_CLIENT) { 3160dc47877a3de00ceadea0005189656ae8dc52669Harvey Harrison IRDA_DEBUG(4, "%s(), disconnect as client\n", __func__); 3171da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 3181da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 3191da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds iriap_do_client_event(self, IAP_LM_DISCONNECT_INDICATION, 3201da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds NULL); 3211da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* 3221da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Inform service user that the request failed by sending 3231da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * it a NULL value. Warning, the client might close us, so 3241da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * remember no to use self anymore after calling confirm 3251da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */ 3261da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (self->confirm) 3271da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds self->confirm(IAS_DISCONNECT, 0, NULL, self->priv); 3281da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } else { 3290dc47877a3de00ceadea0005189656ae8dc52669Harvey Harrison IRDA_DEBUG(4, "%s(), disconnect as server\n", __func__); 3301da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds iriap_do_server_event(self, IAP_LM_DISCONNECT_INDICATION, 3311da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds NULL); 3321da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds iriap_close(self); 3331da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 3341da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 3351da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 3361da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/* 3371da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Function iriap_disconnect_request (handle) 3381da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */ 3391da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic void iriap_disconnect_request(struct iriap_cb *self) 3401da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 3411da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds struct sk_buff *tx_skb; 3421da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 3430dc47877a3de00ceadea0005189656ae8dc52669Harvey Harrison IRDA_DEBUG(4, "%s()\n", __func__); 3441da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 3451da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds IRDA_ASSERT(self != NULL, return;); 3461da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds IRDA_ASSERT(self->magic == IAS_MAGIC, return;); 3471da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 3481b0fee7d68f234be6b270cda51d9fcb71bebd780Samuel Ortiz tx_skb = alloc_skb(LMP_MAX_HEADER, GFP_ATOMIC); 3491da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (tx_skb == NULL) { 3501b0fee7d68f234be6b270cda51d9fcb71bebd780Samuel Ortiz IRDA_DEBUG(0, 3511b0fee7d68f234be6b270cda51d9fcb71bebd780Samuel Ortiz "%s(), Could not allocate an sk_buff of length %d\n", 3520dc47877a3de00ceadea0005189656ae8dc52669Harvey Harrison __func__, LMP_MAX_HEADER); 3531da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return; 3541da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 3551da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 3561da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* 3571da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Reserve space for MUX control and LAP header 3581da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */ 3591da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds skb_reserve(tx_skb, LMP_MAX_HEADER); 3601da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 3611da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds irlmp_disconnect_request(self->lsap, tx_skb); 3621da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 3631da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 3641da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/* 3651da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Function iriap_getvaluebyclass (addr, name, attr) 3661da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 3674a4efbdee278b2f4ed91aad2db5c006ff754276eMatt Mackall * Retrieve all values from attribute in all objects with given class 3681da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * name 3691da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */ 3701da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsint iriap_getvaluebyclass_request(struct iriap_cb *self, 3711da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds __u32 saddr, __u32 daddr, 3721da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds char *name, char *attr) 3731da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 3741da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds struct sk_buff *tx_skb; 3751da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds int name_len, attr_len, skb_len; 3761da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds __u8 *frame; 3771da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 3781da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds IRDA_ASSERT(self != NULL, return -1;); 3791da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds IRDA_ASSERT(self->magic == IAS_MAGIC, return -1;); 3801da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 3811da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* Client must supply the destination device address */ 3821da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (!daddr) 3831da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return -1; 3841da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 3851da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds self->daddr = daddr; 3861da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds self->saddr = saddr; 3871da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 3881da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* 3891da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Save operation, so we know what the later indication is about 3901da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */ 3911da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds self->operation = GET_VALUE_BY_CLASS; 3921da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 3931da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* Give ourselves 10 secs to finish this operation */ 3941da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds iriap_start_watchdog_timer(self, 10*HZ); 3951da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 3961da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds name_len = strlen(name); /* Up to IAS_MAX_CLASSNAME = 60 */ 3971da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds attr_len = strlen(attr); /* Up to IAS_MAX_ATTRIBNAME = 60 */ 3981da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 3991da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds skb_len = self->max_header_size+2+name_len+1+attr_len+4; 400485fb2c998a37d5c3c6aa082aa451e66db90f34aSamuel Ortiz tx_skb = alloc_skb(skb_len, GFP_ATOMIC); 4011da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (!tx_skb) 4021da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return -ENOMEM; 4031da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 4041da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* Reserve space for MUX and LAP header */ 4051da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds skb_reserve(tx_skb, self->max_header_size); 4061da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds skb_put(tx_skb, 3+name_len+attr_len); 4071da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds frame = tx_skb->data; 4081da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 4091da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* Build frame */ 4101da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds frame[0] = IAP_LST | GET_VALUE_BY_CLASS; 4111da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds frame[1] = name_len; /* Insert length of name */ 4121da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds memcpy(frame+2, name, name_len); /* Insert name */ 4131da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds frame[2+name_len] = attr_len; /* Insert length of attr */ 4141da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds memcpy(frame+3+name_len, attr, attr_len); /* Insert attr */ 4151da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 4161da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds iriap_do_client_event(self, IAP_CALL_REQUEST_GVBC, tx_skb); 4171da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 4181da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* Drop reference count - see state_s_disconnect(). */ 4191da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds dev_kfree_skb(tx_skb); 4201da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 4211da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return 0; 4221da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 4231da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus TorvaldsEXPORT_SYMBOL(iriap_getvaluebyclass_request); 4241da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 4251da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/* 4261da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Function iriap_getvaluebyclass_confirm (self, skb) 4271da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 4281da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Got result from GetValueByClass command. Parse it and return result 4291da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * to service user. 4301da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 4311da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */ 4321da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic void iriap_getvaluebyclass_confirm(struct iriap_cb *self, 4331da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds struct sk_buff *skb) 4341da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 4351da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds struct ias_value *value; 4361da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds int charset; 4371da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds __u32 value_len; 4381da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds __u32 tmp_cpu32; 4391da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds __u16 obj_id; 4401da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds __u16 len; 4411da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds __u8 type; 4421da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds __u8 *fp; 4431da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds int n; 4441da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 4451da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds IRDA_ASSERT(self != NULL, return;); 4461da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds IRDA_ASSERT(self->magic == IAS_MAGIC, return;); 4471da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds IRDA_ASSERT(skb != NULL, return;); 4481da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 4491da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* Initialize variables */ 4501da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds fp = skb->data; 4511da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds n = 2; 4521da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 4531da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* Get length, MSB first */ 454448c31aa34b5ee947d322e8747c4cf801fc4c104Al Viro len = be16_to_cpu(get_unaligned((__be16 *)(fp+n))); n += 2; 4551da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 4560dc47877a3de00ceadea0005189656ae8dc52669Harvey Harrison IRDA_DEBUG(4, "%s(), len=%d\n", __func__, len); 4571da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 4581da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* Get object ID, MSB first */ 459448c31aa34b5ee947d322e8747c4cf801fc4c104Al Viro obj_id = be16_to_cpu(get_unaligned((__be16 *)(fp+n))); n += 2; 4601da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 4611da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds type = fp[n++]; 4620dc47877a3de00ceadea0005189656ae8dc52669Harvey Harrison IRDA_DEBUG(4, "%s(), Value type = %d\n", __func__, type); 4631da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 4641da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds switch (type) { 4651da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case IAS_INTEGER: 4661da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds memcpy(&tmp_cpu32, fp+n, 4); n += 4; 4671da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds be32_to_cpus(&tmp_cpu32); 4681da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds value = irias_new_integer_value(tmp_cpu32); 4691da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 4701da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* Legal values restricted to 0x01-0x6f, page 15 irttp */ 4710dc47877a3de00ceadea0005189656ae8dc52669Harvey Harrison IRDA_DEBUG(4, "%s(), lsap=%d\n", __func__, value->t.integer); 4721da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds break; 4731da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case IAS_STRING: 4741da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds charset = fp[n++]; 4751da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 4761da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds switch (charset) { 4771da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case CS_ASCII: 4781da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds break; 4791da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/* case CS_ISO_8859_1: */ 4801da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/* case CS_ISO_8859_2: */ 4811da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/* case CS_ISO_8859_3: */ 4821da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/* case CS_ISO_8859_4: */ 4831da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/* case CS_ISO_8859_5: */ 4841da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/* case CS_ISO_8859_6: */ 4851da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/* case CS_ISO_8859_7: */ 4861da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/* case CS_ISO_8859_8: */ 4871da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/* case CS_ISO_8859_9: */ 4881da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/* case CS_UNICODE: */ 4891da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds default: 4901da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds IRDA_DEBUG(0, "%s(), charset %s, not supported\n", 4910dc47877a3de00ceadea0005189656ae8dc52669Harvey Harrison __func__, ias_charset_types[charset]); 4921da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 4931da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* Aborting, close connection! */ 4941da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds iriap_disconnect_request(self); 4951da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return; 4961da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* break; */ 4971da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 4981da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds value_len = fp[n++]; 4990dc47877a3de00ceadea0005189656ae8dc52669Harvey Harrison IRDA_DEBUG(4, "%s(), strlen=%d\n", __func__, value_len); 5001da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 5011da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* Make sure the string is null-terminated */ 5021da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds fp[n+value_len] = 0x00; 5031da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds IRDA_DEBUG(4, "Got string %s\n", fp+n); 5041da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 5051da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* Will truncate to IAS_MAX_STRING bytes */ 5061da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds value = irias_new_string_value(fp+n); 5071da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds break; 5081da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case IAS_OCT_SEQ: 509448c31aa34b5ee947d322e8747c4cf801fc4c104Al Viro value_len = be16_to_cpu(get_unaligned((__be16 *)(fp+n))); 5101da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds n += 2; 5111da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 5121da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* Will truncate to IAS_MAX_OCTET_STRING bytes */ 5131da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds value = irias_new_octseq_value(fp+n, value_len); 5141da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds break; 5151da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds default: 5161da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds value = irias_new_missing_value(); 5171da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds break; 5181da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 5191da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 5201da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* Finished, close connection! */ 5211da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds iriap_disconnect_request(self); 5221da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 5231da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* Warning, the client might close us, so remember no to use self 5241da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * anymore after calling confirm 5251da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */ 5261da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (self->confirm) 5271da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds self->confirm(IAS_SUCCESS, obj_id, value, self->priv); 5281da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds else { 5290dc47877a3de00ceadea0005189656ae8dc52669Harvey Harrison IRDA_DEBUG(0, "%s(), missing handler!\n", __func__); 5301da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds irias_delete_value(value); 5311da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 5321da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 5331da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 5341da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/* 5351da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Function iriap_getvaluebyclass_response () 5361da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 5371da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Send answer back to remote LM-IAS 5381da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 5391da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */ 5401da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic void iriap_getvaluebyclass_response(struct iriap_cb *self, 5411da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds __u16 obj_id, 5421da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds __u8 ret_code, 5431da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds struct ias_value *value) 5441da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 5451da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds struct sk_buff *tx_skb; 5461da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds int n; 547448c31aa34b5ee947d322e8747c4cf801fc4c104Al Viro __be32 tmp_be32; 548405a42c5c8bd5731087c0ff01310731a3c1c9c24Alexey Dobriyan __be16 tmp_be16; 5491da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds __u8 *fp; 5501da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 5510dc47877a3de00ceadea0005189656ae8dc52669Harvey Harrison IRDA_DEBUG(4, "%s()\n", __func__); 5521da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 5531da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds IRDA_ASSERT(self != NULL, return;); 5541da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds IRDA_ASSERT(self->magic == IAS_MAGIC, return;); 5551da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds IRDA_ASSERT(value != NULL, return;); 5561da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds IRDA_ASSERT(value->len <= 1024, return;); 5571da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 5581da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* Initialize variables */ 5591da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds n = 0; 5601da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 5611da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* 5621da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * We must adjust the size of the response after the length of the 5631da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * value. We add 32 bytes because of the 6 bytes for the frame and 5641da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * max 5 bytes for the value coding. 5651da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */ 566485fb2c998a37d5c3c6aa082aa451e66db90f34aSamuel Ortiz tx_skb = alloc_skb(value->len + self->max_header_size + 32, 567485fb2c998a37d5c3c6aa082aa451e66db90f34aSamuel Ortiz GFP_ATOMIC); 5681da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (!tx_skb) 5691da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return; 5701da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 5711da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* Reserve space for MUX and LAP header */ 5721da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds skb_reserve(tx_skb, self->max_header_size); 5731da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds skb_put(tx_skb, 6); 5741da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 5751da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds fp = tx_skb->data; 5761da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 5771da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* Build frame */ 5781da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds fp[n++] = GET_VALUE_BY_CLASS | IAP_LST; 5791da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds fp[n++] = ret_code; 5801da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 5811da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* Insert list length (MSB first) */ 5826d82de9e576ea84b549b927e6a7775d918a427b5YOSHIFUJI Hideaki tmp_be16 = htons(0x0001); 5831da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds memcpy(fp+n, &tmp_be16, 2); n += 2; 5841da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 5851da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* Insert object identifier ( MSB first) */ 5861da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds tmp_be16 = cpu_to_be16(obj_id); 5871da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds memcpy(fp+n, &tmp_be16, 2); n += 2; 5881da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 5891da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds switch (value->type) { 5901da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case IAS_STRING: 5911da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds skb_put(tx_skb, 3 + value->len); 5921da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds fp[n++] = value->type; 5931da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds fp[n++] = 0; /* ASCII */ 5941da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds fp[n++] = (__u8) value->len; 5951da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds memcpy(fp+n, value->t.string, value->len); n+=value->len; 5961da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds break; 5971da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case IAS_INTEGER: 5981da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds skb_put(tx_skb, 5); 5991da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds fp[n++] = value->type; 6001da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 6011da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds tmp_be32 = cpu_to_be32(value->t.integer); 6021da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds memcpy(fp+n, &tmp_be32, 4); n += 4; 6031da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds break; 6041da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case IAS_OCT_SEQ: 6051da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds skb_put(tx_skb, 3 + value->len); 6061da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds fp[n++] = value->type; 6071da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 6081da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds tmp_be16 = cpu_to_be16(value->len); 6091da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds memcpy(fp+n, &tmp_be16, 2); n += 2; 6101da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds memcpy(fp+n, value->t.oct_seq, value->len); n+=value->len; 6111da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds break; 6121da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case IAS_MISSING: 6130dc47877a3de00ceadea0005189656ae8dc52669Harvey Harrison IRDA_DEBUG( 3, "%s: sending IAS_MISSING\n", __func__); 6141da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds skb_put(tx_skb, 1); 6151da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds fp[n++] = value->type; 6161da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds break; 6171da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds default: 6180dc47877a3de00ceadea0005189656ae8dc52669Harvey Harrison IRDA_DEBUG(0, "%s(), type not implemented!\n", __func__); 6191da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds break; 6201da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 6211da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds iriap_do_r_connect_event(self, IAP_CALL_RESPONSE, tx_skb); 6221da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 6231da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* Drop reference count - see state_r_execute(). */ 6241da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds dev_kfree_skb(tx_skb); 6251da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 6261da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 6271da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/* 6281da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Function iriap_getvaluebyclass_indication (self, skb) 6291da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 6301da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * getvaluebyclass is requested from peer LM-IAS 6311da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 6321da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */ 6331da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic void iriap_getvaluebyclass_indication(struct iriap_cb *self, 6341da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds struct sk_buff *skb) 6351da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 6361da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds struct ias_object *obj; 6371da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds struct ias_attrib *attrib; 6381da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds int name_len; 6391da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds int attr_len; 6401da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds char name[IAS_MAX_CLASSNAME + 1]; /* 60 bytes */ 6411da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds char attr[IAS_MAX_ATTRIBNAME + 1]; /* 60 bytes */ 6421da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds __u8 *fp; 6431da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds int n; 6441da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 6450dc47877a3de00ceadea0005189656ae8dc52669Harvey Harrison IRDA_DEBUG(4, "%s()\n", __func__); 6461da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 6471da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds IRDA_ASSERT(self != NULL, return;); 6481da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds IRDA_ASSERT(self->magic == IAS_MAGIC, return;); 6491da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds IRDA_ASSERT(skb != NULL, return;); 6501da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 6511da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds fp = skb->data; 6521da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds n = 1; 6531da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 6541da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds name_len = fp[n++]; 6551da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds memcpy(name, fp+n, name_len); n+=name_len; 6561da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds name[name_len] = '\0'; 6571da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 6581da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds attr_len = fp[n++]; 6591da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds memcpy(attr, fp+n, attr_len); n+=attr_len; 6601da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds attr[attr_len] = '\0'; 6611da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 6621da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds IRDA_DEBUG(4, "LM-IAS: Looking up %s: %s\n", name, attr); 6631da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds obj = irias_find_object(name); 6641da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 6651da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (obj == NULL) { 6661da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds IRDA_DEBUG(2, "LM-IAS: Object %s not found\n", name); 6671da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds iriap_getvaluebyclass_response(self, 0x1235, IAS_CLASS_UNKNOWN, 6681da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds &irias_missing); 6691da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return; 6701da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 6711da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds IRDA_DEBUG(4, "LM-IAS: found %s, id=%d\n", obj->name, obj->id); 6721da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 6731da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds attrib = irias_find_attrib(obj, attr); 6741da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (attrib == NULL) { 6751da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds IRDA_DEBUG(2, "LM-IAS: Attribute %s not found\n", attr); 6761da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds iriap_getvaluebyclass_response(self, obj->id, 6776819bc2e1e46c71711a8dddf4040e706b02973c0YOSHIFUJI Hideaki IAS_ATTRIB_UNKNOWN, 6781da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds &irias_missing); 6791da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return; 6801da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 6811da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 6821da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* We have a match; send the value. */ 6831da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds iriap_getvaluebyclass_response(self, obj->id, IAS_SUCCESS, 6841da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds attrib->value); 6851da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 6861da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return; 6871da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 6881da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 6891da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/* 6901da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Function iriap_send_ack (void) 6911da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 6921da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Currently not used 6931da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 6941da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */ 6951da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsvoid iriap_send_ack(struct iriap_cb *self) 6961da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 6971da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds struct sk_buff *tx_skb; 6981da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds __u8 *frame; 6991da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 7000dc47877a3de00ceadea0005189656ae8dc52669Harvey Harrison IRDA_DEBUG(2, "%s()\n", __func__); 7011da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 7021da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds IRDA_ASSERT(self != NULL, return;); 7031da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds IRDA_ASSERT(self->magic == IAS_MAGIC, return;); 7041da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 7051b0fee7d68f234be6b270cda51d9fcb71bebd780Samuel Ortiz tx_skb = alloc_skb(LMP_MAX_HEADER + 1, GFP_ATOMIC); 7061da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (!tx_skb) 7071da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return; 7081da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 7091da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* Reserve space for MUX and LAP header */ 7101da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds skb_reserve(tx_skb, self->max_header_size); 7111da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds skb_put(tx_skb, 1); 7121da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds frame = tx_skb->data; 7131da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 7141da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* Build frame */ 7151da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds frame[0] = IAP_LST | IAP_ACK | self->operation; 7161da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 7171da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds irlmp_data_request(self->lsap, tx_skb); 7181da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 7191da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 7201da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsvoid iriap_connect_request(struct iriap_cb *self) 7211da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 7221da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds int ret; 7231da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 7241da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds IRDA_ASSERT(self != NULL, return;); 7251da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds IRDA_ASSERT(self->magic == IAS_MAGIC, return;); 7261da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 7271da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds ret = irlmp_connect_request(self->lsap, LSAP_IAS, 7281da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds self->saddr, self->daddr, 7291da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds NULL, NULL); 7301da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (ret < 0) { 7310dc47877a3de00ceadea0005189656ae8dc52669Harvey Harrison IRDA_DEBUG(0, "%s(), connect failed!\n", __func__); 7321da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds self->confirm(IAS_DISCONNECT, 0, NULL, self->priv); 7331da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 7341da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 7351da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 7361da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/* 7371da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Function iriap_connect_confirm (handle, skb) 7381da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 7391da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * LSAP connection confirmed! 7401da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 7411da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */ 7421da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic void iriap_connect_confirm(void *instance, void *sap, 7431da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds struct qos_info *qos, __u32 max_seg_size, 7441da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds __u8 max_header_size, 7451da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds struct sk_buff *skb) 7461da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 7471da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds struct iriap_cb *self; 7481da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 7491da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds self = (struct iriap_cb *) instance; 7501da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 7511da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds IRDA_ASSERT(self != NULL, return;); 7521da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds IRDA_ASSERT(self->magic == IAS_MAGIC, return;); 7531da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds IRDA_ASSERT(skb != NULL, return;); 7541da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 7551da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds self->max_data_size = max_seg_size; 7561da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds self->max_header_size = max_header_size; 7571da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 7581da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds del_timer(&self->watchdog_timer); 7591da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 7601da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds iriap_do_client_event(self, IAP_LM_CONNECT_CONFIRM, skb); 7611da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 7621da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* Drop reference count - see state_s_make_call(). */ 7631da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds dev_kfree_skb(skb); 7641da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 7651da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 7661da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/* 7671da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Function iriap_connect_indication ( handle, skb) 7681da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 7691da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Remote LM-IAS is requesting connection 7701da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 7711da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */ 7721da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic void iriap_connect_indication(void *instance, void *sap, 7731da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds struct qos_info *qos, __u32 max_seg_size, 7741da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds __u8 max_header_size, 7751da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds struct sk_buff *skb) 7761da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 7771da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds struct iriap_cb *self, *new; 7781da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 7790dc47877a3de00ceadea0005189656ae8dc52669Harvey Harrison IRDA_DEBUG(1, "%s()\n", __func__); 7801da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 7811da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds self = (struct iriap_cb *) instance; 7821da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 7831da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds IRDA_ASSERT(skb != NULL, return;); 7841da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds IRDA_ASSERT(self != NULL, goto out;); 7851da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds IRDA_ASSERT(self->magic == IAS_MAGIC, goto out;); 7861da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 7871da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* Start new server */ 7881da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds new = iriap_open(LSAP_IAS, IAS_SERVER, NULL, NULL); 7891da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (!new) { 7900dc47877a3de00ceadea0005189656ae8dc52669Harvey Harrison IRDA_DEBUG(0, "%s(), open failed\n", __func__); 7911da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds goto out; 7921da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 7931da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 7941da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* Now attach up the new "socket" */ 7951da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds new->lsap = irlmp_dup(self->lsap, new); 7961da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (!new->lsap) { 7970dc47877a3de00ceadea0005189656ae8dc52669Harvey Harrison IRDA_DEBUG(0, "%s(), dup failed!\n", __func__); 7981da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds goto out; 7991da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 8001da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 8011da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds new->max_data_size = max_seg_size; 8021da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds new->max_header_size = max_header_size; 8031da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 8041da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* Clean up the original one to keep it in listen state */ 8051da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds irlmp_listen(self->lsap); 8061da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 8071da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds iriap_do_server_event(new, IAP_LM_CONNECT_INDICATION, skb); 8081da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 8091da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsout: 8101da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* Drop reference count - see state_r_disconnect(). */ 8111da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds dev_kfree_skb(skb); 8121da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 8131da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 8141da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/* 8151da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Function iriap_data_indication (handle, skb) 8161da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 8171da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Receives data from connection identified by handle from IrLMP 8181da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 8191da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */ 8201da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic int iriap_data_indication(void *instance, void *sap, 8211da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds struct sk_buff *skb) 8221da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 8231da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds struct iriap_cb *self; 8241da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds __u8 *frame; 8251da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds __u8 opcode; 8261da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 8270dc47877a3de00ceadea0005189656ae8dc52669Harvey Harrison IRDA_DEBUG(3, "%s()\n", __func__); 8281da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 8291da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds self = (struct iriap_cb *) instance; 8301da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 8311da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds IRDA_ASSERT(skb != NULL, return 0;); 8321da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds IRDA_ASSERT(self != NULL, goto out;); 8331da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds IRDA_ASSERT(self->magic == IAS_MAGIC, goto out;); 8341da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 8351da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds frame = skb->data; 8361da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 8371da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (self->mode == IAS_SERVER) { 8381da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* Call server */ 8390dc47877a3de00ceadea0005189656ae8dc52669Harvey Harrison IRDA_DEBUG(4, "%s(), Calling server!\n", __func__); 8401da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds iriap_do_r_connect_event(self, IAP_RECV_F_LST, skb); 8411da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds goto out; 8421da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 8431da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds opcode = frame[0]; 8441da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (~opcode & IAP_LST) { 8451da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds IRDA_WARNING("%s:, IrIAS multiframe commands or " 8461da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds "results is not implemented yet!\n", 8470dc47877a3de00ceadea0005189656ae8dc52669Harvey Harrison __func__); 8481da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds goto out; 8491da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 8501da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 8511da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* Check for ack frames since they don't contain any data */ 8521da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (opcode & IAP_ACK) { 8530dc47877a3de00ceadea0005189656ae8dc52669Harvey Harrison IRDA_DEBUG(0, "%s() Got ack frame!\n", __func__); 8541da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds goto out; 8551da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 8561da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 8571da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds opcode &= ~IAP_LST; /* Mask away LST bit */ 8581da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 8591da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds switch (opcode) { 8601da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case GET_INFO_BASE: 8611da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds IRDA_DEBUG(0, "IrLMP GetInfoBaseDetails not implemented!\n"); 8621da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds break; 8631da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case GET_VALUE_BY_CLASS: 8641da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds iriap_do_call_event(self, IAP_RECV_F_LST, NULL); 8651da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 8661da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds switch (frame[1]) { 8671da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case IAS_SUCCESS: 8681da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds iriap_getvaluebyclass_confirm(self, skb); 8691da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds break; 8701da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case IAS_CLASS_UNKNOWN: 8710dc47877a3de00ceadea0005189656ae8dc52669Harvey Harrison IRDA_DEBUG(1, "%s(), No such class!\n", __func__); 8721da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* Finished, close connection! */ 8731da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds iriap_disconnect_request(self); 8741da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 8751da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* 8761da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Warning, the client might close us, so remember 8771da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * no to use self anymore after calling confirm 8781da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */ 8791da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (self->confirm) 8801da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds self->confirm(IAS_CLASS_UNKNOWN, 0, NULL, 8811da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds self->priv); 8821da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds break; 8831da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case IAS_ATTRIB_UNKNOWN: 8840dc47877a3de00ceadea0005189656ae8dc52669Harvey Harrison IRDA_DEBUG(1, "%s(), No such attribute!\n", __func__); 8851da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* Finished, close connection! */ 8861da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds iriap_disconnect_request(self); 8871da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 8881da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* 8891da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Warning, the client might close us, so remember 8901da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * no to use self anymore after calling confirm 8911da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */ 8921da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (self->confirm) 8931da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds self->confirm(IAS_ATTRIB_UNKNOWN, 0, NULL, 8941da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds self->priv); 8951da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds break; 8961da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 8971da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds break; 8981da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds default: 8990dc47877a3de00ceadea0005189656ae8dc52669Harvey Harrison IRDA_DEBUG(0, "%s(), Unknown op-code: %02x\n", __func__, 9001da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds opcode); 9011da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds break; 9021da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 9031da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 9041da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsout: 9051da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* Cleanup - sub-calls will have done skb_get() as needed. */ 9061da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds dev_kfree_skb(skb); 9071da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return 0; 9081da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 9091da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 9101da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/* 9111da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Function iriap_call_indication (self, skb) 9121da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 9131da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Received call to server from peer LM-IAS 9141da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 9151da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */ 9161da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsvoid iriap_call_indication(struct iriap_cb *self, struct sk_buff *skb) 9171da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 9181da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds __u8 *fp; 9191da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds __u8 opcode; 9201da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 9210dc47877a3de00ceadea0005189656ae8dc52669Harvey Harrison IRDA_DEBUG(4, "%s()\n", __func__); 9221da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 9231da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds IRDA_ASSERT(self != NULL, return;); 9241da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds IRDA_ASSERT(self->magic == IAS_MAGIC, return;); 9251da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds IRDA_ASSERT(skb != NULL, return;); 9261da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 9271da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds fp = skb->data; 9281da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 9291da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds opcode = fp[0]; 9301da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (~opcode & 0x80) { 931a572da43738f156a6c81034467da429903483687Joe Perches IRDA_WARNING("%s: IrIAS multiframe commands or results " 9320dc47877a3de00ceadea0005189656ae8dc52669Harvey Harrison "is not implemented yet!\n", __func__); 9331da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return; 9341da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 9351da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds opcode &= 0x7f; /* Mask away LST bit */ 9361da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 9371da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds switch (opcode) { 9381da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case GET_INFO_BASE: 9391da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds IRDA_WARNING("%s: GetInfoBaseDetails not implemented yet!\n", 9400dc47877a3de00ceadea0005189656ae8dc52669Harvey Harrison __func__); 9411da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds break; 9421da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case GET_VALUE_BY_CLASS: 9431da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds iriap_getvaluebyclass_indication(self, skb); 9441da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds break; 9451da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 9461da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* skb will be cleaned up in iriap_data_indication */ 9471da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 9481da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 9491da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/* 9501da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Function iriap_watchdog_timer_expired (data) 9511da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 9521da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Query has taken too long time, so abort 9531da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 9541da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */ 9551da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic void iriap_watchdog_timer_expired(void *data) 9561da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 9571da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds struct iriap_cb *self = (struct iriap_cb *) data; 9581da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 9591da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds IRDA_ASSERT(self != NULL, return;); 9601da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds IRDA_ASSERT(self->magic == IAS_MAGIC, return;); 9611da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 9621da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* iriap_close(self); */ 9631da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 9641da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 9651da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#ifdef CONFIG_PROC_FS 9661da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 9671da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic const char *ias_value_types[] = { 9681da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds "IAS_MISSING", 9691da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds "IAS_INTEGER", 9701da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds "IAS_OCT_SEQ", 9711da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds "IAS_STRING" 9721da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}; 9731da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 9746819bc2e1e46c71711a8dddf4040e706b02973c0YOSHIFUJI Hideakistatic inline struct ias_object *irias_seq_idx(loff_t pos) 9751da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 9761da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds struct ias_object *obj; 9771da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 9781da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds for (obj = (struct ias_object *) hashbin_get_first(irias_objects); 9791da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds obj; obj = (struct ias_object *) hashbin_get_next(irias_objects)) { 9801da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (pos-- == 0) 9811da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds break; 9821da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 9836819bc2e1e46c71711a8dddf4040e706b02973c0YOSHIFUJI Hideaki 9841da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return obj; 9851da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 9861da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 9871da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic void *irias_seq_start(struct seq_file *seq, loff_t *pos) 9881da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 9891da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds spin_lock_irq(&irias_objects->hb_spinlock); 9901da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 9911da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return *pos ? irias_seq_idx(*pos - 1) : SEQ_START_TOKEN; 9921da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 9931da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 9941da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic void *irias_seq_next(struct seq_file *seq, void *v, loff_t *pos) 9951da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 9961da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds ++*pos; 9971da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 9986819bc2e1e46c71711a8dddf4040e706b02973c0YOSHIFUJI Hideaki return (v == SEQ_START_TOKEN) 9991da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds ? (void *) hashbin_get_first(irias_objects) 10001da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds : (void *) hashbin_get_next(irias_objects); 10011da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 10021da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 10031da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic void irias_seq_stop(struct seq_file *seq, void *v) 10041da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 10051da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds spin_unlock_irq(&irias_objects->hb_spinlock); 10061da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 10071da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 10081da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic int irias_seq_show(struct seq_file *seq, void *v) 10091da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 10101da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (v == SEQ_START_TOKEN) 10111da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds seq_puts(seq, "LM-IAS Objects:\n"); 10121da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds else { 10131da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds struct ias_object *obj = v; 10141da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds struct ias_attrib *attrib; 10151da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 10161da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds IRDA_ASSERT(obj->magic == IAS_OBJECT_MAGIC, return -EINVAL;); 10171da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 10181da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds seq_printf(seq, "name: %s, id=%d\n", 10191da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds obj->name, obj->id); 10201da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 10211da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* Careful for priority inversions here ! 10221da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * All other uses of attrib spinlock are independent of 10231da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * the object spinlock, so we are safe. Jean II */ 10241da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds spin_lock(&obj->attribs->hb_spinlock); 10251da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 10261da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* List all attributes for this object */ 10271da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds for (attrib = (struct ias_attrib *) hashbin_get_first(obj->attribs); 10281da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds attrib != NULL; 10291da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds attrib = (struct ias_attrib *) hashbin_get_next(obj->attribs)) { 10306819bc2e1e46c71711a8dddf4040e706b02973c0YOSHIFUJI Hideaki 10311da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds IRDA_ASSERT(attrib->magic == IAS_ATTRIB_MAGIC, 10321da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds goto outloop; ); 10331da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 10341da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds seq_printf(seq, " - Attribute name: \"%s\", ", 10351da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds attrib->name); 10361da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds seq_printf(seq, "value[%s]: ", 10371da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds ias_value_types[attrib->value->type]); 10381da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 10391da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds switch (attrib->value->type) { 10401da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case IAS_INTEGER: 10411da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds seq_printf(seq, "%d\n", 10421da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds attrib->value->t.integer); 10431da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds break; 10441da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case IAS_STRING: 10451da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds seq_printf(seq, "\"%s\"\n", 10461da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds attrib->value->t.string); 10471da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds break; 10481da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case IAS_OCT_SEQ: 10496819bc2e1e46c71711a8dddf4040e706b02973c0YOSHIFUJI Hideaki seq_printf(seq, "octet sequence (%d bytes)\n", 10501da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds attrib->value->len); 10511da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds break; 10521da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case IAS_MISSING: 10531da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds seq_puts(seq, "missing\n"); 10541da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds break; 10551da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds default: 10566819bc2e1e46c71711a8dddf4040e706b02973c0YOSHIFUJI Hideaki seq_printf(seq, "type %d?\n", 10571da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds attrib->value->type); 10581da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 10591da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds seq_putc(seq, '\n'); 10601da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 10611da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 10621da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds IRDA_ASSERT_LABEL(outloop:) 10631da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds spin_unlock(&obj->attribs->hb_spinlock); 10641da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 10651da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 10661da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return 0; 10671da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 10681da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 106956b3d975bbce65f655c5612b4822da671f9fd9b2Philippe De Muyterstatic const struct seq_operations irias_seq_ops = { 10701da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds .start = irias_seq_start, 10711da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds .next = irias_seq_next, 10721da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds .stop = irias_seq_stop, 10731da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds .show = irias_seq_show, 10741da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}; 10751da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 10761da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic int irias_seq_open(struct inode *inode, struct file *file) 10771da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 10781da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds IRDA_ASSERT( irias_objects != NULL, return -EINVAL;); 10791da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 10801da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return seq_open(file, &irias_seq_ops); 10811da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 10821da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 1083da7071d7e32d15149cc513f096a3638097b66387Arjan van de Venconst struct file_operations irias_seq_fops = { 10841da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds .owner = THIS_MODULE, 10851da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds .open = irias_seq_open, 10861da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds .read = seq_read, 10871da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds .llseek = seq_lseek, 10881da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds .release = seq_release, 10891da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}; 10901da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 10911da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#endif /* PROC_FS */ 1092