irlan_common.c 31 KB

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