irlan_provider_event.c 6.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241
  1. /*********************************************************************
  2. *
  3. * Filename: irlan_provider_event.c
  4. * Version: 0.9
  5. * Description: IrLAN provider state machine)
  6. * Status: Experimental.
  7. * Author: Dag Brattli <dagb@cs.uit.no>
  8. * Created at: Sun Aug 31 20:14:37 1997
  9. * Modified at: Sat Oct 30 12:52:41 1999
  10. * Modified by: Dag Brattli <dagb@cs.uit.no>
  11. *
  12. * Copyright (c) 1998-1999 Dag Brattli <dagb@cs.uit.no>, All Rights Reserved.
  13. *
  14. * This program is free software; you can redistribute it and/or
  15. * modify it under the terms of the GNU General Public License as
  16. * published by the Free Software Foundation; either version 2 of
  17. * the License, or (at your option) any later version.
  18. *
  19. * Neither Dag Brattli nor University of Tromsø admit liability nor
  20. * provide warranty for any of this software. This material is
  21. * provided "AS-IS" and at no charge.
  22. *
  23. ********************************************************************/
  24. #include <net/irda/irda.h>
  25. #include <net/irda/iriap.h>
  26. #include <net/irda/irlmp.h>
  27. #include <net/irda/irttp.h>
  28. #include <net/irda/irlan_provider.h>
  29. #include <net/irda/irlan_event.h>
  30. static int irlan_provider_state_idle(struct irlan_cb *self, IRLAN_EVENT event,
  31. struct sk_buff *skb);
  32. static int irlan_provider_state_info(struct irlan_cb *self, IRLAN_EVENT event,
  33. struct sk_buff *skb);
  34. static int irlan_provider_state_open(struct irlan_cb *self, IRLAN_EVENT event,
  35. struct sk_buff *skb);
  36. static int irlan_provider_state_data(struct irlan_cb *self, IRLAN_EVENT event,
  37. struct sk_buff *skb);
  38. static int (*state[])(struct irlan_cb *self, IRLAN_EVENT event,
  39. struct sk_buff *skb) =
  40. {
  41. irlan_provider_state_idle,
  42. NULL, /* Query */
  43. NULL, /* Info */
  44. irlan_provider_state_info,
  45. NULL, /* Media */
  46. irlan_provider_state_open,
  47. NULL, /* Wait */
  48. NULL, /* Arb */
  49. irlan_provider_state_data,
  50. NULL, /* Close */
  51. NULL, /* Sync */
  52. };
  53. void irlan_do_provider_event(struct irlan_cb *self, IRLAN_EVENT event,
  54. struct sk_buff *skb)
  55. {
  56. IRDA_ASSERT(*state[ self->provider.state] != NULL, return;);
  57. (*state[self->provider.state]) (self, event, skb);
  58. }
  59. /*
  60. * Function irlan_provider_state_idle (event, skb, info)
  61. *
  62. * IDLE, We are waiting for an indication that there is a provider
  63. * available.
  64. */
  65. static int irlan_provider_state_idle(struct irlan_cb *self, IRLAN_EVENT event,
  66. struct sk_buff *skb)
  67. {
  68. IRDA_DEBUG(4, "%s()\n", __FUNCTION__ );
  69. IRDA_ASSERT(self != NULL, return -1;);
  70. switch(event) {
  71. case IRLAN_CONNECT_INDICATION:
  72. irlan_provider_connect_response( self, self->provider.tsap_ctrl);
  73. irlan_next_provider_state( self, IRLAN_INFO);
  74. break;
  75. default:
  76. IRDA_DEBUG(4, "%s(), Unknown event %d\n", __FUNCTION__ , event);
  77. break;
  78. }
  79. if (skb)
  80. dev_kfree_skb(skb);
  81. return 0;
  82. }
  83. /*
  84. * Function irlan_provider_state_info (self, event, skb, info)
  85. *
  86. * INFO, We have issued a GetInfo command and is awaiting a reply.
  87. */
  88. static int irlan_provider_state_info(struct irlan_cb *self, IRLAN_EVENT event,
  89. struct sk_buff *skb)
  90. {
  91. int ret;
  92. IRDA_DEBUG(4, "%s()\n", __FUNCTION__ );
  93. IRDA_ASSERT(self != NULL, return -1;);
  94. switch(event) {
  95. case IRLAN_GET_INFO_CMD:
  96. /* Be sure to use 802.3 in case of peer mode */
  97. if (self->provider.access_type == ACCESS_PEER) {
  98. self->media = MEDIA_802_3;
  99. /* Check if client has started yet */
  100. if (self->client.state == IRLAN_IDLE) {
  101. /* This should get the client going */
  102. irlmp_discovery_request(8);
  103. }
  104. }
  105. irlan_provider_send_reply(self, CMD_GET_PROVIDER_INFO,
  106. RSP_SUCCESS);
  107. /* Keep state */
  108. break;
  109. case IRLAN_GET_MEDIA_CMD:
  110. irlan_provider_send_reply(self, CMD_GET_MEDIA_CHAR,
  111. RSP_SUCCESS);
  112. /* Keep state */
  113. break;
  114. case IRLAN_OPEN_DATA_CMD:
  115. ret = irlan_parse_open_data_cmd(self, skb);
  116. if (self->provider.access_type == ACCESS_PEER) {
  117. /* FIXME: make use of random functions! */
  118. self->provider.send_arb_val = (jiffies & 0xffff);
  119. }
  120. irlan_provider_send_reply(self, CMD_OPEN_DATA_CHANNEL, ret);
  121. if (ret == RSP_SUCCESS) {
  122. irlan_next_provider_state(self, IRLAN_OPEN);
  123. /* Signal client that we are now open */
  124. irlan_do_client_event(self, IRLAN_PROVIDER_SIGNAL, NULL);
  125. }
  126. break;
  127. case IRLAN_LMP_DISCONNECT: /* FALLTHROUGH */
  128. case IRLAN_LAP_DISCONNECT:
  129. irlan_next_provider_state(self, IRLAN_IDLE);
  130. break;
  131. default:
  132. IRDA_DEBUG( 0, "%s(), Unknown event %d\n", __FUNCTION__ , event);
  133. break;
  134. }
  135. if (skb)
  136. dev_kfree_skb(skb);
  137. return 0;
  138. }
  139. /*
  140. * Function irlan_provider_state_open (self, event, skb, info)
  141. *
  142. * OPEN, The client has issued a OpenData command and is awaiting a
  143. * reply
  144. *
  145. */
  146. static int irlan_provider_state_open(struct irlan_cb *self, IRLAN_EVENT event,
  147. struct sk_buff *skb)
  148. {
  149. IRDA_DEBUG(4, "%s()\n", __FUNCTION__ );
  150. IRDA_ASSERT(self != NULL, return -1;);
  151. switch(event) {
  152. case IRLAN_FILTER_CONFIG_CMD:
  153. irlan_provider_parse_command(self, CMD_FILTER_OPERATION, skb);
  154. irlan_provider_send_reply(self, CMD_FILTER_OPERATION,
  155. RSP_SUCCESS);
  156. /* Keep state */
  157. break;
  158. case IRLAN_DATA_CONNECT_INDICATION:
  159. irlan_next_provider_state(self, IRLAN_DATA);
  160. irlan_provider_connect_response(self, self->tsap_data);
  161. break;
  162. case IRLAN_LMP_DISCONNECT: /* FALLTHROUGH */
  163. case IRLAN_LAP_DISCONNECT:
  164. irlan_next_provider_state(self, IRLAN_IDLE);
  165. break;
  166. default:
  167. IRDA_DEBUG(2, "%s(), Unknown event %d\n", __FUNCTION__ , event);
  168. break;
  169. }
  170. if (skb)
  171. dev_kfree_skb(skb);
  172. return 0;
  173. }
  174. /*
  175. * Function irlan_provider_state_data (self, event, skb, info)
  176. *
  177. * DATA, The data channel is connected, allowing data transfers between
  178. * the local and remote machines.
  179. *
  180. */
  181. static int irlan_provider_state_data(struct irlan_cb *self, IRLAN_EVENT event,
  182. struct sk_buff *skb)
  183. {
  184. IRDA_DEBUG(4, "%s()\n", __FUNCTION__ );
  185. IRDA_ASSERT(self != NULL, return -1;);
  186. IRDA_ASSERT(self->magic == IRLAN_MAGIC, return -1;);
  187. switch(event) {
  188. case IRLAN_FILTER_CONFIG_CMD:
  189. irlan_provider_parse_command(self, CMD_FILTER_OPERATION, skb);
  190. irlan_provider_send_reply(self, CMD_FILTER_OPERATION,
  191. RSP_SUCCESS);
  192. break;
  193. case IRLAN_LMP_DISCONNECT: /* FALLTHROUGH */
  194. case IRLAN_LAP_DISCONNECT:
  195. irlan_next_provider_state(self, IRLAN_IDLE);
  196. break;
  197. default:
  198. IRDA_DEBUG( 0, "%s(), Unknown event %d\n", __FUNCTION__ , event);
  199. break;
  200. }
  201. if (skb)
  202. dev_kfree_skb(skb);
  203. return 0;
  204. }