irlan_provider_event.c 6.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234
  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_ASSERT(self != NULL, return -1;);
  69. switch(event) {
  70. case IRLAN_CONNECT_INDICATION:
  71. irlan_provider_connect_response( self, self->provider.tsap_ctrl);
  72. irlan_next_provider_state( self, IRLAN_INFO);
  73. break;
  74. default:
  75. pr_debug("%s(), Unknown event %d\n", __func__ , event);
  76. break;
  77. }
  78. if (skb)
  79. dev_kfree_skb(skb);
  80. return 0;
  81. }
  82. /*
  83. * Function irlan_provider_state_info (self, event, skb, info)
  84. *
  85. * INFO, We have issued a GetInfo command and is awaiting a reply.
  86. */
  87. static int irlan_provider_state_info(struct irlan_cb *self, IRLAN_EVENT event,
  88. struct sk_buff *skb)
  89. {
  90. int ret;
  91. IRDA_ASSERT(self != NULL, return -1;);
  92. switch(event) {
  93. case IRLAN_GET_INFO_CMD:
  94. /* Be sure to use 802.3 in case of peer mode */
  95. if (self->provider.access_type == ACCESS_PEER) {
  96. self->media = MEDIA_802_3;
  97. /* Check if client has started yet */
  98. if (self->client.state == IRLAN_IDLE) {
  99. /* This should get the client going */
  100. irlmp_discovery_request(8);
  101. }
  102. }
  103. irlan_provider_send_reply(self, CMD_GET_PROVIDER_INFO,
  104. RSP_SUCCESS);
  105. /* Keep state */
  106. break;
  107. case IRLAN_GET_MEDIA_CMD:
  108. irlan_provider_send_reply(self, CMD_GET_MEDIA_CHAR,
  109. RSP_SUCCESS);
  110. /* Keep state */
  111. break;
  112. case IRLAN_OPEN_DATA_CMD:
  113. ret = irlan_parse_open_data_cmd(self, skb);
  114. if (self->provider.access_type == ACCESS_PEER) {
  115. /* FIXME: make use of random functions! */
  116. self->provider.send_arb_val = (jiffies & 0xffff);
  117. }
  118. irlan_provider_send_reply(self, CMD_OPEN_DATA_CHANNEL, ret);
  119. if (ret == RSP_SUCCESS) {
  120. irlan_next_provider_state(self, IRLAN_OPEN);
  121. /* Signal client that we are now open */
  122. irlan_do_client_event(self, IRLAN_PROVIDER_SIGNAL, NULL);
  123. }
  124. break;
  125. case IRLAN_LMP_DISCONNECT: /* FALLTHROUGH */
  126. case IRLAN_LAP_DISCONNECT:
  127. irlan_next_provider_state(self, IRLAN_IDLE);
  128. break;
  129. default:
  130. pr_debug("%s(), Unknown event %d\n", __func__ , event);
  131. break;
  132. }
  133. if (skb)
  134. dev_kfree_skb(skb);
  135. return 0;
  136. }
  137. /*
  138. * Function irlan_provider_state_open (self, event, skb, info)
  139. *
  140. * OPEN, The client has issued a OpenData command and is awaiting a
  141. * reply
  142. *
  143. */
  144. static int irlan_provider_state_open(struct irlan_cb *self, IRLAN_EVENT event,
  145. struct sk_buff *skb)
  146. {
  147. IRDA_ASSERT(self != NULL, return -1;);
  148. switch(event) {
  149. case IRLAN_FILTER_CONFIG_CMD:
  150. irlan_provider_parse_command(self, CMD_FILTER_OPERATION, skb);
  151. irlan_provider_send_reply(self, CMD_FILTER_OPERATION,
  152. RSP_SUCCESS);
  153. /* Keep state */
  154. break;
  155. case IRLAN_DATA_CONNECT_INDICATION:
  156. irlan_next_provider_state(self, IRLAN_DATA);
  157. irlan_provider_connect_response(self, self->tsap_data);
  158. break;
  159. case IRLAN_LMP_DISCONNECT: /* FALLTHROUGH */
  160. case IRLAN_LAP_DISCONNECT:
  161. irlan_next_provider_state(self, IRLAN_IDLE);
  162. break;
  163. default:
  164. pr_debug("%s(), Unknown event %d\n", __func__ , event);
  165. break;
  166. }
  167. if (skb)
  168. dev_kfree_skb(skb);
  169. return 0;
  170. }
  171. /*
  172. * Function irlan_provider_state_data (self, event, skb, info)
  173. *
  174. * DATA, The data channel is connected, allowing data transfers between
  175. * the local and remote machines.
  176. *
  177. */
  178. static int irlan_provider_state_data(struct irlan_cb *self, IRLAN_EVENT event,
  179. struct sk_buff *skb)
  180. {
  181. IRDA_ASSERT(self != NULL, return -1;);
  182. IRDA_ASSERT(self->magic == IRLAN_MAGIC, return -1;);
  183. switch(event) {
  184. case IRLAN_FILTER_CONFIG_CMD:
  185. irlan_provider_parse_command(self, CMD_FILTER_OPERATION, skb);
  186. irlan_provider_send_reply(self, CMD_FILTER_OPERATION,
  187. RSP_SUCCESS);
  188. break;
  189. case IRLAN_LMP_DISCONNECT: /* FALLTHROUGH */
  190. case IRLAN_LAP_DISCONNECT:
  191. irlan_next_provider_state(self, IRLAN_IDLE);
  192. break;
  193. default:
  194. pr_debug("%s(), Unknown event %d\n", __func__ , event);
  195. break;
  196. }
  197. if (skb)
  198. dev_kfree_skb(skb);
  199. return 0;
  200. }