1/********************************************************************* 2 * 3 * Filename: irlan_common.c 4 * Version: 0.9 5 * Description: IrDA LAN Access Protocol Implementation 6 * Status: Experimental. 7 * Author: Dag Brattli <dagb@cs.uit.no> 8 * Created at: Sun Aug 31 20:14:37 1997 9 * Modified at: Sun Dec 26 21:53:10 1999 10 * Modified by: Dag Brattli <dagb@cs.uit.no> 11 * 12 * Copyright (c) 1997, 1999 Dag Brattli <dagb@cs.uit.no>, 13 * All Rights Reserved. 14 * 15 * This program is free software; you can redistribute it and/or 16 * modify it under the terms of the GNU General Public License as 17 * published by the Free Software Foundation; either version 2 of 18 * the License, or (at your option) any later version. 19 * 20 * Neither Dag Brattli nor University of Troms� admit liability nor 21 * provide warranty for any of this software. This material is 22 * provided "AS-IS" and at no charge. 23 * 24 ********************************************************************/ 25 26#include <linux/module.h> 27 28#include <linux/kernel.h> 29#include <linux/string.h> 30#include <linux/init.h> 31#include <linux/errno.h> 32#include <linux/proc_fs.h> 33#include <linux/seq_file.h> 34#include <linux/random.h> 35#include <linux/netdevice.h> 36#include <linux/etherdevice.h> 37#include <linux/rtnetlink.h> 38#include <linux/moduleparam.h> 39#include <linux/bitops.h> 40 41#include <asm/system.h> 42#include <asm/byteorder.h> 43 44#include <net/irda/irda.h> 45#include <net/irda/irttp.h> 46#include <net/irda/irlmp.h> 47#include <net/irda/iriap.h> 48#include <net/irda/timer.h> 49 50#include <net/irda/irlan_common.h> 51#include <net/irda/irlan_client.h> 52#include <net/irda/irlan_provider.h> 53#include <net/irda/irlan_eth.h> 54#include <net/irda/irlan_filter.h> 55 56 57/* 58 * Send gratuitous ARP when connected to a new AP or not. May be a clever 59 * thing to do, but for some reason the machine crashes if you use DHCP. So 60 * lets not use it by default. 61 */ 62#undef CONFIG_IRLAN_SEND_GRATUITOUS_ARP 63 64/* extern char sysctl_devname[]; */ 65 66/* 67 * Master structure 68 */ 69static LIST_HEAD(irlans); 70 71static void *ckey; 72static void *skey; 73 74/* Module parameters */ 75static int eth; /* Use "eth" or "irlan" name for devices */ 76static int access = ACCESS_PEER; /* PEER, DIRECT or HOSTED */ 77 78#ifdef CONFIG_PROC_FS 79static const char *irlan_access[] = { 80 "UNKNOWN", 81 "DIRECT", 82 "PEER", 83 "HOSTED" 84}; 85 86static const char *irlan_media[] = { 87 "UNKNOWN", 88 "802.3", 89 "802.5" 90}; 91 92extern struct proc_dir_entry *proc_irda; 93 94static int irlan_seq_open(struct inode *inode, struct file *file); 95 96static const struct file_operations irlan_fops = { 97 .owner = THIS_MODULE, 98 .open = irlan_seq_open, 99 .read = seq_read, 100 .llseek = seq_lseek, 101 .release = seq_release, 102}; 103 104extern struct proc_dir_entry *proc_irda; 105#endif /* CONFIG_PROC_FS */ 106 107static struct irlan_cb *irlan_open(__u32 saddr, __u32 daddr); 108static void __irlan_close(struct irlan_cb *self); 109static int __irlan_insert_param(struct sk_buff *skb, char *param, int type, 110 __u8 value_byte, __u16 value_short, 111 __u8 *value_array, __u16 value_len); 112static void irlan_open_unicast_addr(struct irlan_cb *self); 113static void irlan_get_unicast_addr(struct irlan_cb *self); 114void irlan_close_tsaps(struct irlan_cb *self); 115 116/* 117 * Function irlan_init (void) 118 * 119 * Initialize IrLAN layer 120 * 121 */ 122static int __init irlan_init(void) 123{ 124 struct irlan_cb *new; 125 __u16 hints; 126 127 IRDA_DEBUG(2, "%s()\n", __FUNCTION__ ); 128 129#ifdef CONFIG_PROC_FS 130 { struct proc_dir_entry *proc; 131 proc = create_proc_entry("irlan", 0, proc_irda); 132 if (!proc) { 133 printk(KERN_ERR "irlan_init: can't create /proc entry!\n"); 134 return -ENODEV; 135 } 136 137 proc->proc_fops = &irlan_fops; 138 } 139#endif /* CONFIG_PROC_FS */ 140 141 IRDA_DEBUG(4, "%s()\n", __FUNCTION__ ); 142 hints = irlmp_service_to_hint(S_LAN); 143 144 /* Register with IrLMP as a client */ 145 ckey = irlmp_register_client(hints, &irlan_client_discovery_indication, 146 NULL, NULL); 147 if (!ckey) 148 goto err_ckey; 149 150 /* Register with IrLMP as a service */ 151 skey = irlmp_register_service(hints); 152 if (!skey) 153 goto err_skey; 154 155 /* Start the master IrLAN instance (the only one for now) */ 156 new = irlan_open(DEV_ADDR_ANY, DEV_ADDR_ANY); 157 if (!new) 158 goto err_open; 159 160 /* The master will only open its (listen) control TSAP */ 161 irlan_provider_open_ctrl_tsap(new); 162 163 /* Do some fast discovery! */ 164 irlmp_discovery_request(DISCOVERY_DEFAULT_SLOTS); 165 166 return 0; 167 168err_open: 169 irlmp_unregister_service(skey); 170err_skey: 171 irlmp_unregister_client(ckey); 172err_ckey: 173#ifdef CONFIG_PROC_FS 174 remove_proc_entry("irlan", proc_irda); 175#endif /* CONFIG_PROC_FS */ 176 177 return -ENOMEM; 178} 179 180static void __exit irlan_cleanup(void) 181{ 182 struct irlan_cb *self, *next; 183 184 IRDA_DEBUG(4, "%s()\n", __FUNCTION__ ); 185 186 irlmp_unregister_client(ckey); 187 irlmp_unregister_service(skey); 188 189#ifdef CONFIG_PROC_FS 190 remove_proc_entry("irlan", proc_irda); 191#endif /* CONFIG_PROC_FS */ 192 193 /* Cleanup any leftover network devices */ 194 rtnl_lock(); 195 list_for_each_entry_safe(self, next, &irlans, dev_list) { 196 __irlan_close(self); 197 } 198 rtnl_unlock(); 199} 200 201/* 202 * Function irlan_open (void) 203 * 204 * Open new instance of a client/provider, we should only register the 205 * network device if this instance is ment for a particular client/provider 206 */ 207static struct irlan_cb *irlan_open(__u32 saddr, __u32 daddr) 208{ 209 struct net_device *dev; 210 struct irlan_cb *self; 211 212 IRDA_DEBUG(2, "%s()\n", __FUNCTION__ ); 213 214 /* Create network device with irlan */ 215 dev = alloc_irlandev(eth ? "eth%d" : "irlan%d"); 216 if (!dev) 217 return NULL; 218 219 self = dev->priv; 220 self->dev = dev; 221 222 /* 223 * Initialize local device structure 224 */ 225 self->magic = IRLAN_MAGIC; 226 self->saddr = saddr; 227 self->daddr = daddr; 228 229 /* Provider access can only be PEER, DIRECT, or HOSTED */ 230 self->provider.access_type = access; 231 if (access == ACCESS_DIRECT) { 232 /* 233 * Since we are emulating an IrLAN sever we will have to 234 * give ourself an ethernet address! 235 */ 236 dev->dev_addr[0] = 0x40; 237 dev->dev_addr[1] = 0x00; 238 dev->dev_addr[2] = 0x00; 239 dev->dev_addr[3] = 0x00; 240 get_random_bytes(dev->dev_addr+4, 1); 241 get_random_bytes(dev->dev_addr+5, 1); 242 } 243 244 self->media = MEDIA_802_3; 245 self->disconnect_reason = LM_USER_REQUEST; 246 init_timer(&self->watchdog_timer); 247 init_timer(&self->client.kick_timer); 248 init_waitqueue_head(&self->open_wait); 249 250 skb_queue_head_init(&self->client.txq); 251 252 irlan_next_client_state(self, IRLAN_IDLE); 253 irlan_next_provider_state(self, IRLAN_IDLE); 254 255 if (register_netdev(dev)) { 256 IRDA_DEBUG(2, "%s(), register_netdev() failed!\n", 257 __FUNCTION__ ); 258 self = NULL; 259 free_netdev(dev); 260 } else { 261 rtnl_lock(); 262 list_add_rcu(&self->dev_list, &irlans); 263 rtnl_unlock(); 264 } 265 266 return self; 267} 268/* 269 * Function __irlan_close (self) 270 * 271 * This function closes and deallocates the IrLAN client instances. Be 272 * aware that other functions which calls client_close() must 273 * remove self from irlans list first. 274 */ 275static void __irlan_close(struct irlan_cb *self) 276{ 277 IRDA_DEBUG(2, "%s()\n", __FUNCTION__ ); 278 279 ASSERT_RTNL(); 280 IRDA_ASSERT(self != NULL, return;); 281 IRDA_ASSERT(self->magic == IRLAN_MAGIC, return;); 282 283 del_timer_sync(&self->watchdog_timer); 284 del_timer_sync(&self->client.kick_timer); 285 286 /* Close all open connections and remove TSAPs */ 287 irlan_close_tsaps(self); 288 289 if (self->client.iriap) 290 iriap_close(self->client.iriap); 291 292 /* Remove frames queued on the control channel */ 293 skb_queue_purge(&self->client.txq); 294 295 /* Unregister and free self via destructor */ 296 unregister_netdevice(self->dev); 297} 298 299/* Find any instance of irlan, used for client discovery wakeup */ 300struct irlan_cb *irlan_get_any(void) 301{ 302 struct irlan_cb *self; 303 304 list_for_each_entry_rcu(self, &irlans, dev_list) { 305 return self; 306 } 307 return NULL; 308} 309 310/* 311 * Function irlan_connect_indication (instance, sap, qos, max_sdu_size, skb) 312 * 313 * Here we receive the connect indication for the data channel 314 * 315 */ 316static void irlan_connect_indication(void *instance, void *sap, 317 struct qos_info *qos, 318 __u32 max_sdu_size, 319 __u8 max_header_size, 320 struct sk_buff *skb) 321{ 322 struct irlan_cb *self; 323 struct tsap_cb *tsap; 324 325 IRDA_DEBUG(2, "%s()\n", __FUNCTION__ ); 326 327 self = (struct irlan_cb *) instance; 328 tsap = (struct tsap_cb *) sap; 329 330 IRDA_ASSERT(self != NULL, return;); 331 IRDA_ASSERT(self->magic == IRLAN_MAGIC, return;); 332 IRDA_ASSERT(tsap == self->tsap_data,return;); 333 334 self->max_sdu_size = max_sdu_size; 335 self->max_header_size = max_header_size; 336 337 IRDA_DEBUG(0, "%s: We are now connected!\n", __FUNCTION__); 338 339 del_timer(&self->watchdog_timer); 340 341 /* If you want to pass the skb to *both* state machines, you will 342 * need to skb_clone() it, so that you don't free it twice. 343 * As the state machines don't need it, git rid of it here... 344 * Jean II */ 345 if (skb) 346 dev_kfree_skb(skb); 347 348 irlan_do_provider_event(self, IRLAN_DATA_CONNECT_INDICATION, NULL); 349 irlan_do_client_event(self, IRLAN_DATA_CONNECT_INDICATION, NULL); 350 351 if (self->provider.access_type == ACCESS_PEER) { 352 /* 353 * Data channel is open, so we are now allowed to 354 * configure the remote filter 355 */ 356 irlan_get_unicast_addr(self); 357 irlan_open_unicast_addr(self); 358 } 359 /* Ready to transfer Ethernet frames (at last) */ 360 netif_start_queue(self->dev); /* Clear reason */ 361} 362 363static void irlan_connect_confirm(void *instance, void *sap, 364 struct qos_info *qos, 365 __u32 max_sdu_size, 366 __u8 max_header_size, 367 struct sk_buff *skb) 368{ 369 struct irlan_cb *self; 370 371 self = (struct irlan_cb *) instance; 372 373 IRDA_ASSERT(self != NULL, return;); 374 IRDA_ASSERT(self->magic == IRLAN_MAGIC, return;); 375 376 self->max_sdu_size = max_sdu_size; 377 self->max_header_size = max_header_size; 378 379 /* TODO: we could set the MTU depending on the max_sdu_size */ 380 381 IRDA_DEBUG(0, "%s: We are now connected!\n", __FUNCTION__); 382 del_timer(&self->watchdog_timer); 383 384 /* 385 * Data channel is open, so we are now allowed to configure the remote 386 * filter 387 */ 388 irlan_get_unicast_addr(self); 389 irlan_open_unicast_addr(self); 390 391 /* Open broadcast and multicast filter by default */ 392 irlan_set_broadcast_filter(self, TRUE); 393 irlan_set_multicast_filter(self, TRUE); 394 395 /* Ready to transfer Ethernet frames */ 396 netif_start_queue(self->dev); 397 self->disconnect_reason = 0; /* Clear reason */ 398#ifdef CONFIG_IRLAN_SEND_GRATUITOUS_ARP 399 irlan_eth_send_gratuitous_arp(&self->dev); 400#endif 401 wake_up_interruptible(&self->open_wait); 402} 403 404/* 405 * Function irlan_client_disconnect_indication (handle) 406 * 407 * Callback function for the IrTTP layer. Indicates a disconnection of 408 * the specified connection (handle) 409 */ 410static void irlan_disconnect_indication(void *instance, 411 void *sap, LM_REASON reason, 412 struct sk_buff *userdata) 413{ 414 struct irlan_cb *self; 415 struct tsap_cb *tsap; 416 417 IRDA_DEBUG(0, "%s(), reason=%d\n", __FUNCTION__ , reason); 418 419 self = (struct irlan_cb *) instance; 420 tsap = (struct tsap_cb *) sap; 421 422 IRDA_ASSERT(self != NULL, return;); 423 IRDA_ASSERT(self->magic == IRLAN_MAGIC, return;); 424 IRDA_ASSERT(tsap != NULL, return;); 425 IRDA_ASSERT(tsap->magic == TTP_TSAP_MAGIC, return;); 426 427 IRDA_ASSERT(tsap == self->tsap_data, return;); 428 429 IRDA_DEBUG(2, "IrLAN, data channel disconnected by peer!\n"); 430 431 /* Save reason so we know if we should try to reconnect or not */ 432 self->disconnect_reason = reason; 433 434 switch (reason) { 435 case LM_USER_REQUEST: /* User request */ 436 IRDA_DEBUG(2, "%s(), User requested\n", __FUNCTION__ ); 437 break; 438 case LM_LAP_DISCONNECT: /* Unexpected IrLAP disconnect */ 439 IRDA_DEBUG(2, "%s(), Unexpected IrLAP disconnect\n", __FUNCTION__ ); 440 break; 441 case LM_CONNECT_FAILURE: /* Failed to establish IrLAP connection */ 442 IRDA_DEBUG(2, "%s(), IrLAP connect failed\n", __FUNCTION__ ); 443 break; 444 case LM_LAP_RESET: /* IrLAP reset */ 445 IRDA_DEBUG(2, "%s(), IrLAP reset\n", __FUNCTION__ ); 446 break; 447 case LM_INIT_DISCONNECT: 448 IRDA_DEBUG(2, "%s(), IrLMP connect failed\n", __FUNCTION__ ); 449 break; 450 default: 451 IRDA_ERROR("%s(), Unknown disconnect reason\n", __FUNCTION__); 452 break; 453 } 454 455 /* If you want to pass the skb to *both* state machines, you will 456 * need to skb_clone() it, so that you don't free it twice. 457 * As the state machines don't need it, git rid of it here... 458 * Jean II */ 459 if (userdata) 460 dev_kfree_skb(userdata); 461 462 irlan_do_client_event(self, IRLAN_LMP_DISCONNECT, NULL); 463 irlan_do_provider_event(self, IRLAN_LMP_DISCONNECT, NULL); 464 465 wake_up_interruptible(&self->open_wait); 466} 467 468void irlan_open_data_tsap(struct irlan_cb *self) 469{ 470 struct tsap_cb *tsap; 471 notify_t notify; 472 473 IRDA_DEBUG(2, "%s()\n", __FUNCTION__ ); 474 475 IRDA_ASSERT(self != NULL, return;); 476 IRDA_ASSERT(self->magic == IRLAN_MAGIC, return;); 477 478 /* Check if already open */ 479 if (self->tsap_data) 480 return; 481 482 irda_notify_init(¬ify); 483 484 notify.data_indication = irlan_eth_receive; 485 notify.udata_indication = irlan_eth_receive; 486 notify.connect_indication = irlan_connect_indication; 487 notify.connect_confirm = irlan_connect_confirm; 488 notify.flow_indication = irlan_eth_flow_indication; 489 notify.disconnect_indication = irlan_disconnect_indication; 490 notify.instance = self; 491 strlcpy(notify.name, "IrLAN data", sizeof(notify.name)); 492 493 tsap = irttp_open_tsap(LSAP_ANY, DEFAULT_INITIAL_CREDIT, ¬ify); 494 if (!tsap) { 495 IRDA_DEBUG(2, "%s(), Got no tsap!\n", __FUNCTION__ ); 496 return; 497 } 498 self->tsap_data = tsap; 499 500 /* 501 * This is the data TSAP selector which we will pass to the client 502 * when the client ask for it. 503 */ 504 self->stsap_sel_data = self->tsap_data->stsap_sel; 505} 506 507void irlan_close_tsaps(struct irlan_cb *self) 508{ 509 IRDA_DEBUG(4, "%s()\n", __FUNCTION__ ); 510 511 IRDA_ASSERT(self != NULL, return;); 512 IRDA_ASSERT(self->magic == IRLAN_MAGIC, return;); 513 514 /* Disconnect and close all open TSAP connections */ 515 if (self->tsap_data) { 516 irttp_disconnect_request(self->tsap_data, NULL, P_NORMAL); 517 irttp_close_tsap(self->tsap_data); 518 self->tsap_data = NULL; 519 } 520 if (self->client.tsap_ctrl) { 521 irttp_disconnect_request(self->client.tsap_ctrl, NULL, 522 P_NORMAL); 523 irttp_close_tsap(self->client.tsap_ctrl); 524 self->client.tsap_ctrl = NULL; 525 } 526 if (self->provider.tsap_ctrl) { 527 irttp_disconnect_request(self->provider.tsap_ctrl, NULL, 528 P_NORMAL); 529 irttp_close_tsap(self->provider.tsap_ctrl); 530 self->provider.tsap_ctrl = NULL; 531 } 532 self->disconnect_reason = LM_USER_REQUEST; 533} 534 535/* 536 * Function irlan_ias_register (self, tsap_sel) 537 * 538 * Register with LM-IAS 539 * 540 */ 541void irlan_ias_register(struct irlan_cb *self, __u8 tsap_sel) 542{ 543 struct ias_object *obj; 544 struct ias_value *new_value; 545 546 IRDA_ASSERT(self != NULL, return;); 547 IRDA_ASSERT(self->magic == IRLAN_MAGIC, return;); 548 549 /* 550 * Check if object has already been registered by a previous provider. 551 * If that is the case, we just change the value of the attribute 552 */ 553 if (!irias_find_object("IrLAN")) { 554 obj = irias_new_object("IrLAN", IAS_IRLAN_ID); 555 irias_add_integer_attrib(obj, "IrDA:TinyTP:LsapSel", tsap_sel, 556 IAS_KERNEL_ATTR); 557 irias_insert_object(obj); 558 } else { 559 new_value = irias_new_integer_value(tsap_sel); 560 irias_object_change_attribute("IrLAN", "IrDA:TinyTP:LsapSel", 561 new_value); 562 } 563 564 /* Register PnP object only if not registered before */ 565 if (!irias_find_object("PnP")) { 566 obj = irias_new_object("PnP", IAS_PNP_ID); 567 irias_add_string_attrib(obj, "Name", "Linux", IAS_KERNEL_ATTR); 568 irias_add_string_attrib(obj, "DeviceID", "HWP19F0", 569 IAS_KERNEL_ATTR); 570 irias_add_integer_attrib(obj, "CompCnt", 1, IAS_KERNEL_ATTR); 571 if (self->provider.access_type == ACCESS_PEER) 572 irias_add_string_attrib(obj, "Comp#01", "PNP8389", 573 IAS_KERNEL_ATTR); 574 else 575 irias_add_string_attrib(obj, "Comp#01", "PNP8294", 576 IAS_KERNEL_ATTR); 577 578 irias_add_string_attrib(obj, "Manufacturer", 579 "Linux-IrDA Project", IAS_KERNEL_ATTR); 580 irias_insert_object(obj); 581 } 582} 583 584/* 585 * Function irlan_run_ctrl_tx_queue (self) 586 * 587 * Try to send the next command in the control transmit queue 588 * 589 */ 590int irlan_run_ctrl_tx_queue(struct irlan_cb *self) 591{ 592 struct sk_buff *skb; 593 594 IRDA_DEBUG(2, "%s()\n", __FUNCTION__ ); 595 596 if (irda_lock(&self->client.tx_busy) == FALSE) 597 return -EBUSY; 598 599 skb = skb_dequeue(&self->client.txq); 600 if (!skb) { 601 self->client.tx_busy = FALSE; 602 return 0; 603 } 604 605 /* Check that it's really possible to send commands */ 606 if ((self->client.tsap_ctrl == NULL) || 607 (self->client.state == IRLAN_IDLE)) 608 { 609 self->client.tx_busy = FALSE; 610 dev_kfree_skb(skb); 611 return -1; 612 } 613 IRDA_DEBUG(2, "%s(), sending ...\n", __FUNCTION__ ); 614 615 return irttp_data_request(self->client.tsap_ctrl, skb); 616} 617 618/* 619 * Function irlan_ctrl_data_request (self, skb) 620 * 621 * This function makes sure that commands on the control channel is being 622 * sent in a command/response fashion 623 */ 624static void irlan_ctrl_data_request(struct irlan_cb *self, struct sk_buff *skb) 625{ 626 IRDA_DEBUG(2, "%s()\n", __FUNCTION__ ); 627 628 /* Queue command */ 629 skb_queue_tail(&self->client.txq, skb); 630 631 /* Try to send command */ 632 irlan_run_ctrl_tx_queue(self); 633} 634 635/* 636 * Function irlan_get_provider_info (self) 637 * 638 * Send Get Provider Information command to peer IrLAN layer 639 * 640 */ 641void irlan_get_provider_info(struct irlan_cb *self) 642{ 643 struct sk_buff *skb; 644 __u8 *frame; 645 646 IRDA_DEBUG(4, "%s()\n", __FUNCTION__ ); 647 648 IRDA_ASSERT(self != NULL, return;); 649 IRDA_ASSERT(self->magic == IRLAN_MAGIC, return;); 650 651 skb = alloc_skb(IRLAN_MAX_HEADER + IRLAN_CMD_HEADER, 652 GFP_ATOMIC); 653 if (!skb) 654 return; 655 656 /* Reserve space for TTP, LMP, and LAP header */ 657 skb_reserve(skb, self->client.max_header_size); 658 skb_put(skb, 2); 659 660 frame = skb->data; 661 662 frame[0] = CMD_GET_PROVIDER_INFO; 663 frame[1] = 0x00; /* Zero parameters */ 664 665 irlan_ctrl_data_request(self, skb); 666} 667 668/* 669 * Function irlan_open_data_channel (self) 670 * 671 * Send an Open Data Command to provider 672 * 673 */ 674void irlan_open_data_channel(struct irlan_cb *self) 675{ 676 struct sk_buff *skb; 677 __u8 *frame; 678 679 IRDA_DEBUG(4, "%s()\n", __FUNCTION__ ); 680 681 IRDA_ASSERT(self != NULL, return;); 682 IRDA_ASSERT(self->magic == IRLAN_MAGIC, return;); 683 684 skb = alloc_skb(IRLAN_MAX_HEADER + IRLAN_CMD_HEADER + 685 IRLAN_STRING_PARAMETER_LEN("MEDIA", "802.3") + 686 IRLAN_STRING_PARAMETER_LEN("ACCESS_TYPE", "DIRECT"), 687 GFP_ATOMIC); 688 if (!skb) 689 return; 690 691 skb_reserve(skb, self->client.max_header_size); 692 skb_put(skb, 2); 693 694 frame = skb->data; 695 696 /* Build frame */ 697 frame[0] = CMD_OPEN_DATA_CHANNEL; 698 frame[1] = 0x02; /* Two parameters */ 699 700 irlan_insert_string_param(skb, "MEDIA", "802.3"); 701 irlan_insert_string_param(skb, "ACCESS_TYPE", "DIRECT"); 702 /* irlan_insert_string_param(skb, "MODE", "UNRELIABLE"); */ 703 704/* self->use_udata = TRUE; */ 705 706 irlan_ctrl_data_request(self, skb); 707} 708 709void irlan_close_data_channel(struct irlan_cb *self) 710{ 711 struct sk_buff *skb; 712 __u8 *frame; 713 714 IRDA_DEBUG(4, "%s()\n", __FUNCTION__ ); 715 716 IRDA_ASSERT(self != NULL, return;); 717 IRDA_ASSERT(self->magic == IRLAN_MAGIC, return;); 718 719 /* Check if the TSAP is still there */ 720 if (self->client.tsap_ctrl == NULL) 721 return; 722 723 skb = alloc_skb(IRLAN_MAX_HEADER + IRLAN_CMD_HEADER + 724 IRLAN_BYTE_PARAMETER_LEN("DATA_CHAN"), 725 GFP_ATOMIC); 726 if (!skb) 727 return; 728 729 skb_reserve(skb, self->client.max_header_size); 730 skb_put(skb, 2); 731 732 frame = skb->data; 733 734 /* Build frame */ 735 frame[0] = CMD_CLOSE_DATA_CHAN; 736 frame[1] = 0x01; /* One parameter */ 737 738 irlan_insert_byte_param(skb, "DATA_CHAN", self->dtsap_sel_data); 739 740 irlan_ctrl_data_request(self, skb); 741} 742 743/* 744 * Function irlan_open_unicast_addr (self) 745 * 746 * Make IrLAN provider accept ethernet frames addressed to the unicast 747 * address. 748 * 749 */ 750static void irlan_open_unicast_addr(struct irlan_cb *self) 751{ 752 struct sk_buff *skb; 753 __u8 *frame; 754 755 IRDA_DEBUG(4, "%s()\n", __FUNCTION__ ); 756 757 IRDA_ASSERT(self != NULL, return;); 758 IRDA_ASSERT(self->magic == IRLAN_MAGIC, return;); 759 760 skb = alloc_skb(IRLAN_MAX_HEADER + IRLAN_CMD_HEADER + 761 IRLAN_BYTE_PARAMETER_LEN("DATA_CHAN") + 762 IRLAN_STRING_PARAMETER_LEN("FILTER_TYPE", "DIRECTED") + 763 IRLAN_STRING_PARAMETER_LEN("FILTER_MODE", "FILTER"), 764 GFP_ATOMIC); 765 if (!skb) 766 return; 767 768 /* Reserve space for TTP, LMP, and LAP header */ 769 skb_reserve(skb, self->max_header_size); 770 skb_put(skb, 2); 771 772 frame = skb->data; 773 774 frame[0] = CMD_FILTER_OPERATION; 775 frame[1] = 0x03; /* Three parameters */ 776 irlan_insert_byte_param(skb, "DATA_CHAN" , self->dtsap_sel_data); 777 irlan_insert_string_param(skb, "FILTER_TYPE", "DIRECTED"); 778 irlan_insert_string_param(skb, "FILTER_MODE", "FILTER"); 779 780 irlan_ctrl_data_request(self, skb); 781} 782 783/* 784 * Function irlan_set_broadcast_filter (self, status) 785 * 786 * Make IrLAN provider accept ethernet frames addressed to the broadcast 787 * address. Be careful with the use of this one, since there may be a lot 788 * of broadcast traffic out there. We can still function without this 789 * one but then _we_ have to initiate all communication with other 790 * hosts, since ARP request for this host will not be answered. 791 */ 792void irlan_set_broadcast_filter(struct irlan_cb *self, int status) 793{ 794 struct sk_buff *skb; 795 __u8 *frame; 796 797 IRDA_DEBUG(2, "%s()\n", __FUNCTION__ ); 798 799 IRDA_ASSERT(self != NULL, return;); 800 IRDA_ASSERT(self->magic == IRLAN_MAGIC, return;); 801 802 skb = alloc_skb(IRLAN_MAX_HEADER + IRLAN_CMD_HEADER + 803 IRLAN_BYTE_PARAMETER_LEN("DATA_CHAN") + 804 IRLAN_STRING_PARAMETER_LEN("FILTER_TYPE", "BROADCAST") + 805 /* We may waste one byte here...*/ 806 IRLAN_STRING_PARAMETER_LEN("FILTER_MODE", "FILTER"), 807 GFP_ATOMIC); 808 if (!skb) 809 return; 810 811 /* Reserve space for TTP, LMP, and LAP header */ 812 skb_reserve(skb, self->client.max_header_size); 813 skb_put(skb, 2); 814 815 frame = skb->data; 816 817 frame[0] = CMD_FILTER_OPERATION; 818 frame[1] = 0x03; /* Three parameters */ 819 irlan_insert_byte_param(skb, "DATA_CHAN", self->dtsap_sel_data); 820 irlan_insert_string_param(skb, "FILTER_TYPE", "BROADCAST"); 821 if (status) 822 irlan_insert_string_param(skb, "FILTER_MODE", "FILTER"); 823 else 824 irlan_insert_string_param(skb, "FILTER_MODE", "NONE"); 825 826 irlan_ctrl_data_request(self, skb); 827} 828 829/* 830 * Function irlan_set_multicast_filter (self, status) 831 * 832 * Make IrLAN provider accept ethernet frames addressed to the multicast 833 * address. 834 * 835 */ 836void irlan_set_multicast_filter(struct irlan_cb *self, int status) 837{ 838 struct sk_buff *skb; 839 __u8 *frame; 840 841 IRDA_DEBUG(2, "%s()\n", __FUNCTION__ ); 842 843 IRDA_ASSERT(self != NULL, return;); 844 IRDA_ASSERT(self->magic == IRLAN_MAGIC, return;); 845 846 skb = alloc_skb(IRLAN_MAX_HEADER + IRLAN_CMD_HEADER + 847 IRLAN_BYTE_PARAMETER_LEN("DATA_CHAN") + 848 IRLAN_STRING_PARAMETER_LEN("FILTER_TYPE", "MULTICAST") + 849 /* We may waste one byte here...*/ 850 IRLAN_STRING_PARAMETER_LEN("FILTER_MODE", "NONE"), 851 GFP_ATOMIC); 852 if (!skb) 853 return; 854 855 /* Reserve space for TTP, LMP, and LAP header */ 856 skb_reserve(skb, self->client.max_header_size); 857 skb_put(skb, 2); 858 859 frame = skb->data; 860 861 frame[0] = CMD_FILTER_OPERATION; 862 frame[1] = 0x03; /* Three parameters */ 863 irlan_insert_byte_param(skb, "DATA_CHAN", self->dtsap_sel_data); 864 irlan_insert_string_param(skb, "FILTER_TYPE", "MULTICAST"); 865 if (status) 866 irlan_insert_string_param(skb, "FILTER_MODE", "ALL"); 867 else 868 irlan_insert_string_param(skb, "FILTER_MODE", "NONE"); 869 870 irlan_ctrl_data_request(self, skb); 871} 872 873/* 874 * Function irlan_get_unicast_addr (self) 875 * 876 * Retrieves the unicast address from the IrLAN provider. This address 877 * will be inserted into the devices structure, so the ethernet layer 878 * can construct its packets. 879 * 880 */ 881static void irlan_get_unicast_addr(struct irlan_cb *self) 882{ 883 struct sk_buff *skb; 884 __u8 *frame; 885 886 IRDA_DEBUG(2, "%s()\n", __FUNCTION__ ); 887 888 IRDA_ASSERT(self != NULL, return;); 889 IRDA_ASSERT(self->magic == IRLAN_MAGIC, return;); 890 891 skb = alloc_skb(IRLAN_MAX_HEADER + IRLAN_CMD_HEADER + 892 IRLAN_BYTE_PARAMETER_LEN("DATA_CHAN") + 893 IRLAN_STRING_PARAMETER_LEN("FILTER_TYPE", "DIRECTED") + 894 IRLAN_STRING_PARAMETER_LEN("FILTER_OPERATION", 895 "DYNAMIC"), 896 GFP_ATOMIC); 897 if (!skb) 898 return; 899 900 /* Reserve space for TTP, LMP, and LAP header */ 901 skb_reserve(skb, self->client.max_header_size); 902 skb_put(skb, 2); 903 904 frame = skb->data; 905 906 frame[0] = CMD_FILTER_OPERATION; 907 frame[1] = 0x03; /* Three parameters */ 908 irlan_insert_byte_param(skb, "DATA_CHAN", self->dtsap_sel_data); 909 irlan_insert_string_param(skb, "FILTER_TYPE", "DIRECTED"); 910 irlan_insert_string_param(skb, "FILTER_OPERATION", "DYNAMIC"); 911 912 irlan_ctrl_data_request(self, skb); 913} 914 915/* 916 * Function irlan_get_media_char (self) 917 * 918 * 919 * 920 */ 921void irlan_get_media_char(struct irlan_cb *self) 922{ 923 struct sk_buff *skb; 924 __u8 *frame; 925 926 IRDA_DEBUG(4, "%s()\n", __FUNCTION__ ); 927 928 IRDA_ASSERT(self != NULL, return;); 929 IRDA_ASSERT(self->magic == IRLAN_MAGIC, return;); 930 931 skb = alloc_skb(IRLAN_MAX_HEADER + IRLAN_CMD_HEADER + 932 IRLAN_STRING_PARAMETER_LEN("MEDIA", "802.3"), 933 GFP_ATOMIC); 934 935 if (!skb) 936 return; 937 938 /* Reserve space for TTP, LMP, and LAP header */ 939 skb_reserve(skb, self->client.max_header_size); 940 skb_put(skb, 2); 941 942 frame = skb->data; 943 944 /* Build frame */ 945 frame[0] = CMD_GET_MEDIA_CHAR; 946 frame[1] = 0x01; /* One parameter */ 947 948 irlan_insert_string_param(skb, "MEDIA", "802.3"); 949 irlan_ctrl_data_request(self, skb); 950} 951 952/* 953 * Function insert_byte_param (skb, param, value) 954 * 955 * Insert byte parameter into frame 956 * 957 */ 958int irlan_insert_byte_param(struct sk_buff *skb, char *param, __u8 value) 959{ 960 return __irlan_insert_param(skb, param, IRLAN_BYTE, value, 0, NULL, 0); 961} 962 963int irlan_insert_short_param(struct sk_buff *skb, char *param, __u16 value) 964{ 965 return __irlan_insert_param(skb, param, IRLAN_SHORT, 0, value, NULL, 0); 966} 967 968/* 969 * Function insert_string (skb, param, value) 970 * 971 * Insert string parameter into frame 972 * 973 */ 974int irlan_insert_string_param(struct sk_buff *skb, char *param, char *string) 975{ 976 int string_len = strlen(string); 977 978 return __irlan_insert_param(skb, param, IRLAN_ARRAY, 0, 0, string, 979 string_len); 980} 981 982/* 983 * Function insert_array_param(skb, param, value, len_value) 984 * 985 * Insert array parameter into frame 986 * 987 */ 988int irlan_insert_array_param(struct sk_buff *skb, char *name, __u8 *array, 989 __u16 array_len) 990{ 991 return __irlan_insert_param(skb, name, IRLAN_ARRAY, 0, 0, array, 992 array_len); 993} 994 995/* 996 * Function insert_param (skb, param, value, byte) 997 * 998 * Insert parameter at end of buffer, structure of a parameter is: 999 * 1000 * ----------------------------------------------------------------------- 1001 * | Name Length[1] | Param Name[1..255] | Val Length[2] | Value[0..1016]| 1002 * ----------------------------------------------------------------------- 1003 */ 1004static int __irlan_insert_param(struct sk_buff *skb, char *param, int type, 1005 __u8 value_byte, __u16 value_short, 1006 __u8 *value_array, __u16 value_len) 1007{ 1008 __u8 *frame; 1009 __u8 param_len; 1010 __le16 tmp_le; /* Temporary value in little endian format */ 1011 int n=0; 1012 1013 if (skb == NULL) { 1014 IRDA_DEBUG(2, "%s(), Got NULL skb\n", __FUNCTION__ ); 1015 return 0; 1016 } 1017 1018 param_len = strlen(param); 1019 switch (type) { 1020 case IRLAN_BYTE: 1021 value_len = 1; 1022 break; 1023 case IRLAN_SHORT: 1024 value_len = 2; 1025 break; 1026 case IRLAN_ARRAY: 1027 IRDA_ASSERT(value_array != NULL, return 0;); 1028 IRDA_ASSERT(value_len > 0, return 0;); 1029 break; 1030 default: 1031 IRDA_DEBUG(2, "%s(), Unknown parameter type!\n", __FUNCTION__ ); 1032 return 0; 1033 break; 1034 } 1035 1036 /* Insert at end of sk-buffer */ 1037 frame = skb_tail_pointer(skb); 1038 1039 /* Make space for data */ 1040 if (skb_tailroom(skb) < (param_len+value_len+3)) { 1041 IRDA_DEBUG(2, "%s(), No more space at end of skb\n", __FUNCTION__ ); 1042 return 0; 1043 } 1044 skb_put(skb, param_len+value_len+3); 1045 1046 /* Insert parameter length */ 1047 frame[n++] = param_len; 1048 1049 /* Insert parameter */ 1050 memcpy(frame+n, param, param_len); n += param_len; 1051 1052 /* Insert value length (2 byte little endian format, LSB first) */ 1053 tmp_le = cpu_to_le16(value_len); 1054 memcpy(frame+n, &tmp_le, 2); n += 2; /* To avoid alignment problems */ 1055 1056 /* Insert value */ 1057 switch (type) { 1058 case IRLAN_BYTE: 1059 frame[n++] = value_byte; 1060 break; 1061 case IRLAN_SHORT: 1062 tmp_le = cpu_to_le16(value_short); 1063 memcpy(frame+n, &tmp_le, 2); n += 2; 1064 break; 1065 case IRLAN_ARRAY: 1066 memcpy(frame+n, value_array, value_len); n+=value_len; 1067 break; 1068 default: 1069 break; 1070 } 1071 IRDA_ASSERT(n == (param_len+value_len+3), return 0;); 1072 1073 return param_len+value_len+3; 1074} 1075 1076/* 1077 * Function irlan_extract_param (buf, name, value, len) 1078 * 1079 * Extracts a single parameter name/value pair from buffer and updates 1080 * the buffer pointer to point to the next name/value pair. 1081 */ 1082int irlan_extract_param(__u8 *buf, char *name, char *value, __u16 *len) 1083{ 1084 __u8 name_len; 1085 __u16 val_len; 1086 int n=0; 1087 1088 IRDA_DEBUG(4, "%s()\n", __FUNCTION__ ); 1089 1090 /* get length of parameter name (1 byte) */ 1091 name_len = buf[n++]; 1092 1093 if (name_len > 254) { 1094 IRDA_DEBUG(2, "%s(), name_len > 254\n", __FUNCTION__ ); 1095 return -RSP_INVALID_COMMAND_FORMAT; 1096 } 1097 1098 /* get parameter name */ 1099 memcpy(name, buf+n, name_len); 1100 name[name_len] = '\0'; 1101 n+=name_len; 1102 1103 /* 1104 * Get length of parameter value (2 bytes in little endian 1105 * format) 1106 */ 1107 memcpy(&val_len, buf+n, 2); /* To avoid alignment problems */ 1108 le16_to_cpus(&val_len); n+=2; 1109 1110 if (val_len > 1016) { 1111 IRDA_DEBUG(2, "%s(), parameter length to long\n", __FUNCTION__ ); 1112 return -RSP_INVALID_COMMAND_FORMAT; 1113 } 1114 *len = val_len; 1115 1116 /* get parameter value */ 1117 memcpy(value, buf+n, val_len); 1118 value[val_len] = '\0'; 1119 n+=val_len; 1120 1121 IRDA_DEBUG(4, "Parameter: %s ", name); 1122 IRDA_DEBUG(4, "Value: %s\n", value); 1123 1124 return n; 1125} 1126 1127#ifdef CONFIG_PROC_FS 1128 1129/* 1130 * Start of reading /proc entries. 1131 * Return entry at pos, 1132 * or start_token to indicate print header line 1133 * or NULL if end of file 1134 */ 1135static void *irlan_seq_start(struct seq_file *seq, loff_t *pos) 1136{ 1137 int i = 1; 1138 struct irlan_cb *self; 1139 1140 rcu_read_lock(); 1141 if (*pos == 0) 1142 return SEQ_START_TOKEN; 1143 1144 list_for_each_entry(self, &irlans, dev_list) { 1145 if (*pos == i) 1146 return self; 1147 ++i; 1148 } 1149 return NULL; 1150} 1151 1152/* Return entry after v, and increment pos */ 1153static void *irlan_seq_next(struct seq_file *seq, void *v, loff_t *pos) 1154{ 1155 struct list_head *nxt; 1156 1157 ++*pos; 1158 if (v == SEQ_START_TOKEN) 1159 nxt = irlans.next; 1160 else 1161 nxt = ((struct irlan_cb *)v)->dev_list.next; 1162 1163 return (nxt == &irlans) ? NULL 1164 : list_entry(nxt, struct irlan_cb, dev_list); 1165} 1166 1167/* End of reading /proc file */ 1168static void irlan_seq_stop(struct seq_file *seq, void *v) 1169{ 1170 rcu_read_unlock(); 1171} 1172 1173 1174/* 1175 * Show one entry in /proc file. 1176 */ 1177static int irlan_seq_show(struct seq_file *seq, void *v) 1178{ 1179 if (v == SEQ_START_TOKEN) 1180 seq_puts(seq, "IrLAN instances:\n"); 1181 else { 1182 struct irlan_cb *self = v; 1183 1184 IRDA_ASSERT(self != NULL, return -1;); 1185 IRDA_ASSERT(self->magic == IRLAN_MAGIC, return -1;); 1186 1187 seq_printf(seq,"ifname: %s,\n", 1188 self->dev->name); 1189 seq_printf(seq,"client state: %s, ", 1190 irlan_state[ self->client.state]); 1191 seq_printf(seq,"provider state: %s,\n", 1192 irlan_state[ self->provider.state]); 1193 seq_printf(seq,"saddr: %#08x, ", 1194 self->saddr); 1195 seq_printf(seq,"daddr: %#08x\n", 1196 self->daddr); 1197 seq_printf(seq,"version: %d.%d,\n", 1198 self->version[1], self->version[0]); 1199 seq_printf(seq,"access type: %s\n", 1200 irlan_access[self->client.access_type]); 1201 seq_printf(seq,"media: %s\n", 1202 irlan_media[self->media]); 1203 1204 seq_printf(seq,"local filter:\n"); 1205 seq_printf(seq,"remote filter: "); 1206 irlan_print_filter(seq, self->client.filter_type); 1207 seq_printf(seq,"tx busy: %s\n", 1208 netif_queue_stopped(self->dev) ? "TRUE" : "FALSE"); 1209 1210 seq_putc(seq,'\n'); 1211 } 1212 return 0; 1213} 1214 1215static struct seq_operations irlan_seq_ops = { 1216 .start = irlan_seq_start, 1217 .next = irlan_seq_next, 1218 .stop = irlan_seq_stop, 1219 .show = irlan_seq_show, 1220}; 1221 1222static int irlan_seq_open(struct inode *inode, struct file *file) 1223{ 1224 return seq_open(file, &irlan_seq_ops); 1225} 1226#endif 1227 1228MODULE_AUTHOR("Dag Brattli <dagb@cs.uit.no>"); 1229MODULE_DESCRIPTION("The Linux IrDA LAN protocol"); 1230MODULE_LICENSE("GPL"); 1231 1232module_param(eth, bool, 0); 1233MODULE_PARM_DESC(eth, "Name devices ethX (0) or irlanX (1)"); 1234module_param(access, int, 0); 1235MODULE_PARM_DESC(access, "Access type DIRECT=1, PEER=2, HOSTED=3"); 1236 1237module_init(irlan_init); 1238module_exit(irlan_cleanup); 1239